zoukankan      html  css  js  c++  java
  • 基于51单片机PWM调速数码管显示测速L298芯片控制直流电机正反运转的项目工程

      1 #include"reg52.h"//单片机头文件
      2 #define uchar unsigned char//宏定义,用uchar表示unsigned char,叫无符号字符型数据类型,取值范围为:0到255。
      3 #define uint unsigned int//宏定义,用uint表示unsigned int,叫无符号整数型数据类型,取值范围为:0到65535。
      4 sbit qitingjian=P1^0;//位定义启停键
      5 sbit zhengzhuan=P1^1;//位定义正转键
      6 sbit fanzhuan=P1^2;//位定义反转键
      7 sbit jiasujian=P1^3;//位定义加速键
      8 sbit jiansujian=P1^4;//位定义减速键
      9 sbit IN1=P1^5;//位定义数码管段码端口
     10 sbit IN2=P1^6;//位定义数码管位码端口
     11 sbit ENA=P1^7;//位定义L298M芯片使能端ENA
     12 sbit duan=P3^0;//位定义L298M芯片控制端IN1
     13 sbit wei=P3^1;//位定义L298M芯片控制端IN2
     14 sbit qitingled=P3^4;//位定义启停指示灯
     15 sbit zhengzhuanled=P3^5;//位定义正转指示灯
     16 sbit fanzhuanled=P3^6;//位定义反转指示灯
     17 sbit zhuansuled=P3^7;//位定义转速指示灯
     18 sbit waibuzhongduanling=P3^2; //外部中断0端口
     19 uint qian,bai,shi,ge,zhuansu;//数码管千位变量、百位变量、十位变量、个位变量以及转速变量
     20 uint maichongcount,Time0num,Time1num,pwm,qitingnum,zhengzhuanflag,fanzhuanflag;//脉冲计数变量、定时器0定时计数变量、定时器1定时计数变量、脉冲宽度调制变量、启停键按下数次变量、正转标志位变量、反转标志位变量
     21 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x27,0x7f,0x6f,0x40,0x7c,0x39,0x5e,0x79,0x71,0x00};//共阴数码管段码,高电平点亮段码,低电平熄灭段码。
     22 uchar code weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};//共阴数码管位码,低电平点亮位码,高电平熄灭位码。
     23 void delay(uint jishi);//毫秒延时函数
     24 void TimerInit();//定时器初始化函数
     25 void Time0();//定时器0定时函数
     26 void Time1();//定时器1定时函数
     27 void KeyScan();//按键扫描函数
     28 void waibuzhongduanlingjishu();//外部中断0计数函数
     29 void shumaguandisplay(uint qian,uint bai,uint shi,uint ge);//数码管显示函数
     30 void shumaguannodisplay(uint qian,uint bai,uint shi,uint ge);//数码管无显示函数
     31   void main()//主函数
     32 {
     33    TimerInit();//定时器初始化函数
     34    IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。
     35    IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。
     36    while(1)//死循环
     37  {
     38     KeyScan();//按键扫描函数
     39     if(qitingnum==1)//判断启停键是否第一次按下
     40     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数
     41   }
     42  }
     43   void delay(uint jishi)//延时函数
     44 {
     45    uint i,j;
     46    for(i=jishi;i>0;i--)
     47     for(j=110;j>0;j--);
     48   }
     49   void TimerInit()//定时器初始化函数
     50 {
     51    TMOD=0x11;//设定定时器为定时器0和定时器1,工作模式都为1。
     52    TH0=(65536-1000)/256;//TH0装初值为65536-100=65436,即定时100微妙,相当于0.1毫秒。
     53    TL0=(65536-1000)%256;//TL0装初值为65536-100=65436
     54    TH1=(65536-50000)/256;//TH1装初值为65536-50000=15536,即定时50000微妙,相当于50毫秒。
     55    TL1=(65536-50000)%256;//TL1装初值为65536-50000=15536
     56    EA=1;//全局中断允许
     57    ET0=1;//打开定时器0中断允许
     58    TR0=1;//开定时器0       
     59    EX0=1;//开外部中断0允许
     60    IT0=1;//设置外部中断0下降触发中断
     61    ET1=1;//打开定时器1中断允许
     62    TR1=1;//开定时器1
     63  }
     64   void Time0() interrupt 1//定时器0定时函数,每0.1毫秒产生pwm波一次。
     65 {       
     66    TH0=(65536-1000)/256;//TH0重装初值为65536-100=65436,即定时100微妙,相当于0.1毫秒。
     67    TL0=(65536-1000)%256;//TH0重装初值为65536-100=65436
     68    Time0num++;//定时器0定时计数变量先赋值再自加
     69    if(Time0num==20)//判断定时器0定时计数变量是否大于等于20,PWM波完整周期为20ms,定时器0定时计数变量Time0num数值越大,电机运转越快。
     70   {
     71     Time0num=0;//定时器0定时计数变量等于0
     72    }
     73    if(Time0num<pwm)//判断定时器0定时计数变量还否小于脉冲宽度调制变量       
     74   {                               
     75     ENA=1;//L298M芯片使能端ENA置高电平,电机运转。
     76     zhuansuled=0;//开转速指示灯
     77    }
     78    else
     79   {
     80     ENA=0;//L298M芯片使能端ENA置低电平,电机不运转。
     81     zhuansuled=1;//关转速指示灯
     82    }
     83 }
     84   void Time1() interrupt 3//定时器1定时函数,定时50ms,采集电机转速。       
     85 {       
     86    TH1=(65536-50000)/256;//TH1装初值为65536-50000=15536,即定时50000微妙,相当于50毫秒。
     87    TL1=(65536-50000)%256;//TH1装初值为65536-50000=15536
     88    Time1num++;//定时器1定时计数变量先赋值再自加
     89    if(Time1num==20)//判断定时器1定时计数变量是否等于20,即每1秒测速一次。
     90   {       
     91     Time1num=0;//定时器1定时计数变量等于0
     92     EX0=0;//关外部中断0
     93     zhuansu=55*maichongcount/24;//电机转速=每分钟X脉冲计数变量/每转一圈需要的脉冲个数,即55*maichongcount/24,其中的55表示55秒,为什么不是一分钟60秒?由于Protues仿真电路图中的MOTOR-ENCODER仿真件存在误差,为了让MOTOR-ENCODER仿真件显示的转速达到数码管显示转速的效果,进行了一定秒数的修改,不过实际运用要以一分钟60秒为准,maichongcount为单片机从外部中断0端口处获取MOTOR-ENCODER仿真件旋转生产的脉冲计数变量,24为MOTOR-ENCODER仿真件每旋转一圈产生的脉冲个数。
     94     qian=zhuansu/1000;//数码管千位显示
     95     bai=zhuansu%1000/100;//数码管百位显示
     96     shi=zhuansu%100/10;//数码管十位显示
     97     ge=zhuansu%10;//数码管个位显示
     98     maichongcount=0;//脉冲计数变量归零
     99     EX0=1;//开外部中断0
    100    }
    101 }
    102   void waibuzhongduanlingjishu() interrupt 0  using 1//外部中断0计数函数,外部脉冲计数。
    103 {
    104    maichongcount++ ;//脉冲计数变量先赋值再自加
    105   }
    106   void KeyScan()//按键扫描函数
    107 {
    108    if(qitingjian==0)//判断启停键是否按下
    109   {
    110     shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    111     if(qitingjian==0)//再次判断启停键是否按下
    112    {
    113      while(!qitingjian)//启停键释放
    114      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数
    115      qitingnum++;//启停键按下数次变量先赋值再加加
    116      qitingled=0;//开启停指示灯
    117      if(qitingnum==2)//判断启停键按下数次变量是否为2
    118     {
    119       qitingnum=0;//启停键按下数次变量归零
    120       qitingled=1;//关启停指示灯
    121       zhengzhuanled=1;//关正转指示灯
    122       fanzhuanled=1;//关反转指示灯
    123       zhuansuled=1;//关转速指示灯
    124       zhengzhuanflag=0;//正转标志位变量为0
    125       fanzhuanflag=0;//反转标志位变量为0
    126       IN1=0;//L298M芯片控制端IN1置低电平,电机不运转。
    127       IN2=0;//L298M芯片控制端IN2置低电平,电机不运转。
    128       shumaguannodisplay(qian,bai,shi,ge);//数码管无显示函数
    129      }
    130     }
    131    }
    132    if(qitingnum==1)//判断启停键是否第一次按下
    133   {     
    134     if(zhengzhuan==0)//判断是否按下正转键
    135    {
    136      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    137      if(zhengzhuan==0)//再次判断是否按下正转
    138     {
    139       while(!zhengzhuan)//正转键释放
    140       shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    141       zhengzhuanled=0;//开正转指示灯
    142       fanzhuanled=1;//关反转指示灯
    143       zhengzhuanflag=1;//正转标志位变量为1
    144       fanzhuanflag=0;//反转标志位变量为0
    145       IN1=1;//L298N芯片控制端IN1置高电平
    146       IN2=0;//L298N芯片控制端IN2置低电平
    147      }
    148     }
    149     if(fanzhuan==0)//判断是否按下反转键
    150    {
    151      shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    152      if(fanzhuan==0)//再次判断是否按下反转键
    153     {
    154       while(!fanzhuan)//反转键释放
    155       shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    156       zhengzhuanled=1;//关正转指示灯
    157       fanzhuanled=0;//开反转指示灯
    158       zhengzhuanflag=0;//正转标志位变量为0
    159       fanzhuanflag=1;//反转标志位变量为1
    160       IN1=0;//L298N芯片控制端IN1置低电平
    161       IN2=1;//L298N芯片控制端IN2置高电平
    162      }
    163     }
    164    }
    165     if(zhengzhuanflag==1||fanzhuanflag==1)//判断电机是否为正转或反转
    166    {
    167      if(jiasujian==0)//判断是否按下加速键
    168     {
    169       shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    170       if(jiasujian==0)//再次判断是否按下加速键
    171      {
    172        while(!jiasujian)//加速键释放
    173        shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    174        if(pwm < 20)//判断脉冲宽度调制变量是否小于20
    175        pwm++;//脉冲宽度调制变量先赋值再加加 
    176        if(pwm >= 20)//判断脉冲宽度调制变量是否大于等于20
    177        pwm = 19;//脉冲宽度调制变量等于20                                  
    178       }
    179      }
    180      if(jiansujian==0) //判断是否按下减速键
    181     {
    182       shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    183       if(jiansujian==0)//再次判断是否按下减键
    184      {
    185        while(!jiansujian)//减速键释放
    186        shumaguandisplay(qian,bai,shi,ge);//数码管显示函数做延时
    187        if(pwm > 0)//判断脉冲宽度调制变量是否大于0
    188        pwm--;//脉冲宽度调制变量先赋值再减减 
    189        if(pwm <= 0)//判断脉冲宽度调制变量是否小于等于0
    190        pwm = 0;//脉冲宽度调制变量等于0 
    191       }
    192      }
    193     }
    194    }
    195   void shumaguandisplay(uint qian,uint bai,uint shi,uint ge)//数码管显示函数
    196 {
    197    duan=1;//开数码管段码端口                      
    198    P0=table[qian];//数码千位显示
    199    duan=0;//关数码管段码端口
    200    P0=0x00;//关数码管段码显示
    201    wei=1;//开数码管位码端口
    202    P2=weima[0];//第1位数码管显示
    203    wei=0;//关数码管位码端口
    204    delay(1);//延时
    205    
    206    duan=1;//开数码管段码端口                      
    207    P0=table[bai];//数码百位显示
    208    duan=0;//关数码管段码端口
    209    P0=0x00;//关数码管段码显示
    210    wei=1;//开数码管位码端口
    211    P2=weima[1];//第2位数码管显示
    212    wei=0;//关数码管位码端口
    213    delay(1);//延时
    214 
    215    duan=1;//开数码管段码端口                  
    216    P0=table[shi];//数码管十位显示
    217    duan=0;//关数码管段码端口
    218    P0=0x00;//关数码管段码显示
    219    wei=1;//开数码管位码端口
    220    P2=weima[2];//第3位数码管显示
    221    wei=0;//关数码管位码端口
    222    delay(1);//延时
    223 
    224    duan=1;//开数码管段码端口                        
    225    P0=table[ge];//数码管个位显示
    226    duan=0;//关数码管段码端口
    227    P0=0x00;//关数码管段码显示
    228    wei=1;//开数码管位码端口
    229    P2=weima[3];//第4位数码管显示
    230    wei=0;//关数码管位码端口
    231    delay(1);//延时     
    232  }
    233   void shumaguannodisplay(uint qian,uint bai,uint shi,uint ge)//数码管显示函数
    234 {
    235    duan=1;//开数码管段码端口  
    236    P0=table[qian];//数码千位显示
    237    duan=1;//关数码管段码端口
    238    P0=0x00;//关数码管段码显示
    239    wei=1;//开数码管位码端口
    240    P2=weima[0];//第1位数码管显示
    241    wei=1;//关数码管位码端口
    242    delay(1);//延时
    243    
    244    duan=1;//开数码管段码端口                      
    245    P0=table[bai];//数码百位显示
    246    duan=1;//关数码管段码端口
    247    P0=0x00;//关数码管段码显示
    248    wei=1;//开数码管位码端口
    249    P2=weima[1];//第2位数码管显示
    250    wei=1;//关数码管位码端口
    251    delay(1);//延时
    252 
    253    duan=1;//开数码管段码端口                  
    254    P0=table[shi];//数码管十位显示
    255    duan=1;//关数码管段码端口
    256    P0=0x00;//关数码管段码显示
    257    wei=1;//开数码管位码端口
    258    P2=weima[2];//第3位数码管显示
    259    wei=1;//关数码管位码端口
    260    delay(1);//延时
    261 
    262    duan=1;//开数码管段码端口                        
    263    P0=table[ge];//数码管个位显示
    264    duan=1;//关数码管段码端口
    265    P0=0x00;//关数码管段码显示
    266    wei=1;//开数码管位码端口
    267    P2=weima[3];//第4位数码管显示
    268    wei=1;//关数码管位码端口
    269    delay(1);//延时     
    270  }

  • 相关阅读:
    C#调用Delphi的dll 详解
    C# 用API截取桌面屏幕
    C# 控件代码设置置顶和置底属性
    C#用API 获取电脑桌面背景图地址
    利用JS使IE浏览器默认打开是全屏显示
    aspx页面生成xml数据
    MacOS下安装Anaconda+Pycharm+TensorFlow+Keras
    GitHub编辑README
    Win10(64位)下安装Anaconda+Tensorflow(GPU)
    Win7(64位)下安装Anaconda+Tensorflow(CPU)
  • 原文地址:https://www.cnblogs.com/AChenWeiqiangA/p/12773577.html
Copyright © 2011-2022 走看看