找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3104|回复: 4
打印 上一主题 下一主题
收起左侧

基于51单片机PWM调速数码管显示测速L298芯片控制直流电机正反运转的项目工程

[复制链接]
跳转到指定楼层
楼主
本帖最后由 51黑电子会员 于 2020-4-25 16:25 编辑
  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.    duan=1;//开数码管段码端口                  
  215.    P0=table[shi];//数码管十位显示
  216.    duan=0;//关数码管段码端口
  217.    P0=0x00;//关数码管段码显示
  218.    wei=1;//开数码管位码端口
  219.    P2=weima[2];//第3位数码管显示
  220.    wei=0;//关数码管位码端口
  221.    delay(1);//延时

  222.    duan=1;//开数码管段码端口                        
  223.    P0=table[ge];//数码管个位显示
  224.    duan=0;//关数码管段码端口
  225.    P0=0x00;//关数码管段码显示
  226.    wei=1;//开数码管位码端口
  227.    P2=weima[3];//第4位数码管显示
  228.    wei=0;//关数码管位码端口
  229.    delay(1);//延时     
  230. }
  231.   void shumaguannodisplay(uint qian,uint bai,uint shi,uint ge)//数码管显示函数
  232. {
  233.    duan=1;//开数码管段码端口  
  234.    P0=table[qian];//数码千位显示
  235.    duan=1;//关数码管段码端口
  236.    P0=0x00;//关数码管段码显示
  237.    wei=1;//开数码管位码端口
  238.    P2=weima[0];//第1位数码管显示
  239.    wei=1;//关数码管位码端口
  240.    delay(1);//延时
  241.    
  242.    duan=1;//开数码管段码端口                     
  243.    P0=table[bai];//数码百位显示
  244.    duan=1;//关数码管段码端口
  245.    P0=0x00;//关数码管段码显示
  246.    wei=1;//开数码管位码端口
  247.    P2=weima[1];//第2位数码管显示
  248.    wei=1;//关数码管位码端口
  249.    delay(1);//延时

  250.    duan=1;//开数码管段码端口                  
  251.    P0=table[shi];//数码管十位显示
  252.    duan=1;//关数码管段码端口
  253.    P0=0x00;//关数码管段码显示
  254.    wei=1;//开数码管位码端口
  255.    P2=weima[2];//第3位数码管显示
  256.    wei=1;//关数码管位码端口
  257.    delay(1);//延时

  258.    duan=1;//开数码管段码端口                        
  259.    P0=table[ge];//数码管个位显示
  260.    duan=1;//关数码管段码端口
  261.    P0=0x00;//关数码管段码显示
  262.    wei=1;//开数码管位码端口
  263.    P2=weima[3];//第4位数码管显示
  264.    wei=1;//关数码管位码端口
  265.    delay(1);//延时     
  266. }
复制代码



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:723721 发表于 2020-5-5 07:32 来自手机 | 只看该作者
楼主楼主有没有程序和仿真文件呀
回复

使用道具 举报

板凳
ID:171036 发表于 2020-5-6 19:57 | 只看该作者
NT果冻布丁粉 发表于 2020-5-5 07:32
楼主楼主有没有程序和仿真文件呀

看程序就可以做出来啊
回复

使用道具 举报

地板
ID:817071 发表于 2020-9-7 15:54 来自手机 | 只看该作者
楼主 为什么程序编译的时候有很多错误提示
回复

使用道具 举报

5#
ID:156220 发表于 2020-9-9 10:10 | 只看该作者
楼主的注释太详细了,谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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