SG90舵机闲谈,附加野火舵机驱动之PWM模式2见解

背景

        很早以前在看江协科技的课程时,他驱动舵机的VCC是5.0V,PWM信号是标准3.3V,舵机能够被正常驱动。但是实际上这种接法并不完全正确。

        由数据手册我们可以看到SG90的供电电压范围为4.8V~6V,5V在合适的范围内。

但是要关心以下两点:

1.数据手册显示在20ms的周期中,1ms的脉冲对应-90°,2ms的脉冲对应90°。(错误版本)

        这与我们熟知的PWM驱动舵机规则是不同的(正确版本)

        并且经过实际测试,数据手册中所给出的1 - 2ms Duty Cycle是不可行的。无法从-90°映射到90°。我又查阅了很多数据手册,发现都是这样写的,排除数据手册大批量出现这么低级的错误的情况,也许是国外的舵机版本与我们的版本不同?

 2.数据手册规定PWM信号的电平最大值为4.8V~5V

        也就是说,舵机的供电以及PWM信号最好都为5V。

        但是经过实测,对于SG90舵机来说,在接5V电压时,不需要额外的PWM电平转换电路,3.3V的PWM信号也能够完全驱动舵机从-90°转动到90°。

        野火作为stm32培训的领头羊,在野火的舵机驱动教程中,他们给出了一套更为严谨的方案:将stm32单片机输出的3.3V PWM信号转化为5V的方案

 分析:

        在J28中,1为GND,2为VCC,3为PWM信号。在这里我们分析3号引脚电路。

        PD12为单片机PWM输出信号。

a. 假设我们输出2.5ms脉冲的舵机驱动信号,理论上PD12处的最高电压为2.5/20*3.3=0.4125V,也就是三极管基极的电压为0.4125V,而根据SS8050的数据手册可知,这是一个硅三极管,该NPN三极管的导通电压Vbe值约为0.7V。PWM输入信号的电压值完全无法使三极管开启。说明此时无法完成PWM电平转换的功能。

b. 假设我们输入占空比为40%的PWM信号,PD12处的最高电压为0.4*3.3=1.32V。

在输出高电平期间,三极管导通,Vce接近于0v,三极管ce视为短接,向舵机输入0v信号;

在输出低电平期间,三极管截至,Vce接近于5V,三极管ce视为断路,向舵机输入5V信号;

从以上我们可以看出,这里的电平转化电路实际上是经历了一个反相。

那我们要如何弥补这个反相呢?

这里介绍下stm32的PWM模式:

        模式1规定,当定时器的计数值CNT小于CCR时输出高电平大于CCR时输出低电平

        模式2规定,当定时器的计数值CNT小于CCR时输出低电平大于CCR时输出高电平

可以看出,模式1与模式2正好是反相的关系。

具体分析为,通过PWM输出1ms的低电平信号时,电平转化电路产生对应的1ms高电平信号;

输出剩余19ms高电平信号时,电平转化电路产生对应的19ms低电平信号,完美补偿了电平转化电路所带来的影响。

因此,野火在这里选择PWM模式2。

以下是CH32V307定时器TIM2 PWM驱动SG90舵机的示例代码,你可以根据需求进行修改: ```c #include "ch32v30x.h" #define SG90_MIN 400 // SG90舵机最小占空比 #define SG90_MAX 2400 // SG90舵机最大占空比 void TIM2_PWM_Init(void) { TIM2_DeInit(); // 复位TIM2寄存器 TIM2_TimeBaseInit(TIM2_PRESCALER_16, 999); // 设置TIM2时钟为16分频,周期为1000 TIM2_Cmd(ENABLE); // 使能TIM2 TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, SG90_MIN, TIM2_OCPOLARITY_HIGH); // 初始化TIM2通道1 TIM2_OC1PreloadConfig(ENABLE); // 使能TIM2通道1预装载寄存器 TIM2_CtrlPWMOutputs(ENABLE); // 使能TIM2 PWM输出 } void SG90_SetPosition(uint16_t position) { if (position < SG90_MIN) // 如果设置位置小于最小值 { position = SG90_MIN; // 将位置设置为最小值 } else if (position > SG90_MAX) // 如果设置位置大于最大值 { position = SG90_MAX; // 将位置设置为最大值 } TIM2_SetCompare1(position); // 设置TIM2通道1占空比 } int main(void) { TIM2_PWM_Init(); // 初始化TIM2 PWM输出 while (1) { // 设置SG90舵机位置为最小值 SG90_SetPosition(SG90_MIN); delay_ms(1000); // 设置SG90舵机位置为最大值 SG90_SetPosition(SG90_MAX); delay_ms(1000); } return 0; } ``` 在这个示例代码中,我们使用了TIM2作为PWM输出的定时器,并通过TIM2通道1来控制SG90舵机的位置。在`TIM2_PWM_Init`函数中,我们初始化了TIM2定时器和通道1,并使能了PWM输出。在`SG90_SetPosition`函数中,我们对输入位置进行了限制,并通过`TIM2_SetCompare1`函数来设置SG90舵机的占空比,从而达到控制位置的效果。最后,在`main`函数中,我们通过循环不断地将SG90舵机的位置设置为最小值和最大值,以验证控制效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Crkylin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值