STC8H系列—15.硬件PWM控制SG90舵机教程

一、概述:

   STC8H系列16位高级PWM定时器输出PWM波在上一节有一定的介绍,这里对于控制原理不再作出复述,感兴超的朋友可以回看上一节的内容。

这一节主要目标是应用硬件PWM控制SG90舵机,其重点是通过计算精确输出固定周期(20ms)的脉冲,通过精确的改变一定范围的脉宽(0.5ms-2.5ms)实现舵机不同角度的精确控制,关于精确控制舵机的应用的意义不在本文的探讨范围。

STC8H内置了8个PWM输出通道,理论上不使用其它资源的前提下即可独立去控制8个舵机设备,硬PWM的控制简单,对CPU的资源消耗少,在多舵机控制应用场景下有一定的使用价值,下面的实例讨论PWM,K0每按键一次,舵机反向(逆时针)偏转45度,K1每按一次键一次,舵机正向(顺时针)偏转45度,当计算好PWMA_ARR值后输出固定周期的PWM波,动态改变PWMA_CCR的值即改变不同的脉宽即可实现舵机的控制。

二、知识链接:

   1、时基单元:

CK_PSC为时钟源,过分频器后得到CK_CNT用来计数,PWMA_ARR用来控制脉冲的周期,PWMA_CNTR用来计数。

当计数器的值到达PWMA_ARR时,计数器的值清零,又重新开始计数。

关于时钟源CK_PSC的来源有4种来源,通过PWMA_SMCR的SMS位控制,其中ECE为外部时钟使能,当使用外部时钟模式时即必须将ECE置1。

2、PWM模式:

当PWMA_CR寄存器中的DIR=0时,执行向上计数。

当PWMA_CNT< PWMA_CCR1时,PWM输出高电平,否则输出低电平。

3、高级PWM功能脚的切换:

以下的实例开启P1.0与P1.1作为PWMA通道1输出端

4、输出使能端:

开启EON1P位置1(P1.1)与开启EON1N位置1(P1.2)

5、捕获比较使能寄存器:

开启CCINE=1和CC1E=1使能PWMA通道1比较器工作。

6、捕获比较模式寄存器:

选择OC1M=110为PWM模式1,OC1PE=1开启PWM的预装功能:

7、工作原理:

舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前在高档遥控玩具,如航模,包括飞机模型,潜艇模型;遥控机器人中已经使用得比较普遍。舵机是一种俗称,其实是一种伺服马达。

SG90 舵机技术参数: 

产品名称

SG90 9g 塑料齿数字舵机

产品净重

9g

产品尺寸

23*12.2*29mm

产品扭矩

1.5kg/cm

反应速度

0.3sec/60degree

工作电压

4.2V-6V

使用温度

0-55

动作死区

10us

齿轮介质

塑料

工作模式

模拟

控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
 

  舵机的控制信号是PWM信号,利用占空比的变化改变舵机的位置。

8、控制原理:

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

   0.5ms--------------0度;

   1.0ms------------45度;

   1.5ms------------90度;

   2.0ms-----------135度;

   2.5ms-----------180度;

请看下形象描述吧:

9、频率计算:

例如:当SYSclk=12M=12000000Hz时,周期为20ms的PWM频率输出,需要得到0.5ms,1.0ms,1.5ms,2.0ms,2.5ms,计算各寄存器的配置能数PWMA_PSCR分频值,PWMA_ARR周期值,和对应的PWMA_CRR的占空比值。

解:

1、单位输出:

PWM输出频率=1s/20ms=1000ms/20ms=50Hz

点空比:0度--->0.5ms/20ms=1/40

        45度--->1ms/20ms=1/20

        90度--->1.5ms/20ms=3/40

        135度--->2.0ms/20ms=1/10

        180度--->2.5ms/20ms=1/8

2、求出分频倍数

12000000/50=240000

2、求出组合分频:

(PWMA_PSCR+1)*( PWMA_ARR+1)=(3+1)*(59999+1)

PWMA_PSCR=0x0003

PWMA_ARR=0xEA5F

3、求出占空比的值:

PWMA_CCR点空比值:

0度--->60000*1/40=1500

        45度--->60000*1/20=3000

        90度--->60000*3/40=4500

        135度--->60000*1/10=6000

        180度--->60000*1/8=7500

三、实验平台搭建:

   1、MCU:STC-打狗棒系列核心实验板 V2.3

   2、实验板平台:德飞莱LY-51s 

   3、硬件连接表:

         P10---------->S(橙色)

         +5V---------->VCC(红色)

         GND---------->GND(棕色)

          K0---------->P20(每控一次反向偏转45度)

         K1---------->P21(每控一次正向偏转45度)

四、测试源代码:

#include <STC8H.h>

#include "intrins.h"

void Delay1ms(unsigned char x);//当主时钟频率为12M,1ms延时为基准

void init_IO();//初始化IO

void init_PWM();

void main()

{

    unsigned int num=1500;  //用于改变PWM的占空比增量变量

     P_SW2 |= 0x80;  //扩展寄存器XFR访问使能 

      init_IO();

      init_PWM();

   while(1)

    {

       //每按一次K0舵机正向转动45度,分别是0度->45度->90度->135度->180度

       if(P20==0)

       {

          Delay1ms(20);

          if(P20==0)

           {

                 Delay1ms(20);

                while(P20==0);

                if(num<7500)

                    num+=1500;

           }

       }

       

       //每按一次K1舵机反向转动45度,分别是180度->135度->90度->45度->0度

       if(P21==0)

       {

          Delay1ms(20);

          if(P21==0)

           {

                 Delay1ms(20);

                while(P21==0);

                if(num>1500)

                    num-=1500;

           }         

       }

       

      PWMA_CCR1H = num>>8; //更新占空比时间

    PWMA_CCR1L = num; 

      }

}



void init_IO()

{

   RSTCFG=0x50;  //开启RST键进入ISP模式

   P0M1 = 0x00;   P0M0 = 0x00;   //设置P0口为准双向口

   P1M1 = 0x00;   P1M0 = 0x00;   //设置P1口为准双向口

   P2M1 = 0x00;   P2M0 = 0x00;   //设置P1口为准双向口

   P5M1 = 0x00;   P5M0 = 0x00;   //设置P5口为准双向口

}



void init_PWM()

{

      PWMA_CCMR1 = 0x68;

     PWMA_CCER1 = 0x05;

  

     PWMA_PSCRH=0x00;//设置时钟分频

     PWMA_PSCRL=0x03; 



      PWMA_ARRH = 0xEA; //设置周期时间

    PWMA_ARRL = 0x5F;

     

     PWMA_ENO |= 0x01; //使能输出P10

  

     PWMA_PS = 0x00;  //高级 PWM 通道输出脚选择位

     

     PWMA_BKR = 0x80; //使能主输出

    PWMA_CR1 |= 0x01; //开始计时 



    PWMA_CCR1H = 0x05; //设置占空比时间0.5ms-----复位0度

   PWMA_CCR1L = 0xDC;

}





void Delay1ms(unsigned char x)    //@12.000MHz

{

   unsigned char i, j;

   while(x--)

   {

      i = 16;

     j = 147;

      do

      {

        while (--j);

      } while (--i);

   } 

}

猜你喜欢

转载自blog.csdn.net/qq_21082985/article/details/132339989