나는 세 개의 타이머를 사용하여 위상 쉬프트 PWM 신호를 생성하려고합니다.stm32f405 트리거 신호 생성 PWM
- TIM1가
- TIM3는
- TIM4의 위상을 생성하는데 사용되는 시프트 TIM4, 위상 트리거로서 사용된다 (는 1MHz에서 실행) 기준으로 사용된다
을 TIM3하여 신호 triggerd 시프트 요약하면 : - :
0,123,473 TIM1 --- 트리거> TIM3 --- 트리거 ---> TIM4 는신호는 같아야합니다
다음은 현재 코드입니다. 참조가 1MHz에서 올바르게 실행 중입니다. 하지만 트리거 신호가 지금 작동하지 않습니다. 오류는 initReferenceTimer() 또는 initReferencePWM() 함수의 어느 곳에 나 있어야합니다. 지금까지는 위에서 언급 한 트리거 신호를 생성하지 않습니다. 그래서 단계별 시프트 신호가 올바르게 트리거되면 테스트 할 수 없었습니다.
누구나 그것에 대해 좋은 생각이 있습니까?
디버깅을 위해 트리거 신호를 출력 핀에 바인딩합니다.
#define TIMER_CLOCK 84
#define TIM1_TIMER_CLOCK 168
#define FREQU 1 //MHz
#define SHIFT 20
#define MasterPeriod (TIM1_TIMER_CLOCK/FREQU)-1
#define MasterPulse ((TIM1_TIMER_CLOCK/FREQU)-1)/2
#define ReferencePeriod SHIFT
#define ReferencePulse (SHIFT/2)
#define SlavePeriod (TIM1_TIMER_CLOCK/FREQU)-1
#define SlavePulse ((TIM1_TIMER_CLOCK/FREQU)-1)/2
//TIM1 Channel1: PA7 N
void initMasterPin()
{
GPIO_InitTypeDef GPIO_InitStructureTimer;
// Port clock enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// Set PWM Port, Pin and method
GPIO_InitStructureTimer.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructureTimer.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureTimer.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructureTimer.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureTimer.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructureTimer);
// Connect TIM pin to AF
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM1);
}
//TIM3 Channel1 PC6
void initReferencePin()
{
GPIO_InitTypeDef GPIO_InitStructureTimer;
// Port clock enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
// Set PWM Port, Pin and method
GPIO_InitStructureTimer.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructureTimer.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureTimer.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructureTimer.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureTimer.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOC, &GPIO_InitStructureTimer);
// Connect TIM pin to AF
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);
}
//TIM4 Channel1: PB6
void initSlavePin()
{
GPIO_InitTypeDef GPIO_InitStructureTimer;
// Port clock enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
// Set PWM Port, Pin and method
GPIO_InitStructureTimer.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructureTimer.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureTimer.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructureTimer.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureTimer.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructureTimer);
// Connect TIM pin to AF
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);
}
//Tim1 Channel1: PA7
void initMasterTimer()
{
// set timer frequencies
TIM_TimeBaseInitTypeDef TIM_Config;
// 1.Enable TIM clock
RCC_APB2PeriphClockCmd (RCC_APB2Periph_TIM1, ENABLE);
// 2.Fill the TIM_TimeBaseInitStruct with the desired parameters.
// Time Base configuration
TIM_TimeBaseStructInit (&TIM_Config);
TIM_Config.TIM_Period = MasterPeriod;
TIM_Config.TIM_Prescaler = 0;
TIM_Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_Config.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_Config.TIM_RepetitionCounter = 0;
//configure the Time Base unit with the corresponding configuration
TIM_TimeBaseInit (TIM1, &TIM_Config);
// Enable the NVIC if you need to generate the update interrupt.
// Enable the corresponding interrupt
}
//TIM3 Channel1 PC6
void initReferenceTimer()
{
// set timer frequencies
TIM_TimeBaseInitTypeDef TIM_Config;
// 1.Enable TIM clock
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3, ENABLE);
// 2.Fill the TIM_TimeBaseInitStruct with the desired parameters.
// Time Base configuration
TIM_TimeBaseStructInit (&TIM_Config);
TIM_Config.TIM_Period = ReferencePeriod;//One Step Phase Shift
TIM_Config.TIM_Prescaler = 0;
TIM_Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_Config.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_Config.TIM_RepetitionCounter = 0;
//configure the Time Base unit with the corresponding configuration
TIM_TimeBaseInit (TIM3, &TIM_Config);
// Enable the NVIC if you need to generate the update interrupt.
// Enable the corresponding interrupt
}
//TIM4 Channel1: PB6
void initSlaveTimer()
{
// set timer frequencies
TIM_TimeBaseInitTypeDef TIM_Config;
// 1.Enable TIM clock
RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM4, ENABLE);
// 2.Fill the TIM_TimeBaseInitStruct with the desired parameters.
// Time Base configuration
TIM_TimeBaseStructInit (&TIM_Config);
TIM_Config.TIM_Period = SlavePeriod;
TIM_Config.TIM_Prescaler = 0;
TIM_Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_Config.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_Config.TIM_RepetitionCounter = 0;
//configure the Time Base unit with the corresponding configuration
TIM_TimeBaseInit (TIM4, &TIM_Config);
// Enable the NVIC if you need to generate the update interrupt.
// Enable the corresponding interrupt
}
//Tim1 Channel1: PA7
void initMasterPWM(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = MasterPulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
}
//TIM3 Channel1 PC6
void initReferencePWM(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = ReferencePulse; // set the duty cycle/pulse here!
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single);
/* Slave Mode selection: TIM3 */
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Gated);
/* Select the Master Slave Mode */
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
}
//TIM4 Channel1: PB6
void initSlavePWM(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = SlavePulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated);
TIM_SelectOnePulseMode(TIM4, TIM_OPMode_Single);
}
int main(void)
{
initMasterPin();
initReferencePin(); //FOR DEBUGGING ONLY
initSlavePin();
initMasterTimer();
initReferenceTimer();
initSlaveTimer();
initMasterPWM();
initReferencePWM();
initSlavePWM();
// enable timer/counter
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_Cmd(TIM4, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM4, ENABLE);
/* Busy loop */
int i;
while (1)
{
i++;
}
}
이런 종류의 문제는 매우 실망 스러울 수 있습니다. 일반적으로 타이머와 GPIO의 전원, 클럭킹 및 구성을 반복해서 확인하면 숨겨진하지만 머리가 두드리는 사소한 실수로 인해 작동하지 않을 때까지 반복해서 확인할 수 있습니다. 부분 기능을 확인하는 간단한 사례가 있는지 또는 동일한 문제를 다루는 예가 있는지 확인할 수도 있습니다. 변경된 APB 버스 또는 GPIO 대체 기능 ID가 필요할 수 있으므로 다른 번호가 매겨진 타이머로 코드를 이동할 때주의하십시오. –
물론 어설 션 실패 후 무한 루프로 벗어나지 말고 코드가 완전히 실행되는 UART 출력 로깅이나 디버거 또는 상태 LED로 확인하십시오. –