STM32学习17--定时器之舵机

STM32学习17--定时器之舵机
舵机是一种根据输入PWM信号占空比来控制输出角度的装置。一、舵机基本参数舵机Servo Motor是一种根据输入PWM脉冲宽度调制信号占空比来控制输出轴角度的精密执行装置。它内部包含直流电机、减速齿轮组、位置反馈电位器和控制电路通过闭环控制实现精确的角度定位。1、以舵机SG90为例SG90是一款微型舵机广泛应用于机器人、航模、智能小车等场景。其核心电气参数如下工作电压4.8V ~ 6.0V典型5V3.3V无驱动力工作电流100mA ~ 250mA空载~堵转扭矩1.2kg·cm ~ 1.8kg·cm电压不同响应速度0.1s/60°4.8VPWM控制信号规范PWM周期固定20ms频率50Hz不能改变高电平脉宽范围0.5ms ~ 2.5ms对应输出角度0° ~ 180°典型对应关系0.5ms → 0°最左位置1.5ms → 90°中间位置2.5ms → 180°最右位置2、参数计算基于STM32F103C8T6系统时钟72MHz目标生成周期20ms、分辨率满足0.5ms~2.5ms可调的PWM信号。步骤分解确定计数频率系统时钟72MHz预分频器PSC设为7200-1则计数器时钟频率 72MHz / 7200 10kHz即每个计数周期0.1ms。确定自动重装载值ARRPWM周期 (ARR1) × 计数周期。周期20ms对应200个计数周期20ms ÷ 0.1ms 200故ARR 200-1 199。计算CCR值捕获/比较寄存器CCR值决定高电平脉宽与角度呈线性关系。0°0.5msCCR 0.5ms ÷ 0.1ms 590°1.5msCCR 1.5ms ÷ 0.1ms 15180°2.5msCCR 2.5ms ÷ 0.1ms 25通用公式CCR (Angle / 180.0) × (25 - 5) 5其中Angle为0~180°。3、接线示意图SG90舵机通常有三根线棕色线BrownGND接地红色线RedVCC电源5V橙色线Orange信号线PWM输入连接STM32开发板时信号线 → PA1TIM2通道2VCC → 5V电源注意电流需足够GND → 共地注意若驱动多个舵机建议使用外部独立电源供电避免开发板LDO过载。1、以舵机SG90为例PWM周期固定20ms频率50Hz高电平范围0.5~2.5ms对应0~180°0.5ms→0°1.5ms→90°中间位置2.5ms→180°2、参数计算系统时钟72MHz周期20ms。设PSC1 7200计数频率10kHz0.1ms计数一次ARR1 200CCR值线性关系CCR5→0.5ms0°CCR15→1.5ms90°CCR25→2.5ms180°3、接线二、代码部分练习以TIM2为例通道1→PA1实现0°→180→0°循环往复。最经典且最简单的做法在whiel()里放2个For循环一个负责正转0→180°另一个负责反转180→0。1、PWM初始化void PWM_Init(uint16_t ARR,uint16_t PSC) { TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; GPIO_InitTypeDef GPIO_InitStructure; TIM_OCInitTypeDef OC_Config; //开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //初始化GPIO GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA,GPIO_InitStructure); //初始化时基单元 TIM_BaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_BaseInitStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_BaseInitStructure.TIM_Period ARR; TIM_BaseInitStructure.TIM_Prescaler PSC; TIM_TimeBaseInit(TIM2,TIM_BaseInitStructure); //配置OC TIM_OCStructInit(OC_Config); OC_Config.TIM_OCMode TIM_OCMode_PWM1; OC_Config.TIM_OutputState TIM_OutputState_Enable; OC_Config.TIM_OCPolarity TIM_OCPolarity_High; OC_Config.TIM_Pulse 15; TIM_OC2Init(TIM2,OC_Config); TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM2,ENABLE); TIM_Cmd(TIM2,ENABLE); }2、舵机Servo初始化及设置角度函数#include stm32f10x.h #include PWM.h void Servo_Init() { PWM_Init(200,7200-1); } void SetMyAngle(uint16_t Angle) { uint16_t Val; if(Angle180) { Angle 180; } Val (uint16_t)((25.0-5.0)/180.0)*Angle5); TIM_SetCompare2(TIM2,Val); }3、舵机Servo头文件#ifndef __SERVO_H #define __SERVO_H void Servo_Init(); void SetMyAngle(uint16_t Angle); #endif4、main函数#include stm32f10x.h // Device header #include Delay.h #include OLED.h #include Servo.h uint16_t ang; int main() { OLED_Init(); Servo_Init(); SetMyAngle(0);//先归零 Delay_ms(1000);//等待舵机物理归位 OLED_ShowString(1,1,Angle:); while(1) { //0→180 for(ang 0;ang 180;ang) { SetMyAngle(ang); Delay_ms(10); //延时决定转动速度 OLED_ShowNum(1,7,ang,3); } Delay_ms(1000); //到头停止1s //180→0 for(ang 180;ang 0;ang--) { SetMyAngle(ang); Delay_ms(10); OLED_ShowNum(1,7,ang,3); } Delay_ms(1000); //到头停止1s } }注意1平滑度控制Delay_ms(10)这个参数决定了舵机转动的丝滑程度。如果设为Delay_ms(1)舵机会转动非常快会因为惯性产生抖动。如果设为10ms转动会比较丝滑。这个过程中耗时约1.8s。可多次试验几次调整参数。2数据类型angle使用了uint16_t无符号16位整数在反向循环中条件写的是angle0而不是angle0因为无符号数减到0后再减1会发送下溢变成65535一直大于条件0导致死循环。本文完