这篇教程与网上的大部分教程都不相同,着重讲述如何使用编程PCA9685,而不是着重讲述原理,最后你还是一头雾水。这是一篇教你如何如何输出固定舵机角度,如何移植程序,从PCA9685的原理到如何移植的教程,在动手中学习理论。
单片机型号:stm32f103c8t6
使用stm32来控制一个舵机并不是难事,但是如果控制多个舵机,那硬件资源就显得捉襟见肘了。
因此,必须使用神器,PCA9685了,相信你能主动上网搜索PCA9685,也一定知道PCA9685是多牛了,我就不去转述了。
我们从整体的keil工程来看一下:
我们需要注意的无非是两个文件,一个是IIC驱动文件,一个是PCA9685的驱动文件,进行移植的话,只要把这两个.C文件和对应的.h文件放到你的工程目录中,即可完成函数的调用,就这么简单? 对,就这么简单。接下来我们详细看一下PCA9685的驱动函数,以及讲解一下PCA9685函数的功能。
void pca_setfreq(float freq)//设置PWM频率
{
u8 prescale,oldmode,newmode;
double prescaleval;
freq *= 0.92;
prescaleval = 25000000;
prescaleval /= 4096;
prescaleval /= freq;
prescaleval -= 1;
prescale =floor(prescaleval + 0.5f);
oldmode = pca_read(pca_mode1);
newmode = (oldmode&0x7F) | 0x10; // sleep
pca_write(pca_mode1, newmode); // go to sleep
pca_write(pca_pre, prescale); // set the prescaler
pca_write(pca_mode1, oldmode);
delay_ms(2);
pca_write(pca_mode1, oldmode | 0xa1);
}
我们都知道舵机是在20ms周期的脉冲中产生一个0.5-2.5ms的脉冲进行控制的,PCA9685驱动中需要手动对舵机控制频率进行设置, 用的就是图上的这个函数,这个函数的具体原理需要参考手册,在这里不讲这些原理,你只要把这个函数直接拿去用,就可以了。
我们设置了频率,也要对占空比进行配置,这样舵机才能按照不同的角度进行控制,LED0_ON_L、LED0_ON_H、LED0_OFF_L、LED0_OFF_H+4这些是PCA9685的IIC地址,由于我们在这里只用到这一个模块,所以取的首地址,再往下看,num、on和off变量,num为模块的通道号,比如控制0号通道,控制1号通道,2号通道等等,取决于你的模块上连了几个舵机,以及你想用哪个舵机,on和off这两个变量是用来配置占空比的。
on:pwm上升计数值0-4096;off:pwm下降计数值0-4096,一个pwm周期分成4096份。
由0开始+1计数,计到on时跳变为高电平,继续计数到off时,跳变为低电平,直到计满4096重新开始。所以当on不等于0时,可作为延时,当on等于0时,0ff/4096的值,就是pwm的占空比。
最后我们看一下舵机通道和角度控制函数,以及函数中一些参数是怎么计算来的。
void Servo_angle(u8 num,u8 angle)
{
u32 off = 0;
off = (u32)(158+angle*2.2);
pca_setpwm(num,0,off);
}
这个函数主要功能是控制通道号和舵机旋转角度,其中一句off = (u32)(158+angle*2.2)有很多同学看不明白,158和2.2是如何得来的?
在这里我们举个例子:
以转到60度为例:
60度对应的脉宽 = 0.5ms+(60/180)*2(2.5ms-0.5ms) = 1.1666ms
换算成占空比= 1.1666ms / 20ms = off /4096,off = 239,50hz对应周期为20ms。
setPWM(num,0,239);
看到这里大家应该就明白158是怎么算的了,参考上面的239,就可以计算出158对应的占空比。
PS:0°对应的值大约为130,180°对应的值为530,最大为590.
158+angle *2.2 = 360.
这样我们就可以按照自己想法来定义舵机输出通道和角度了。
工程中有一个doc文件,对程序中的一些难点加了一些解释和计算过程,希望能帮到大家。