void main()
{
int i = 1000;
while(1)
{
P1_0 = 1;
delay_us(500); //即最前面的0.5ms高电平,这段是固定的
delay_us(i); //通过调节i的范围 0~1000可以对应0.5~1.5ms的PWM,
P1_0 = 0;
delay_us(20000 - 500 - i); //这是低电平时间,要把整个周期控制在50HZ
}
}
按以上程序的样子写,虽然可以做到调节PWM控制舵机/电调了,但是现实中明显不可能这样做,因为单片机还要做别的事,而且只输出一个通道PWM根本做不出四轴。
我就把我做过或者思考过的两种做多通道商品舵机/电调用的PWM的方法给大家说说,然后对比一下各自的优缺点,我也很期待各位能分享一下其他的方法~
第一种,是我正在用的,用单片机的定时器,输入每个高电平的时间然后拉高引脚开始计时,到时间后拉低引脚,然后在中断里切换到下一个通道,继续拉高引脚重复上一步,纯中断操作。
第二种,是我打算要做的,用单片机定时器做大概10us的中断,一开始直接拉高每个通道的电平,然后每10us把所有通道的值减一,然后判断哪一个通道的值为0了,就拉低电平。
两种方法都能实现多通道PWM信号输出,但是各自的优点缺点都很明显。
第一种
优点:精度高,因为是用定时器计时可以做到远高于8位的精度(我这里10~12位)。每个通道逐个扫描(这也算优点?)。耗费单片机时间少,对系统负荷很轻,在我的飞控里,这片单片机同时负责姿态计算,浮点和三角函数都用了..
缺点:输出的通道少,50HZ的频率时只能输出 13个(0.5~1.5ms)或者8个(0.5~2.5ms)通道,具体为什么,你算算13*1.5 还有8*2.5等于多少就知道了。50HZ,就是要在20ms内把所有通道都扫描一次。同时,也使得PWM频率提不上去,反应迟钝对于飞控来说,的确很棘手。
第二种
优点:支持通道可以达到数十个(假如每2.5ms输出8个通道,20ms内就可以扫描8组通道,一共就可以输出64个通道!!)。输出PWM的频率可以很高(可以做到理论最大值)。
缺点:占用单片机时间很集中(集中在输出高电平的时候)。10us(按0.5~1.5ms对应只能做到7位不到的精度)的定时器中断,不是一般的51能办到的,我用的C8051F 50MIPS都很吃力。
总结以上,第一种方式,适合给同时做连续采集传感器信息,需要连续计算的单片机用,而第二种因为占用时间太集中,更适合单独做成舵机驱动模块,机器人方面应用应该会多一些...
新手习惯用while循环来定时,这样非常容易抖舵,只要有中断,就会开始抖,不用说也知道原因了吧?要解决其实很简单的,只要用硬件定时器就可以了。
另外,控制商品电调/舵机,八位精度足以。我试过一个“标准舵机”,我的八位精度PWM从100慢慢跳到107之后,他才给我羞涩地动了一格... |