单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 260|回复: 0
收起左侧

51单片机直流电机测速测距系统程序设计 LCD12864显示

[复制链接]
onepercent 发表于 2019-1-11 20:08 | 显示全部楼层 |阅读模式
1.设计目的
     设计并制作一个测量模拟小车(如模拟自行车、摩托车等)的行驶速度及距离的装置,且能分别显示其行驶速度和行驶距离值。
2.方案简介
  硬件:
     主控:stc89c52rc最小系统板
     测速模块:槽式光电测速传感器,20栅格编码盘
     显示:LCD12864
     输入:4*4键盘
     电机:5v直流电机
     电机驱动:L298N
     报警模块:放大电路、蜂鸣器、发光二极管
     电源:单片机、LCD、传感器供电由最小系统版供电;
         电机驱动由3节3.7v锂电池供电(电机驱动要和单片机共地)


     因为都是用的模块,除了信号放大电路,其他都是杜邦线连接单片机与各个模块。
  软件:
     大致思路是定时器T0输出PWM波改变电机转速,模拟小车转动。外部中断INT0记脉冲(下降沿)。测速方法为M法。有能力的可以尝试改为M/T法,
  单片机的定时器TI已经特意留出来了,具体程序见附件。
1.png

单片机源程序如下:
  1. #include <reg52.h>               
  2. #include <12864.c>
  3. #define T  500         //PWM波 周期50us

  4. typedef unsigned int   u32;
  5. typedef unsigned short u16;
  6. typedef unsigned char  u8 ;

  7. uchar  key=0;   //键值
  8. u8     speed_high=5;   //最高速度设置
  9. u8     actual_speed=0;           //实际速度
  10. u8     temp=0;  //按键扫描中间值
  11. uchar  key_flag=0;//按键标志
  12. unsigned int    num_flag=0;          // 按键次数标志

  13. unsigned char flag_h=0;
  14. unsigned char us500 = 0;//500us定时次数计数器
  15. unsigned char ms100_flag=0; //100ms定时到标志
  16. unsigned char s1_flag=0;        //500ms标志
  17. unsigned char Time1L=0,Time1H=0,Time0L=0,Time0H=0;//PWM波定时器占空比高,低电平时间变量
  18. unsigned char        maichong_count=0;        //电机转数脉冲计数器

  19. char         NextState=1; //定时器高,低电平转换标志
  20. double         CurrentWaves = 0;
  21. double         distance=0;
  22. u16                distant=0;
  23. u16           PWM_a=300;//占空比初值

  24. sbit IN1=P2^6;
  25. sbit IN2=P2^7;
  26. sbit PWM=P2^5;   //PWM波输出端口
  27. sbit bee=P3^7;   



  28. uchar code Code[]="123A456B789C*0#D";         //键值码
  29. uchar code Buff[]="0123456789";           //显示字形码
  30. uchar Buff1[4]={'0','0',' ','0'};        //第一行显示缓冲区
  31. uchar Buff2[4]={'0','0',' ','0'};  //  第二行显示缓冲区
  32. uchar Buff3[4]={'0','0',' ','0'};  // 第三行显示缓冲区
  33. uchar Buff4[4]={'0','0',' ','0'};  // 第四行显示缓冲区        


  34. void  keydown(void);
  35. void  keyscan(void);
  36. void  keyjudge(void);
  37. void disp(void);
  38. void a_count(void);
  39. void rnu(void);
  40. void stop(void);




  41. /**********************************************************/
  42. //延时一毫秒子程序
  43. void mDelay(uint Delay)           
  44. {        uint i;
  45.         for(;Delay > 0;Delay--)
  46.                 for(i = 0;i < 110;i++);
  47. }

  48. /**********************************************************/
  49. //定时计数器0初始化               
  50. void Init_T0()
  51. {
  52.         TMOD=0x01; //定时器0模式设置
  53.         Time1H=(65536-PWM_a)/256;  //定时器0初值1
  54.     Time1L=(65536-PWM_a)%256;  // 定时器0初值1
  55.         Time0H=(65536+PWM_a-T)/256;        // 定时器0初值2
  56.         Time0L=(65536+PWM_a-T)%256;// 定时器0初值2
  57.         TH0=Time1H;
  58.         TL0=Time1L;
  59.         ET0=1;
  60.         TR0=1;
  61.         EX0=1; //外中断0允许
  62.         IT0=1; //外部中断边沿触发方式
  63.         NextState=1;
  64.         PWM=1;
  65. }
  66. /**********************************************************/
  67. //电机启动
  68.      void  run(void)
  69. {

  70.          IN1=1;
  71.          IN2=0;
  72.          EA=0;
  73.          Init_T0();
  74.          EA=1;
  75.          IN1=1;
  76.          IN2=0;
  77. }
  78. /**********************************************************/
  79. //电机停止
  80. void stop()
  81. {
  82.         IN1=0;
  83.         IN2=0;
  84.         PWM=0;
  85.         ET0=0;
  86.         TR0=0;
  87.         EA=0;        
  88. }
  89. /*************************************************************/
  90. //判断键是否按下
  91. void  keydown(void)
  92. {  
  93.           P1=0xF0;
  94.           if(P1!=0xF0)
  95.         {  
  96.           mDelay(20);
  97.           keyscan();
  98.     }
  99. }


  100. /**********************************************************/

  101.         // 键扫描子程序
  102. void  keyscan(void)
  103. {
  104.       P1=0xF0;                //行线为输入,列线为输出,并置列线输出全为0
  105.           temp=P1;                //读P1口      
  106.       temp=temp&0xF0;
  107.       temp=~((temp>>4)|0xF0);
  108.       if(temp==1)
  109.         key=0;
  110.       else if(temp==2)
  111.         key=1;
  112.       else if(temp==4)
  113.         key=2;
  114.       else if(temp==8)
  115.         key=3;
  116.      P1=0x0F;                 //列线为输入,行线为输出,并置行线输出全为0  
  117.          temp=P1;                 //读P1口
  118.      temp=temp&0x0F;
  119.      temp=~(temp|0xF0);        
  120.      if(temp==1)
  121.         key=key+0;
  122.      else if(temp==2)
  123.         key=key+4;
  124.      else if(temp==4)
  125.         key=key+8;
  126.      else if(temp==8)
  127.         key=key+12;
  128.                 P1=0xF0;
  129.             while(P1!=0XF0);
  130.           {  
  131.                  mDelay(5);
  132.       }
  133.      keyjudge();             //判断按键功能           
  134. }


  135. /*************************************************************/
  136. //按键功能判断
  137. void  keyjudge(void)
  138. {
  139.            uchar a=Code[key];
  140.            a=a-0x30;
  141.            if(key==3)
  142.                  {          Buff1[2]='>';                 //按键指示A 显示
  143.                           Buff2[2]=' ';                 //按键指示B 取消显示
  144.                           Buff3[2]=' ';                 //按键指示C 取消显示
  145.                           key_flag='A';
  146.                       num_flag=0;
  147.                  }
  148.            else if(key==7)
  149.                  {
  150.                    Buff3[2]=' ';                 //按键指示C 取消显示
  151.                    Buff1[2]=' ';                 //按键指示A取消显示
  152.                    Buff2[2]='>';                 //按键指示B 显示
  153.            key_flag='B';
  154.                    num_flag=0;
  155.                  }
  156.            else if(key==11)
  157.                  {
  158.                                             
  159.                           Buff1[2]=' ';                    //按键指示A 取消显示
  160.                       Buff2[2]=' ';                         //按键指示B 取消显示
  161.                             Buff3[2]='>';                         //按键指示C 显示
  162.                            run();
  163.                  }
  164.                 else if(key==15)           
  165.                  {           Buff1[2]=' ';            
  166.                               Buff2[2]=' ';               
  167.                            Buff3[2]=' ';               
  168.                           stop();
  169.                           actual_speed=0;
  170.                           CurrentWaves=0;
  171.                           disp();                 
  172.                  }
  173.                  else if(key==14)           //#############
  174.                  {
  175.                           //PWM_a-=10;
  176.                          run();
  177.                          stop();
  178.                          distant=0;
  179.                          disp();
  180.                  }
  181.                  else if(key==12)           //***********
  182.                  {
  183.                          //PWM_a+=10;
  184.                          run();
  185.                          stop();
  186.                          distance=0;
  187.                          distant=0;
  188.                          actual_speed=0;
  189.                          CurrentWaves=0;
  190.                          disp();
  191.                  }
  192.                  else
  193.                  {
  194.                          if (key_flag=='A')      //输入设定转速
  195.                          {
  196.                                  if(num_flag==1)
  197.                                          {
  198.                                                    Buff1[1]=a+0x30;
  199.                                                    PWM_a=PWM_a+a;
  200.                                                    num_flag=0;
  201.                                          }
  202.                                    else if (num_flag==0)
  203.                                          {
  204.                                                   Buff1[0]=a+0x30;
  205.                                                   PWM_a=a*10;
  206.                                                   num_flag++;
  207.                                          }
  208.                                          disp();
  209.                                 }
  210.                          else if(key_flag=='B')               
  211.                           {
  212.                                   if(num_flag==1)
  213.                                          {
  214.                                                    Buff2[1]=a+0x30;
  215.                                                    speed_high=speed_high+a;
  216.                                                    num_flag=0;
  217.                                          }
  218.                                    else if (num_flag==0)
  219.                                          {
  220.                                                   Buff2[0]=a+0x30;
  221.                                                   speed_high=a*10;
  222.                                                   num_flag++;
  223.                                          }
  224.                    disp();
  225.                           }
  226.                   
  227.                     else
  228.                                 {
  229.                                           num_flag=0;
  230.                                           key_flag=0;
  231.                                 }
  232.                 }
  233. }

  234. /*****************速度距离计算*************/
  235. void a_count(void)
  236. {
  237.         actual_speed=CurrentWaves*3.6;  //实际转速计算
  238.         
  239.         distant=distance/10;
  240. }
  241. /*******************显示***************************/
  242. void disp(void)
  243. {
  244.            write_12864com(0x80+3);  //12864LCD第一行显示 设置参数指示显示位置
  245.            write_12864data(Buff1[2]);
  246.            write_12864com(0x80+4);                //12864LCD第一行显示
  247.            write_12864data(Buff1[0]);                 
  248.            write_12864com(0x80+5);               
  249.            write_12864data(Buff1[1]);
  250.            Display_string(6,0,"per");


  251.        write_12864com(0x90+3);        //12864LCD第二行显示 设置参数指示显示位置
  252.            write_12864data(Buff2[2]);
  253.        write_12864com(0x90+4);            //12864LCD第二行显示
  254.            write_12864data(Buff2[0]);                 
  255.            write_12864com(0x90+5);               
  256.            write_12864data(Buff2[1]);
  257.            Display_string(6,1,"km/h");

  258.            write_12864com(0x88+3);    //12864LCD第三行显示 设置参数指示显示位置
  259.            write_12864data(Buff3[2]);
  260.            Buff3[0]=Buff[ actual_speed/10];         //占空比十位
  261.        write_12864com(0x88+4);            //12864LCD第三行显示        
  262.        write_12864data(Buff3[0]);        
  263.            Buff3[1]=Buff[ actual_speed%10];  //  占空比个位
  264.            write_12864com(0x88+5);               
  265.            write_12864data(Buff3[1]);
  266.                 Display_string(6,2,"km/h");
  267.         

  268.            write_12864com(0x98+3);    //12864LCD第四行显示 设置参数指示显示位置
  269.            write_12864data(Buff4[0]);
  270.            Buff4[0]=Buff[distant/100];         //占空比十位
  271.        write_12864com(0x98+4);            //12864LCD第三行显示        
  272.        write_12864data(Buff4[1]);        
  273.            Buff4[1]=Buff[(distant/10)%10];  //  占空比个位
  274.            write_12864com(0x98+5);               
  275.            write_12864data(Buff4[2]);
  276.            Buff4[2]=Buff[distant%10];
  277.            Display_string(6,3,"m");

  278. }


  279. /*****************报警*************/

  280. void warn(void)
  281. {
  282.         if(actual_speed>speed_high||actual_speed==speed_high)
  283.         {
  284.                 bee=0;
  285.         }
  286.         else
  287.         {
  288.                 bee=1;
  289.         }
  290. }

  291. /**********************************************************/
  292. //T0中断服务程序
  293. void time0(void) interrupt 1
  294. {               
  295.         EX0=0;         //关闭INT0中断
  296.     PWM=~PWM;         //取反
  297.         if( NextState )
  298.         {
  299.                 TL0=Time0L;
  300.                 TH0=Time0H;
  301.                 NextState=0;
  302.         }
  303.         else
  304.         {
  305.                 TL0=Time1L;
  306.                 TH0=Time1H;                        
  307.                 NextState=1;
  308.                 us500++;
  309.         }
  310.         if( us500 > 199 )        //定时100ms到否
  311.         {        
  312. ……………………

  313. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
51测速测距12864.zip (47.96 KB, 下载次数: 8)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机. 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

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