对一有刷马达进行控制(控制周期为100Hz),PWM频率为10KHz(TIM_Period=1800),希望能在PWM开通的中间位置对马达的电流采样 (因为电路设计
的缘故,PWM关断时ADC的输入被嵌位在3V); 例如:如果TIM_Pulse=600,那么希望在计数器等于300时采样 程序中选择时钟2的第四通道控制PWM输出,选择时钟2的第二通道控制AD采样 相关代码如下,只用速度环控制,马达运行正常,但ADC采样点落在PWM关断期间,因为ADC值对应的总是3V左右 大家帮忙看看是那里出了问题,先谢谢各位了。
void PWMInitialization(void) { /*初始化PWM输出管脚*/ GPIO_InitStructure.GPIO_Pin = MOTOR_PWM_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(MOTOR_PWM_PORT, &GPIO_InitStructure); /* 选择时钟2的第四通道控制PWM输出 */ TIM_TimeBaseStructure.TIM_Period = 1800; //频率为10KHz TIM_TimeBaseStructure.TIM_Prescaler = 0x00; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM2, ENABLE); TIM_Cmd(TIM2, ENABLE);
/* 选择时钟2的第二通道控制AD采样 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM2, ENABLE);
/*允许时钟的相关中断*/ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM2, TIM_IT_Update|TIM_IT_CC2, ENABLE); }
void MotorControl(void) // 频率为100Hz { ......... //控制算法计算PWM控制量,并存在MotorPWMValue中 ......... TIM_OCInitStructure.TIM_Pulse = MotorPWMValue; ......... }
void TIM2_IRQHandler(void) //频率为10KHz { u16 capture;
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { capture = TIM_GetCapture1((TIM2); TIM_ClearITPendingBit(TIM2, TIM_IT_Update|TIM_IT_CC2); //TIM_SetCompare2(TIM2, MotorPWMValue/2); TIM_SetCompare2(TIM2, capture+MotorPWMValue/2); }
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update|TIM_IT_CC2); GetADCResult(MotorCurrent); } } |