如何使用定时器在STM32F103上为控制伺服电机生成PWM C代码 我希望通过PWM控制伺服电机 我从ADC获得值然后计算到PWM占空比
流程图 获得VR的价值 - > ADC模块(将模拟转换为数字) - >计算PWM占空比 - >使用Timer为控制伺服电机生成PWM - > while循环
抱歉我的英语朗。答案 0 :(得分:1)
此代码假设APB1时钟= 72MHz Servo_Target为微秒的八分之一,因此4000表示1ms(低伺服位置),8000表示2ms(高伺服位置) 警告:PWM频率为463Hz因此您无法使用此设置进行模拟伺服。它适用于无刷调节器。如果您想使用模拟器,则需要更改TIM_Prescaler,TIM_Period 并考虑对Servo_Target值的影响
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 8192;
TIM_TimeBaseStructure.TIM_Prescaler = 18;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE); // Start PWM Timer
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
// THIS IS THE WIDTH in 1/8 us
TIM_OCInitStructure.TIM_Pulse = Servo_Target;
/* PWM1 Mode configuration: TIM2 Channel1 */
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: TIM2 Channel2 */
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
// add OC3_ and OC4_ for 3rd and 4th channels
TIM_ARRPreloadConfig(TIM2, ENABLE);
答案 1 :(得分:0)
我假设您使用的是IDE并使用C语言编写,但我不熟悉此设备。
基本上,您需要使用定时器,其中设备上有多个定时器,并为“输出比较”中断写入中断处理程序。如果启用了输出比较中断,那么每次定时器中的值与某个寄存器中的值匹配时,都会调用您的处理程序。
一种常见的技术是让处理程序将引脚切换到伺服,然后更改输出比较寄存器中的值,以便在下次需要时再次触发处理程序。
if(off)
turn pin on
ocreg += pwm_value
else
turn pin off
ocreg += cycle-pwm_value
引脚将保持正常的时间长度,并始终以相同的频率开启。您需要根据伺服规范为这些变量找到合适的值。
您可以使用另一个定时器定期对ADC进行采样,或者将其构建到与PWM相同的中断处理程序中,或者甚至让它在忙循环中运行,等待ADC完成。
main()
loop
start ADC
while (ADC busy) { do nothing }
calculate pwm and store in variable pwm_value
loop
根据伺服规格的不同,您可能需要稍微修改这些以防止循环漂移,但伺服系统通常非常宽容。
您需要查找编译器的中断处理程序语法示例,并始终阅读有关如何使用寄存器控制定时器和启用中断的手册。
祝你好运,当你完成更多时,用一些代码发布一个新问题。