找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4031|回复: 2
收起左侧

[求助]51单片机控制舵机程序

[复制链接]
ID:40082 发表于 2012-5-11 19:44 | 显示全部楼层 |阅读模式
向各位大侠求助,用51单片机控制舵机旋转,90度180度都可以,最好将程序略加注释,感谢!!
回复

使用道具 举报

ID:162106 发表于 2017-2-12 14:50 | 显示全部楼层
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
sbit KEY1 = P3^2;        //定义调速的按键
sbit DC = P1^0;                //定义直流电机的控制端口
uchar CYCLE;                  //定义周期
uchar PWM;                    //定义低电平时间
/*********************************
函数:Delay_1ms()
参数:t
返回:无
功能:延时子程序,延时时间为 1ms * del。
          使用晶振是11.0592M。
**********************************/
void Delay_1ms(uint t)
{
        uint i,j;
        for(i=0;i<t;i++)
        {
                for(j=0;j<=100;j++)
                {
                        _nop_();
                }
        }       
}
/*********************************
函数:Time0Init()
参数:无
返回:无
功能:设置定时器0的工作方式2定时时长为100微秒,
      并打开中断和启动定时器。
          该例中使用的单片机晶振为11.0592M。
**********************************/
void Time0Init(void)
{
        TMOD = 0x02;        //设定定时器0工作在方式2模式
        TH0  = 0xA3;    //定时时长为100微秒的初值自动重载
        TL0  = 0xA3;    //定时时长为100微秒的初值
        ET0 = 1;        //打开定时器0中断
        EA = 1;                    //打开总中断
        TR0 = 1;            //启动定时器
}
/*********************************
函数:Time0Int()
参数:无
返回:无
说明:定时器0中断函数。用于处理PWM的信号。
**********************************/
void Time0Int(void) interrupt 1 using 1
{
        static uchar Count;   //当前处于周期的什么时刻
        if(Count == PWM)    //判断低电平时间是否结束
        {
                DC = 1;                 //直流电机转
        }
        Count++;
        if(Count == CYCLE)  //一个周期结束
        {
                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初始化
        CYCLE = 200;        //定义PWM周期为20毫秒
        P2 = 0xfe;          //数码管最后一位亮
        while(1)
        {
                Key();       
        }
}
回复

使用道具 举报

ID:254537 发表于 2018-12-18 23:40 | 显示全部楼层
#include <reg52.h>
unsigned char count;                        //0.5ms次数标识
sbit pwm=P1^0;                                //信号输出
sbit jia=P1^1;                                //角度增加按键
sbit jan=P1^2;                                //角度减小按键
char jd;                                        //角度标识
void delay(unsigned int i)
{
        unsigned int j,k;
        for(j=i;j>0;j--)
                for(k=125;k>0;k--);
}
void Time0_init()                        //定时器初始化
{
        TMOD=0x01;
        IE=0x82;
        TH0=0xff;
        TL0=0x19;                                //12晶振,0.25ms
        TR0=1;                                   //定时器开始
}
void Time0_int() interrupt 1                        //中断程序
{
        TH0=0xff;
        TL0=0x19;
        if(count<jd) //输出count个高电平
                pwm=1;
        else
        pwm=0;    //其余输出低电平
        count++;
        count=count%40;  //时钟保持40个count 即20ms
}
void keyscan()                                //按键扫描
{
        if(jia==0)                                //角度增加键是否按下
        {
                delay(50);                        //按下延时,消抖
                if(jia==0)
                {
                        jd++;                        //角度标识加1
                        count=0;                //按键按下,则20ms周期重新开始
                        if(jd==50)
                                jd=9;                         //已经是180°则保持
                                while(jia==0);         //等待按键放开
                }
        }
        if(jan==0)                                         //角度减小键是否按下
        {
                delay(10);
                if(jd==0);
                {
                        jd--;                                 //角度标识减1
                        count=0;
                        if(jd==0)
                                jd=1;
                        while(jan==0);
                }
        }
}

void main()
{
        jd=1;
        count=0;
        Time0_init();
        while(1)
        {
                keyscan();
//                display();
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表