微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求大神,12M晶振stc89c52驱动舵机,舵机不转

求大神,12M晶振stc89c52驱动舵机,舵机不转

时间:10-02 整理:3721RD 点击:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
sbit KEY1 = P3^5;        //定义调速的按键
sbit DC = P1^0;                //定义舵机的控制端口
uchar CYCLE;                  //定义周期
uchar PWM;                    //定义低电平时间
/*********************************
函数:Delay_1ms()
参数:t
返回:无
功能:延时子程序,延时时间为 1ms * del。
          使用晶振是12M。
**********************************/
void Delay_1ms(uchar c)
//{
//        uint i,j;
//        for(i=0;i<t;i++)
//        {
//                for(j=0;j<=100;j++)
//                {
//                        _nop_();
//                }
//        }       
//}
//{
//    unsigned char a,b;
//    for(;c>0;c--)
//        for(b=38;b>0;b--)
//            for(a=130;a>0;a--);
//}
{
    uchar a,b;
    for(;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}
/*********************************
函数:Time0Init()
参数:无
返回:无
功能:设置定时器0的工作方式2定时时长为100微秒,
      并打开中断和启动定时器。
          该例中使用的单片机晶振为12M。
**********************************/
void Time0Init(void)
{
        TMOD = 0x02;        //设定定时器0工作在方式2模式
        TH0  = 0x00;    //定时时长为100微秒的初值自动重载
        TL0  = 0x9C;    //定时时长为100微秒的初值
        ET0 = 1;        //打开定时器0中断
        EA = 1;                    //打开总中断
        TR0 = 1;            //启动定时器
}
/*********************************
函数:Time0Int()
参数:无
返回:无
说明:定时器0中断函数。用于处理PWM的信号。
**********************************/
void Time0Int(void) interrupt 1
//using 1
{       
        static uchar Count;   //当前处于周期的什么时刻
        TH0  = 0x00;    //定时时长为100微秒的初值自动重载
        TL0  = 0x9C;
        if(Count >= PWM)    //判断低电平时间是否结束
        {
                DC = 1;                 //
        }
        else DC= 0;
        Count++;
        if(Count == 200)  //一个周期结束
        {
                Count=0;
                if(PWM != 0)   //如果左右时间是0 保持原来状态
                {
                        DC = 0;    //
                }
        }
}
/*********************************
函数:Key()
参数:无
返回:无
功能:判断KEY1是否按下并让数码管显示和给PWM提供低电平时长。
**********************************/
void Key(void)
{
        static uchar Number = 1;                 //定义档位,初始化为1档
        if(KEY1 == 0)   // 判断是否有按键按下
          {
                   Delay_1ms(15);   //延时抗干扰信号
                   if(KEY1 == 0)    //再次判断是否有按键按下
              {
                           Number++;           //按一下P3.2口,就给直流电机换一个档位
                          if(Number == 6)   //等于6时,给档位重新赋值1
                        {
                                Number = 1;
               }
                        switch(Number)
                        {
                               case 1:
                                {
                                        P0=0x06;        //数码管显示1       
                                        PWM=175;    //高电平2.5毫秒,舵机旋转到右极限(为+90度)
                                        break;       
                                }
                                   case 2:
                                {
                                        P0=0x5B;        //数码管显示2
                                        PWM=180;    //高电平2毫秒,舵机旋转角度为+45度
                                        break;
                                }
                               case 3:
                                {
                                        P0=0x4F;        //数码管显示3
                                        PWM=185;    //高电平1.5毫秒,舵机旋转角度为0度
                                        break;
                              }
                                case 4:
                                {
                                        P0=0x66;        //数码管显示4
                                        PWM=190;    //高电平1毫秒,舵机旋转角度为-45度
                                        break;
                                }
                                case 5:
                                {
                                        P0=0x6d;        //数码管显示5
                                        PWM=195;    //高电平0.5毫秒,舵机旋转角度为-90度
                                        break;
                               }
                                default:
                                        break;
                           }
                        while(1)    //按键释放
                        {
                                if(KEY1 == 1)   //判断是否释放
                                {
                                        break;
                                }
                        }
                  }
        }
}
/*********************************
函数:Main()
参数:无
返回:无
功能:主函数
**********************************/
void Main(void)
{
        Time0Init();    //定时器0初始化
//        Time0Int();
        CYCLE = 200;        //定义PWM周期为20毫秒
        P0 = 0xfe;          //数码管最后一位亮
        while(1)
        {
                Key();       
        }
}

换个自带PWM的单片机吧,定时器作为PWM的发生源不好用,而且舵机是靠一定频率的PWM来驱动的,是周期小于2ms的PWM,stc系列的就选stc12c5a60s2吧,它有两路PWM。频率可通过定时器来调。很方便。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top