STM32 SG90舵机应用

无意中翻到了一个舵机,想了解一下舵机的使用。
在这里插入图片描述
舵机与普通的电机不同,它可以根据指令旋转到0至180度之间的任意角度然后精准的停下来。

原理是啥我也不知道。

从找的资料看到
“很多舵机的位置等级有1024个,如果舵机的有效角度范围为180度的话,其控制的角度精度是可以达到180/1024度约0.18度了,从时间上看其实要求的脉宽控制精度为2000/1024us约2us。
如果你拿了个舵机,连控制精度为1度都达不到的话,而且还看到舵机在发抖。在这种情况下,只要舵机的电压没有抖动,那抖动的就是你的控制脉冲了。”

橙色信号线 红色正极 棕色负极

舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度伺服为例,那么对应的控制关系是这样的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;

然而我的实测却不一样。

void Servo_Play(void)
{
	TIM_SetCompare2(TIM2, 40);
	delay_ms(500);
	TIM_SetCompare2(TIM2, 75);
	delay_ms(500);
	TIM_SetCompare2(TIM2, 110);
	delay_ms(500);
	TIM_SetCompare2(TIM2, 149);
	delay_ms(500);
	TIM_SetCompare2(TIM2, 199);
	delay_ms(500);
}

周期20ms,代码中的数字单位为10us。

对舵机有了初步的认识,先写下来,以免忘了。

<think>好的,用户想了解如何在STM32控制SG90舵机,并提供示例代码。我需要结合提供的引用内容来整理答案。 首先,SG90舵机通常使用PWM控制,周期20ms,脉宽0.5ms到2.5ms对应角度0°到180°。STM32的定时器可以生成PWM信号。引用1提到使用STM32F103C8T6,并且代码适用于多种舵机型号。引用2和3中的代码示例展示了初始化和角度设置的方法。 接下来,我需要分步骤说明控制流程。首先,硬件连接部分,舵机的信号线接到STM32的PWM输出引脚。然后,配置定时器,比如TIM3的通道1,设置预分频和自动重装载值,计算合适的ARR和PSC值。例如,假设系统时钟72MHz,预分频71,得到定时器时钟1MHz。自动重装载值设为20000-1,对应20ms周期。接着,设置占空比,计算不同角度对应的脉冲宽度。 然后,需要提供初始化代码和角度控制函数。引用2中的示例代码给出了初始化的函数和设置角度的函数。比如,使用TIM_SetCompare1来更新占空比。此外,用户可能需要知道如何在不同通道上控制多个舵机,比如使用TIM3的通道1和通道2,分别对应不同的GPIO引脚。 还要注意,用户可能需要调整具体的定时器和通道,根据实际硬件连接修改代码。例如,引用3中的源码链接可能提供更完整的示例,需要引导用户参考。 最后,生成相关问题,比如如何调整角度范围、多路PWM控制、不同舵机型号的兼容性,以及常见问题排查。这些能帮助用户进一步学习和解决问题。 确保所有数学公式用$...$,比如计算占空比时,脉冲宽度和角度的关系式。独立公式如占空比计算使用$$...$$格式。同时正确引用提供的参考文献,比如初始化步骤参考引用2和3,硬件连接参考引用1。 检查LaTeX语法是否正确,使用中文回答,结构清晰。确保示例代码正确,并符合用户的需求。最后验证步骤是否覆盖了配置定时器、设置PWM参数、编写控制函数等关键点,确保用户能逐步实现控制。</think>### STM32控制SG90舵机教程 #### 一、硬件连接 SG90舵机有3根线: - 红色:接5V电源 - 棕色:接GND - 橙色:接STM32的PWM输出引脚(如PA6/TIM3_CH1)[^1] #### 二、PWM参数配置 SG90舵机控制参数: - 周期:$T=20ms$ - 脉冲宽度:$0.5ms \leq t \leq 2.5ms$(对应$0^\circ \sim 180^\circ$) 定时器计算公式: $$ ARR = \frac{T \times F_{clk}}{Prescaler} - 1 $$ 假设使用TIM3,系统时钟72MHz,预分频值71: $$ ARR = \frac{0.02 \times 72 \times 10^6}{72} - 1 = 20000 - 1 $$ #### 三、代码实现 1. **初始化配置** ```c // TIM3初始化(通道1) void PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // PA6配置为复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器基础配置 TIM_TimeBaseStructure.TIM_Period = 19999; // ARR值 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // PWM模式配置 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_OC1Init(TIM3, &TIM_OCInitStructure); TIM_Cmd(TIM3, ENABLE); } ``` 2. **角度控制函数** ```c // 设置角度(0°-180°) void Set_Angle(uint8_t angle) { uint16_t pulse = 500 + angle * (2000 / 180); // 计算脉冲宽度:0.5ms + angle*(2000us/180) TIM_SetCompare1(TIM3, pulse); } ``` 3. **主函数调用** ```c int main(void) { PWM_Init(); while(1) { Set_Angle(0); // 0° Delay_ms(1000); Set_Angle(90); // 90° Delay_ms(1000); Set_Angle(180); // 180° Delay_ms(1000); } } ``` #### 四、注意事项 1. 多个舵机控制时需使用不同定时器通道[^2] 2. 实际应用中需添加死区保护 3. 电源需独立供电避免电流不足
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值