• 其工作原理是由控制器发出PWM(脉冲宽度调制)信号给舵机,经电路板上的IC处理后计算出转动方向, 再驱动无核心马达转动,透过减速齿轮将动力传至摆臂,同时由位置检测器(电位器)返回位置信号,判断是否已经到达...

    舵机,又称伺服马达,是一种具有闭环控制系统的机电结构。舵机主要是由外 壳、电路板、无核心马达、齿轮与位置检测器所构成。其工作原理是由控制器发出PWM(脉冲宽度调制)信号给舵机,经电路板上的IC处理后计算出转动方向, 再驱动无核心马达转动,透过减速齿轮将动力传至摆臂,同时由位置检测器(电位器)返回位置信号,判断是否已经到达设定位置,一般舵机只能旋转180度。舵机有3根线,棕色为地,红色为电源正,橙色为信号线,但不同牌子的舵机,线的颜色可能不同,需要注意。

    舵机的转动位置是靠控制PWM(脉冲宽度调制)信号的占空比来实现的,标准PWM(脉冲宽度调制)信号的周期固定为20ms,占空比0.5~2.5ms 的正脉冲宽度和舵机的转角-90°~90°(即0~180度)相对应。注意,由于舵机牌子不同,其控制器解析出的脉冲宽度也不同,所以对于同一信号,不同牌子的舵机旋转的角度也不同。其原理是:它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号, 控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。

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

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

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

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

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

     

    采用11.0592MHZ51单片机驱动舵机转动程序如下:

    //上电自动转动
    
    #include <reg52.h>
    
    unsigned char count;      //0.5ms次数标识
    
    sbit pwm =P1^0 ;          //PWM信号输出
    
    sbit jia =P2^4;           //角度增加按键检测IO口
    
    sbit jian =P2^5;           //角度减少按键检测IO口
    
    unsigned char jd;         //角度标识
    
     
    
    sbit pwm1 =P0^0 ;          //PWM信号输出给示波器,检测PWM波用
    
    void delay(unsigned char i)//延时
    
    {
    
      unsigned char j,k;
    
      for(j=i;j>0;j--)
    
        for(k=125;k>0;k--);
    
    }
    
    void Time0_Init()          //定时器0初始化
    
    {
    
    //定时器0装初值 用示波器检测后,11.0592MHZ晶振 定时0.5ms进入中断 装初值如下
    
    TH0  = (65536-445)/256;
    
    TL0  = (65536-445)%256;
    
     
    TMOD = 0x01;    //定时器0工作在方式1   
    
    IE = 0x82;	//IE=0x82=1000 0010 等价于 EA=1 开总中断  ET0=1 开定时器0中断
    
      TR0=1;          //开定时器0
    
    }
    
    void Time0_Int() interrupt 1 //中断程序
    
    {
    
    //重装初值
    
    TH0  = (65536-445)/256;
    
    TL0  = (65536-445)%256;
    
     
    
        if(count< jd)
    
    {
    
     pwm=1;                  //确实小于,PWM输出高电平
    
     pwm1=pwm;              //接示波器用的io口,观测PWM波形用	    }	//判断0.5ms次数是否小于角度标识
    
     //pwm=1;                  //确实小于,PWM输出高电平
    
        else
    
    {
    
     pwm=0;                  //确实小于,PWM输出高电平
    
     pwm1=pwm;             //接示波器用的io口,观测PWM波形用	}
    
        //  pwm=0;                  //大于则输出低电平
    
        count=(count+1);          //0.5ms次数加1
    
        count=count%40;     //次数始终保持为40 即保持周期为20ms
    
    }
    
     
    
    //此注销掉部分为通过按键控制舵机转动的程序,功能为通过jia按键控制正转,
    
    //通过jian按键控制反转
    
    /*void keyscan()              //按键扫描
    
    {
    
       if(jia==0)               //角度增加按键是否按下
    
      {
    
        delay(10);              //按下延时,消抖
    
        if(jia==0)              //确实按下
    
         {
    
          jd++;                 //角度标识加1
    
          count=0;              //按键按下 则20ms周期从新开始
    
          if(jd==6)
    
            jd=5;               //已经是180度,则保持
    
          while(jia==0);        //等待按键放开
    
         }
    
      }
    
      if(jian==0)                //角度减小按键是否按下
    
      {
    
        delay(10);
    
        if(jian==0)
    
         {
    
          jd--;                 //角度标识减1
    
          count=0;
    
          if(jd==0)
    
            jd=1;               //已经是0度,则保持
    
          while(jan==0);
    
         }
    
      }
    
    }*/
    
     
    void main()
    
    {
    
    //上电,舵机自动正反转    
    
    //应注意每次步进是延时函数delay参数的设置,此处延时函数参数设置的并不理想    
    
    while(1)
    
    {
    
      for(jd=1;jd<6;jd++)
    
    {
    
    count=0;
    
    Time0_Init();
    
    delay(50000000);
    
    }
    
    delay(50000000);
    
    for(jd=6;jd>0;jd--)
    
    {
    
    count=0;
    
    Time0_Init();
    
    delay(50000000);
    
    }
    
    }
    
    }


     

    展开全文
  • 通过按键控制舵机的左转和右转,舵机工作周期为20ms.本程序非常简单易懂,希望可以帮到有需要的人。
  • 51单片机控制舵机程序
  • 51单片机控制舵机

    2018-08-04 08:14:19
    舵机简介 舵机一般由舵盘、减速齿轮组、位置反馈电位计5k、直流电机、控制电路板等。一般情况下舵机的信号线为黄色或白色,电源分4.8V和6V,分别对应不同的转矩标准。   PWM控制方法 PWM通过占空比来控制舵机,...

    舵机简介

    舵机一般由舵盘、减速齿轮组、位置反馈电位计5k、直流电机、控制电路板等。一般情况下舵机的信号线为黄色或白色,电源分4.8V和6V,分别对应不同的转矩标准。

     

    PWM控制方法

    PWM通过占空比来控制舵机,占空比周期T=20ms,高电平方波持续时间为0.5ms~2.5ms.对应舵机角度为:

     

     

     

    对于t = 0.5ms~2.5ms 的产生,写程序时我们可以采用全局变量。让全局变量等于5~25之间,因为舵机的一个计数周期是0.1ms,这样全局变量的5~25正好就是0.5ms~2.5ms

     

    PWM波产生思路:将信号管脚线初始化为低电平,然后写一个while循环,在循环中将该管脚置为为高电平,延时,再拉低为低电平,如此循环产生PWM波,以高电平产生时间来控制舵机转动角度。

    注意:5mv以上的控制电压的变化就会引起电机的抖动。

     

    基于单片机的控制:

     

    单片机系统实现对舵机输出转角的控制,必须先完成两个任务:

     

    1、产生    PWM周期信号,本设计产生一个20ms的周期信号;

     

    2、脉宽的调整,即单片机模拟PWM信号的输出,并调整占空比。

     

    当系统中只需要实现一个舵机的控制,采用的控制方式是改变单片机的一个定时器中断的初值,将20ms分为两次中断执行,一次短定时中断和一次长定时中断。这样既节省了硬件电路,也减少了软件开销,控制系统工作效率和控制精度都很高。

     


     具体的设计过程:例如想让舵机转向左极限的角度,它的正脉冲为2ms,则负脉冲为20ms-2ms=18ms,所以开始时在控制口发送高电平,然后设置定时器在2ms后发生中断,中断发生后,在中断程序里将控制口改为低电平,并将中断时间改为18ms,再过18ms进入下一次定时中断,再将控制口改为高电平,并将定时器初值改为2ms,等待下次中断到来,如此往复实现PWM信号输出到舵机。用修改定时器中断初值的方法巧妙形成了脉冲信号,调整时间段的宽度便可使伺服机灵活运动。

     

      为保证软件在定时中断里采集其他信号,并且使发生PWM信号的程序不影响中断程序的运行(如果这些程序所占用时间过长,有可能会发生中断程序还未结束,下次中断又到来的后果),所以需要将采集信号的函数放在长定时中断过程中执行,也就是说每经过两次中断执行一次这些程序,执行的周期还是20ms。

    如果系统中需要控制几个舵机的准确转动,可以用单片机和计数器进行脉冲计数产生PWM信号。

    脉冲计数可以利用51单片机的内部计数器来实现,但是从软件系统的稳定性和程序结构的合理性看,宜使用外部的计数器,还可以提高CPU的工作效率。

     

    
    #include <reg52.h>      
    
    #include <math.h>
    
    typedef unsigned char uchar;
    
    typedef unsigned int uint;
    
    sbit  KEY1=P3^4;					//按键1
    
    sbit  KEY2=P3^5;					//按键2
    
    sbit PWM_OUT=P2^7;				//PWM输出口
    
    uint PWM_Value;			//定义pwm值
    
    uchar order=0; 
    
    void Delay(unsigned int s);      //延时函数声明
    
    uchar flag;									//舵机按键标志
    
    
    
    
    /*延时函数*/
    void Delay(unsigned int s)
    
    {
    
    unsigned int i;
    
    for(i=0; i<s; i++);
    
    for(i=0; i<s; i++);
    
    }
    
    
    
    /*定时器初始化*/
    void Init_Timer0()        
    
    {
    
    TMOD=0x11;
    
    TH0=(65536-1500)/256;
    
    TL0=(65536-1500)%256;
    
    EA = 1;
    
    ET0 = 1;
    
    TR0 = 1;
    
    PT0=1;
    
    }               
    
    
    /*主函数*/
    void main(void)
    
    {
    
    Delay(6000);
    
    PWM_Value = 1500;					//pwm初值为1500
    
    
    
    Init_Timer0();
    
    while(1)
    
    {
    
    if((KEY1 ==0 )|(KEY2 ==0 ))							//按键1或按键2被按下
    
    {
    
    if(KEY1 ==0 )												//确认按键1被按下
    
    {
    
    flag = 1;												//标志位赋值1
    
    }
    
    if(KEY2 ==0 )									//确认按键2被按下
    
    {
    
    flag = 2;											//标志位赋值2
    
    }
    
    }
    
    else
    
    {
    
    flag = 0;								//否则标志位为0
    
    }
    
    Delay(20);								//延时20ms
    
    } 
    }
    
    
    /*****中断程序*******/
    void timer0(void) interrupt 1 
    
    {       
    
    if(flag==1)	PWM_Value += 1;							//如果标志位1时,pwm的值加1
    									
    if(flag==2)	PWM_Value -= 1;							//如果标志位为2时,pwm减1
    
    
    
    
    
    if(PWM_Value>=2500)										//如果pwm的值大于2500
    
    PWM_Value = 2500;												//则保持在2500
    
    
    
    
    
    if(PWM_Value<=500)											//如果pwm的值小于500
    
    PWM_Value=500;													//则保持在500
    
    
    
    
    
    switch(order)
    
    {
    
    	case 1:PWM_OUT=1;
    
    		   TH0=(65536-PWM_Value)>>8; 
    
    		   TL0=(uchar)(65536-PWM_Value);
    
    		   break;                          
    
    	case 2:PWM_OUT=0;
    
    		   TH0=(65536-(5000-PWM_Value))>>8;    
    
    		   TL0=(uchar)(65536-(5000-PWM_Value));
    
    		   break;                          
    
    	   
    
    	
    	case 3:
    
    		   TH0=60536>>8;   
    
    		   TL0=(uchar)60536;
    
    		   break;
    
    	case 4:
    
    		   TH0=60536>>8;   
    
    		   TL0=(uchar)60536;
    
    		   order=0;
    
    		   break;
    
    default: order=0; 
    
    		   break;
    
    }
    
              order++;
    
    }

     

    展开全文
  • 51单片机舵机控制

    2019-10-29 20:39:00
    51单片机舵机控制系统概述硬件设计程序设计 概述 在这篇博客中,将介绍一个基于51单片机舵机控制系统,其可以通过矩阵按键输入角度,舵机打到预定角度,并在数码管上显示。 硬件设计 这次的小系统电路都由洞洞...

    概述

    在这篇博客中,将介绍一个基于51单片机的舵机控制系统,其可以通过矩阵按键输入角度,舵机打到预定角度,并在数码管上显示。

    硬件设计

    这次的小系统电路都由洞洞板搭建,主要包括51单片机最小系统,矩阵按键,数码管驱动和舵机四个部分。Protues仿真电路图如下
    在这里插入图片描述

    • 数码管驱动
      仿真测试程序数码管时可以直接用IO口驱动,但是实物搭建电路需要再接驱动电路,这次选择了74HC245芯片来驱动。这款芯片使用非常简单,在驱动显示屏,做隔离芯片时应用都非常多。它有A0-A7,B0-B7两组输入输出口,可以DIR管脚选择数据传输方向,在使用时如果不需要转换传输方向可以直接将此管脚接到芯片VCC或者GND。
      在这里插入图片描述

    • 矩阵按键
      4*4的矩阵按键每一行每一列接在一个口上,通过行列扫描确定哪一个按键被按下,也就是导通。

    • 舵机
      舵机一般分为数字舵机和模拟电机。它们都由马达,减速齿轮组和控制电路组成。主要区别是数字电机有微处理器和晶振,能产生一周期为20ms,占空比为7.5%(即1.5ms高电平)的基准信号,通过输入与信号比较确定打角。而模拟电机则通过电位器产生的差分电压驱动电机正反转从而改变角度。这次选用的是SG90 180度的模拟舵机,价格低,带动一个激光头绰绰有余。通过单片机输出的周期为20ms的PWM波控制,在宽度从0.5ms到2.5ms,每一个占空比对应一个角度,示意图如下
      在这里插入图片描述

    程序设计

    PWM波的产生

    在51单片机中,没有可以直接调用产生PWM波的底层库,需要自己用定时器写。一般产生PWM波能用两个定时器写,每一个定时器只固定拉高或者拉低,靠时间差确定周期。也可以只用一个定时器写,通过改变装载值来反复改变电平。以下详细说明用一个定时器写的方式,另外一个定时器空余出来可以实现更多功能。
    一个定时器产生PWM波需要两组装载值,分别控制高低电平时间。设置一个全局变量作为中断标志位确定用哪一组装载值,拉高还是拉低电平,每一次进入中断后改变标志位的值。舵机180度对应每周期高电平时间0.5到2.5ms,可调范围2ms,用12M晶振时也就是2000个机器周期长,得到装载值与角度关系系数为11.11,取11,再加0.5ms对应的500个机器周期,就能得到角度与高电平对应值的关系。
    机器周期数=角度*11+500
    *周期20ms减去高电平时间就能换算出低电平对应装载值。*如果想要更精确,系数和对应值可以用浮点型,在最后计算装载值时再强制转换成整型。
    把这段程序单独贴出来

     /*******************************************************
     装载值计算函数
    *******************************************************/
     void zhuang(u8 jiaodu)
     {
       u16 zhuangza; //高电平对应机械周期数
       zhuangza=jiaodu*11+500;  //2000/180=11.11  
       H1=  (65536-zhuangza)/256; 
       L1 = (65536-zhuangza)%256;
       H2 = (45536+zhuangza)/256;//65535-(2000-高电平值)
       L2 = (45536+zhuangza)%256;
     }
     
    /*******************************************************
    定时器1中断服务函数
    *******************************************************/
    void Time1(void) interrupt 3    
    {
     if(servoflag==0) //中断标志位
     {
     TH1 = H1; 
     TL1 = L1;   
     PWM=1;
     servoflag=1;
     }
     else if(servoflag==1)
     {
     TH1 = H2; 
     TL1 = L2;   
     PWM=0;
     servoflag=0;
     } 
    }    

    矩阵按键功能与数码管显示参数传递

    矩阵按键前10个值分别对应0到9。10为确定键,按下后在主函数中将按键读到的几个一位数转换成角度,传给装载值计算函数,改变PWM波占空比,舵机打到对应角度。另外设计了11,12,13三个键,按下后能使舵机直接打到程序预定好的角度。相应按键功能分配在主函数中。具体程序不再赘述。
    为了使输入多位数时能正确显示,让数码管的每一位固定显示个、十、百位,对应数组的四个元素,初值不显示,输入低位后,接受按键值的元素移向高位。

    完整程序

    #include "reg52.h"
    
    typedef unsigned int u16;   
    typedef unsigned char u8;
    
    sbit LA=P2^4;     //数码管位选
    sbit LB=P2^1;
    sbit LC=P2^2;
    sbit LD=P2^3;
    sbit PWM=P2^5;   //PWM输出口
    u8 code smgduan[17]={0x3f,0x06,0x9b,0x8f,0xA6,0xAd,0xBd,0x07,0xBf,
    0xAf,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    //0到9,大于9不显示
    u8 f=0; 
    static u8 jiaodu=0; //角度
    u8 keyflag,servoflag;  //按键标志位,中断标志位
    u8 H1=0xFA,L1=0x24,H2=0xB7,L2=0xBC;  //两组装载值
    u16 zhuangzai;    
    u8 w[4]={16,16,16,16};   //按键输入值保存数组,初值16不显示
    u8 KeyValue;  //按键值
    /*******************************************************
    延时函数
    *******************************************************/
    void delay(u16 i)
    {
     while(i--); 
    }
    /*******************************************************
    定时器1初始化
    *******************************************************/
    
    void Timer1Init()
    {
     TMOD|=0X10;
     
     TH1 = 0xFC; 
     TL1 = 0x18;
     ET1=1;   
     EA=1;
     TR1=1; 
    }
    /******************************************************
    装载值计算函数
    *******************************************************/
    void zhuang(u8 jiaodu)
     { 
      u16 zhuangza;
     zhuangza=jiaodu*11+500;  //高电平对应值与角度换算
      H1=  (65536-zhuangza)/256; //H,L分别是装载值高、低8位
     L1 = (65536-zhuangza)%256;  //1是高电平装载值,2是低电平装载值
     H2 = (45536+zhuangza)/256;
     L2 = (45536+zhuangza)%256;
    }
    /*******************************************************
    数码管动态扫描
    *******************************************************/
    void DigDisplay()    
    {
     u8 i;
     for(i=0;i<4;i++)
     {
      switch(i)  
      {
       case(0):
        LA=0;LB=1;LC=1;LD=1; P0=smgduan[w[0]];break;
       case(1):
        LA=1;LB=0;LC=1;LD=1; P0=smgduan[w[1]];break;
       case(2):
        LA=1;LB=1;LC=0;LD=1; P0=smgduan[w[2]];break;
       case(3):
        LA=1;LB=1;LC=1;LD=0; P0=smgduan[w[3]];break;
      } 
      delay(10);  
      P0=0x00;
    //  delay(100);   //不加亮度更高
     }
    }
    /*******************************************************
    矩阵按键扫描
    *******************************************************/
    void KeyDown(void)
    {
     char a=0;
     P1=0x0f;
     if(P1!=0x0f)
     {
      delay(1000);//消抖
      if(P1!=0x0f)
      { 
       keyflag=1;
       //测试列
       P1=0X0F;
       switch(P1)
       {
        case(0X0e): KeyValue=0;break;
        case(0X0d): KeyValue=1;break;
        case(0X0b): KeyValue=2;break;
        case(0X07): KeyValue=3;break;
       }
       //测试行
       P1=0XF0;
       switch(P1)
       {
        case(0Xe0): KeyValue=KeyValue;break;
        case(0Xd0): KeyValue=KeyValue+4;break;
        case(0Xb0): KeyValue=KeyValue+8;break;
        case(0X70): KeyValue=KeyValue+12;break;
       }
       while((a<50)&&(P1!=0xf0))  //松手检测
       {
        delay(1000);
        a++;
       }
      }
     }
    }
    /*******************************************************
    主函数
    *******************************************************/
    void main()  
    {
     u8 i=0;
     Timer1Init();  //定时器1初始化
     while(1)
     {
      DigDisplay();
      KeyDown();
      if(keyflag==1)
      {
       w[i]=KeyValue;
          i++;
       keyflag=0;
      }
      if(KeyValue==10)    //确定键
      {
       for(i=0;w[i]<10;i++)
        jiaodu=jiaodu*10+w[i];
       zhuang(jiaodu);
       jiaodu=0;
      }
      if(KeyValue==12)
      {
       zhuang(87);      //特定角度
      }
      if(KeyValue==13)
      {
       zhuang(97);
      }
       if(KeyValue==14)
      {
       zhuang(109);
      }
     }  
    }
    /*******************************************************
    定时器中断服务函数
    *******************************************************/
    void Time1(void) interrupt 3    
    {
     if(servoflag==0) 
     {
     TH1 = H1; 
     TL1 = L1;   
     PWM=1;
     servoflag=1;   //改变值,下次进入中断用另一组装载值
     }
     else if(servoflag==1)
     {
     TH1 = H2; 
     TL1 = L2;   
     PWM=0;
     servoflag=0;
     } 
    }

    外加模块

    为了增加系统的趣味性,可以在舵机上安装激光头,距离一定距离放置三个目标靶,将其角度写入程序,则可以通过特定按键打靶。还可以在目标靶上增加指示电路,是激光打到靶后指示灯亮,可以通过光敏电阻的简单电路实现。

    展开全文
  • 51单片机舵机角度控制程序 ,定时器实现的角度控制程序。 内容为KIEL C程序文件
  • 单片机控制舵机

    2019-06-08 16:47:56
    通过按键控制MCU输出不同占空比的PWM信号来控制舵机旋转不同角度; 同时在LCD1602实时显示当前舵机的角度。 仿真原理图如下: C语言代码如下: /*----------------------------- FileName: Servo.h Function...

    项目描述:
    通过按键控制MCU输出不同占空比的PWM信号来控制舵机旋转不同角度;
    同时在LCD1602实时显示当前舵机的角度。
    仿真原理图如下:
    在这里插入图片描述
    C语言代码如下:

    /*-----------------------------
    FileName: Servo.h
    Function:头文件
    Author: Zhang Kaizhou
    Date: 2019-6-7 13:52:49
    ------------------------------*/
    #include <reg52.h>
    #include <string.h>
    #define uchar unsigned char
    #define uint unsigned int
    #define PERIOD 40 // 定时40次,周期为20ms
    	
    /*主控模块的端口定义*/
    sbit angleAdd = P1^3;
    sbit angleDecrease = P1^4;
    sbit servoPWM = P3^1;
    
    /*LCD1602显示模块端口定义*/
    sbit lcdrs = P1^0;
    sbit lcdrw = P1^1;
    sbit lcden = P1^2;
    
    /*主控模块函数声明*/
    void timer0Init();
    void keyScan();
    
    /*LCD1602显示函数声明*/
    void LCDInit();
    void displayInit();
    void display(uchar dat);
    void writeCommand(uchar command);
    void writeData(uchar angle);
    void delay(uchar xms);
    
    /*-----------------------------------------------------
    FileName: main.c
    Function: 单片机控制舵机
    Description: 按键控制单片机输出不同占空比的PWM信号
    控制舵机在0 ~ 360度范围内进行旋转;旋转的单位角度为45度
    Author: Zhang Kaizhou
    Date: 2019-6-7 13:50:21
    ------------------------------------------------------*/
    #include "Servo.h"
    
    uchar angle = 1; // 初始角度默认为0度
    uchar count = 0; // 初始定时次数为0次
    
    void main(){
    	timer0Init();
    	LCDInit();
    	displayInit();
    	while(1){
    		keyScan();
    		display(angle);
    	}
    }
    
    /*定时器0初始化函数*/
    void timer0Init(){
    	TMOD = 0x01; // timer0 工作方式一(16位定时器)
    	EA = 1; // 开全局中断
    	ET0 = 1; // 开C/T0溢出中断允许
    	TH0 = (65536 - 500) / 256; // 装初值(定时器0定时0.5ms,晶振12MHz)
    	TL0 = (65536 - 500) % 256;
    	TR0 = 1; // 启动定时器0
    }
    
    /*定时器0溢出中断服务程序*/
    void timer0Service() interrupt 1{
    	TH0 = (65536 - 500) / 256;
    	TL0 = (65536 - 500) % 256;
    	if(count < angle){
    		servoPWM = 1;
    	}else if(count < (PERIOD - angle)){
    		servoPWM = 0;
    	}
    	count++;
    }
    
    /*键盘扫描函数*/
    void keyScan(){
    	if(!angleAdd){ // 角度加键按下
    		delay(5);
    		if(!angleAdd){
    			if(angle < 9){ // 角度小于最大旋转角
    				while(!angleAdd); // 等待按键释放
    				angle++; // 角度加1
    			}else{ // 角度大于等于最大旋转角
    				while(!angleAdd);
    				angle = 9; // 保持最大旋转角
    			}
    		}
    	}
    	if(!angleDecrease){ // 角度减键按下
    		delay(5);
    		if(!angleDecrease){
    			if(angle > 1){ // 角度大于0度时减1个档位
    				while(!angleDecrease);
    				angle--;
    			}else{ // 角度为0度时保持最小旋转角
    				while(!angleDecrease);
    				angle = 1;
    			}
    		}
    	}
    }
    
    /*-----------------------------
    FileName:display.c
    Function: LCD1602显示函数
    Author: Zhang Kaizhou
    Date: 2019-6-7 13:52:11
    ------------------------------*/
    #include "Servo.h"
    
    uchar code table0[] = {"Servo Info"}; // 每行的字符数据
    uchar code table1[] = {"Angle:"};
    uchar code table2[][10] = {"000", "045", "090", "135", "180", "225", "270", "315", "360"};
    
    /*初始化LCD1602的设置*/
    void LCDInit(){
    	lcden = 0; // 拉低使能端,准备产生使能高脉冲信号
    	writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口)
    	writeCommand(0x0c); // 开显示,不显示光标
    	writeCommand(0x06); // 写一个字符后地址指针自动加1
    	writeCommand(0x01); // 显示清零,数据指针清零
    }
    
    /*LCD上电界面*/
    void displayInit(){
    	uchar i;
    	writeCommand(0x80); // 将数据指针定位到第一行首
    	for(i = 0; i < strlen(table0); i++){
    		writeData(table0[i]);
    		delay(5);
    	}
    	
    	writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首
    	for(i = 0; i < strlen(table1); i++){
    		writeData(table1[i]);
    		delay(5);
    	}
    }
    
    /*LCD显示函数*/
    void display(uchar angle){
    	uchar i;
    	writeCommand(0x80 + 0x40 + strlen(table1));
    	for(i = 0; i < strlen(table2[angle - 1]); i++){
    		writeData(table2[angle - 1][i]);
    		delay(5);
    	}
    }
    
    /*写指令函数*/
    void writeCommand(uchar command){
    	lcdrs = 0; // 命令选择
    	lcdrw = 0;
    	P0 = command;
    	delay(5);
    	
    	lcden = 1; // 产生一个正脉冲使能信号
    	delay(5);
    	lcden = 0;
    }
    
    /*写数据函数*/
    void writeData(uchar dat){
    	lcdrs = 1; // 数据选择
    	lcdrw = 0;
    	P0 = dat;
    	delay(5);
    	
    	lcden = 1;
    	delay(5);
    	lcden = 0;
    }
    
    /*延时函数*/
    void delay(uchar xms){
    	uint i, j;
    	for(i = xms; i > 0; i--)
    		for(j = 110; j > 0; j--);
    }
    
    展开全文
  • STC15控制舵机

    2020-06-15 17:09:09
    STC15 pwm模块 控制舵机 舵机旋转 延时函数由stc-isp-15xx-v6.86O.exe 生成
  • #include "STC15F2K60S2.h" #include "INTRINS.H" #define uchar unsigned char #define uint unsigned int uint a; sbit pwm=P0^0; sbit IN1=P0^1; sbit IN2=P0^2; ...sbit beep=
    #include "STC15F2K60S2.h"  
    #include "INTRINS.H"


    #define uchar unsigned char
    #define uint unsigned int


    uint a;
    sbit pwm=P0^0;
    sbit IN1=P0^1;
    sbit IN2=P0^2;
    sbit flage=P1^1;
    sbit beep=P1^2;


    void init()


    {


    a=200;
    p10=0;

    TMOD=0x11;

    TH0=(65536-100)/256;

    TL0=(65536-100)%256;

    EA=1;

    ET0=1;


    }


    void main()


    {
    P0M0=0x00;
    P0M1=0x00;
    P1M0=0x00;
    P1M1=0x00;
    init();
    IN1=0;
    IN2=1;
    TR0=1;
    flage=1;
           pwm=1;


    while(1) ;


    }


    void timer0()interrupt 1 //定时器0为0.1ms一个周期


    {


    TH0=(65536-100)/256;

    TL0=(65536-100)%256;

    if( flage==1)
     
    {
      beep=1;
    if(a>195) //产生周期为20ms,高电平为0.5ms,舵机会转到0度  

    pwm=1;//如果想反转方向,就需把第一个p10=0,第二个p10=-1

    else

    pwm=0;

     a--;

    if(a<1)a=200; 
    }
    else
    {
    beep=0;
    if(a>180) //产生周期为20ms,高电平为2.0ms,舵机会转到135度  

    pwm=1;

    else

    pwm=0;

    aa--;

    if(a<1)a=200; 
    }






    }
    展开全文
  • Stm32驱动舵机

    2019-03-14 08:01:08
    Stm32驱动舵机 一、舵机分类:数字舵机和模拟舵机 一般价格贵的舵机基本都是数字舵机,反之就是模拟舵机了。他们之间的区别就是,数字的舵机你输出脉冲后,会很清脆的到达固定的角度,不会产生异响,脉冲固定...
  • 51单片机通过定时器模拟PWM控制多个舵机 程序
  • 领导要求我驱动3-4个舵机。研究了几日,总算折腾出一个方案..、 1.舵机驱动的基本原理  (可以参考http://blog.sina.com.cn/s/blog_8240cbef01018hu1.html)  "控制信号由接收机的通道进入信号调制芯片,获得...
  • keil 4.0 stc15单片机P10口控制舵机
  • 基于51单片机舵机控制C语言程序代码,控制舵机的转角大小。
  • 求一个51单片机控制舵机(非常简单易懂的程序,通过按键控制舵机左右转)
  • 基于PIC单片机舵机控制系统设计
  • 51单片机控制小舵机

    2019-05-21 22:17:42
    以前从没有想过写博客,但是最近发现以前的代码老是找不到,而且找到了也不一定想得起当时的逻辑,很麻烦,所以打算写写提醒一下自己。 最近老板让做一个代码 ...
  • 为什么要写这篇博客、因为我在调我的51单片机wifi小车的双舵机摄像头的时候。从一开始对PWM很陌生到完全理解PWM调节并调好了两个舵机加起来花费了整整一天的时间。也看了很多的资料。这里综合一下,希望能帮助到像我...
  • 下面是我用keil写的程序,怎么烧录到STC89C52单片机中实现不了预期功能呢? 本来是按下jia键,舵机就转180度,按下jian键就转0度。可是我的舵机却反应得不那么 灵敏。我用的是SG90舵机,接在开发板5v,该舵机正常...
  • 舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。 舵机是一种位置伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。其工作原理是:控制...
1 2 3 4 5 ... 20
收藏数 567
精华内容 226