【单片机程序设计】如何单定时器配置多路PWM

刚开始玩单片机的朋友需要控制如:步进电机,舵机,直流电机都是通过利用delay函数粗糙地调控高低电平,有的些朋友可能想优化程序,不喜欢用delay函数,他就会用到定时器来配置PWM。如果你会用一个定时器配置一路PWM,那如何才能高效率运用一个定时器配置多路PWM呢?本文就介绍鄙人以舵机控制为例,其他同理,如何用一个定时器配置多路PWM的一个小思路。

舵机如何工作:

舵机是工作在50hz的脉冲频率,通过控制占空比(0.5-2.5ms)范围来控制舵机转角,脉冲必须以50hz的频率刷新。
比如:一个舵机控制脉冲高电平持续时间0.5ms,低电平持续时间19.5ms,总共20ms(50hz),那么舵机角度为0°如图
【单片机程序设计】如何单定时器配置多路PWM

控制思路:

1.我们了解了舵机的工作方法,那么我们就可以利用舵机周期性变化来控制PWM,每经过20ms统一对多路脉冲输出总线置低电平(或高电平),这里基本脉冲单位配置函数(定时器配置函数):

void int_timer0() interrupt 1

2.用定时器配置多脉冲,那么我们可以利用定时器配置基本脉冲单位(一个tmp的时间),然后根据不同的脉冲宽度需要,再通过扫描判断的方式,达到想要的脉冲单位个数,就对此脉冲输出端口置高电平(或低电平)。

3.现在我们可以输出自己想要的脉冲了,那么怎么区分不同的输出端口呢?其实,我们只需要在置低电平之前,判断是哪路输出端需要配置低电平就ok了。我们用到舵机控制函数

voidServo(uint angle,uchar No)
输入No为pwm编号(1-8)。

程序实现:
定时器配置函数

void int_timer0() interrupt 1

{
       TH0 = (65536-19)/256;              //以10UM为基本脉冲控制单位
       TL0 = (65536-19)%256;
       tmp++;                          //基本脉冲累buff                             
}

舵机控制函数(可连续调用,需要不停刷新函数)
这个有点难理解,我们先看一下函数

void Servo(uint angle,ucharNo)  //型参为角度和舵机编号1-8

{
       code uchar k=0x01;
       pwm = k;
       pwm = _crol_ (i,(No-1));         //通过输入编号对pwm总线进行位操作
       if(tmp <=50+angle+1)             //50即0.5ms,后面加常数1用于后期角度调试
       {
              P1 |=pwm;                       //配置好的赋予pwm总线
       }     
       else if(tmp <=1980)                 //1980(20ms)为具体调试值,需要自己调试
       {
              P1 &=(~pwm);
       }
       else if(tmp >1980)
       {
              tmp = 0;                                   //每20ms对基本脉冲单位累计buff清零
       }
}

现在进行函数讲解:
假设初始状态为高电平,那么我们一直判断是否达到需要低电平的时间,在达到低电平时间点之前tmp<=50+angle,我们将其置高电平
P1 |=pwm;
那么在20ms内的其他时间elseif(tmp <=1980)就都是低电平了
P1 &=(~pwm);
如果累计超出20ms我们就把tmp清零。

有可能有的朋友会不理解,为什么这条函数可以多次使用,但是多组pwm在示波器上几乎是同时进行变化的?其实这要归功于’<=’这个符号,而不是’=’。每次调用函数,函数其实只是执行了一个有效操作,那就是把某端口置高电平或把某端口置低电平。如果函数voidServo(uint angle,uchar No)执行时间足够快那么就可以在精度满足下把20ms中都抽一点点时间来控制高低电平,就可以重复调用<200次了,也就是一个定时器可以发出<200路pwm。具体还是看晶振和单片机分频啦。怎么样?赶紧试试看吧

上一篇:模拟舵机学习(c8t6主控制器)


下一篇:使用树莓派制作智能小车