如何用定时器C代码在STM32F103上产生控制伺服电机的脉宽调制,通过脉宽调制来控制伺服电机,从模数转换器得到值,然后计算出脉宽调制占空比
VR --> ADC模块(模数转换)的取值流程图-->计算PWM占空比-->使用定时器产生控制伺服电机的PWM --> while循环
为我的英语语言道歉。
发布于 2012-03-13 05:56:41
此代码假设脉宽调制时钟=72 the Servo_Target为微秒的八分之一,因此4000表示1ms (低伺服位置),8000表示2ms (高伺服位置)警告:脉宽调制频率为463 is,因此您不能将此设置用于模拟伺服。它适用于BRUSHELESS监管机构。如果要用于模拟伺服,则必须更改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);发布于 2011-09-07 11:01:22
我假设您使用的是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根据伺服规格的不同,你可能需要稍微修改这些参数,以防止周期漂移,但伺服通常是相当宽宏大量的。
您需要找到适用于您的编译器的中断处理程序语法示例,并始终阅读有关如何使用寄存器来控制计时器和启用中断的手册。
祝你好运,当你完成了更多的工作后,用一些代码发布一个新的问题。
https://stackoverflow.com/questions/7325324
复制相似问题