找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机+Proteus仿真时LCD1602显示器无法正常显示

[复制链接]
跳转到指定楼层
楼主
200黑币
电路图:




通过左边按键可以控制电机启停正反转加减速。而相应的状态也会反映在显示屏上,问题在于显示只能显示正转其他都显示不了。




源程序如下:
  1. #include <reg52.h>
  2. #include<string.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6.      
  7. sbit lcdrs=P2^0;       //寄存器选择,0:数据寄存器。1:为状态/命令寄存器
  8. sbit lcden=P2^1;         //--LCD控制引脚

  9. sbit speed=P3^2;                                        //测速端口
  10. sbit ENA=P2^2;                                        //电机使能控制端

  11. sbit key1=P1^0;         //启动按键
  12. sbit key2=P1^1;                                        //正转按键
  13. sbit key3=P1^2;                                        //反转按键
  14. sbit key4=P1^3;                                        //加速按键
  15. sbit key5=P1^4;                                        //减速按键
  16. sbit key6=P1^5;                                        //停止按键
  17. sbit Zheng=P1^6;                                                //正转输出端口
  18. sbit Fan=P1^7;                                                //反转输出端口


  19. uchar Timer0_flag=4;
  20. uchar Timer0_BiaoZhi=0;//初始化占空比为1:3(高:低)

  21. uchar gewei;
  22. uchar shiwei;
  23. uchar baiwei;

  24. /******标志位设置*****/
  25. uchar KEY1=0;//优先级标志
  26. uchar KEY2=0;//加速标志

  27. uchar INT1_FLAG=0;
  28. uchar COUNTER_high=0;
  29. uchar COUNTER_low=0;
  30. uchar SUM=0;
  31. uint TIMER1_COUNTER=0;
  32. uint INT1_tingzhi=0;                //在要测速时置0

  33. /****面板显示****/
  34. uchar code lcd_desktop11[]="stop";//停止
  35. uchar code lcd_desktop12[]="ford";//正转
  36. uchar code lcd_desktop13[]="fanz";//反转
  37. uchar code lcd_desktop21[]="speedup";//加速
  38. uchar code lcd_desktop22[]="speeddn";//减速
  39. uchar code num[]={'0','1','2','3','4','5','6','7','8','9'};//要显示的转速数字。

  40. //-----lcd液晶屏头文件-----//
  41. /**延时函数**/
  42. void delayms(uchar xms)   
  43. {
  44.         uchar i,j;
  45.         for(i=xms;i>0;i--)
  46.         for(j=110;j>0;j--);
  47. }

  48. /****LCD写命令******/
  49. void write_command(uchar com)//com写入命令
  50. {
  51.         lcdrs=0;
  52.         P0=com;
  53.         delayms(2);
  54.         lcden=1;
  55.         delayms(2);
  56.         lcden=0;
  57. }

  58. /**************LCD写数据*********/
  59. void write_data(uchar date)//数据为DATA
  60. {
  61.         lcdrs=1;
  62.         P0=date;
  63.         delayms(2);
  64.         lcden=1;
  65.         delayms(2);
  66.         lcden=0;
  67. }

  68. /********LCD初始化****************/
  69. void lcd_init()//显示模式设置
  70. {
  71.         lcden=0;
  72.         write_command(0x38);
  73.         write_command(0x0c);
  74.         write_command(0x06);
  75.         write_command(0x01);
  76. }

  77. /**电机初始化函数**/
  78. void motor_init(void)
  79. {
  80.         ENA=0;                                //        停止
  81. }

  82. void ZhongDuanKaiQi(void)
  83. {
  84.         EA=1;               
  85.         ET0=1;        //计时器0允许中断。产生脉冲。
  86.         ET1=1;        //计时器1允许中断。对低电平进行计时。
  87.         //EX1=1;        //INT0允许中断。测速。由外部来启动。
  88.         IT1=1;        //低电平触发。
  89.         PX1=0;        //低级中断。
  90.         PT0=1;
  91.         PT1=0;
  92.         TMOD=0x12;//定时器工作方式控制
  93. }
  94. /***定时器T1初始化!!!等待外部脉冲的到来***/
  95. void Timer1_init(void)
  96. {
  97.         TH1=0;
  98.         TL1=0;                //等待外部脉的到来。INT1
  99. }
  100. /*****定时T0初始化*****/
  101. void Timer0_init(void)
  102. {
  103.         TH0=0;
  104.         TL0=0;
  105.         TR0=1;
  106. }
  107. /********测速模块,显示速度*******/
  108. void speed_test(void)
  109. {
  110. //        TIMER1_COUNTER;
  111.         COUNTER_high=TH1;
  112.         COUNTER_low=TL1;
  113.         SUM=COUNTER_high*256+COUNTER_low+TIMER1_COUNTER*65536;//得到的是多少us。
  114.         SUM=SUM/1000;                                //化为毫秒。
  115.         SUM=1000/SUM;                                //圈每秒。
  116.         SUM=SUM*60;                                        //圈每分钟;三位数。
  117.         gewei=SUM%10;
  118.         shiwei=SUM/10%10;
  119.         baiwei=SUM/100;
  120.         write_command(0xc0);
  121.         write_data(baiwei);
  122.         write_command(0xc1);
  123.         write_data(shiwei);
  124.         write_command(0xc2);
  125.         write_data(gewei);
  126.         SUM=0;
  127.         TIMER1_COUNTER=0;               
  128. }


  129. /********外中断1函数**********/
  130. void INT1_QIDONG() interrupt 2
  131. {
  132.         INT1_tingzhi++;
  133.         if(INT1_tingzhi==5)
  134.         {
  135.                 INT1_tingzhi=5;EX1=0;//关闭中断。
  136.         }
  137.         if(INT1_tingzhi<=4)
  138.         {
  139.                 INT1_FLAG++;
  140.           if(INT1_FLAG==2)
  141.                         {
  142.                                 INT1_FLAG=0;TR1=0;speed_test();
  143.                         }
  144.                 else
  145.                         {
  146.                                 Timer1_init();
  147.                                 TR1=1;
  148.                         }
  149.         }
  150. }
  151. /******定时器T1计数*******/
  152. void Timer1_QIDONG() interrupt 3
  153. {
  154.         TIMER1_COUNTER++;
  155. }


  156. /**相位测量并输出!!!!!出现问题???**/
  157. void xiangwei_test(void)
  158. {
  159.         uchar i=0,j=0;
  160.         //while((P2^3==0)&&(P2^4==0));
  161.         //if((P2^3==0)&&(P2^4==0))
  162.         {
  163.                 //delayms(5);
  164.                 if(P2^3==1)
  165.                 {
  166.                         write_command(0x01);
  167.                         write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop13[i]);//反转。
  168.                         j++;//反转
  169.                 }
  170.                
  171.                 if(P2^4==1)
  172.                 {
  173.                         write_command(0x01);
  174.                         write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop12[i]);//正转。
  175.                         j++;
  176.                 }
  177.         }
  178. }

  179. /****T0中断发出信号并进行通道选择****/
  180. void Timer0() interrupt 1
  181. {        
  182.         Timer0_flag--;
  183.         if((Timer0_BiaoZhi)>=(Timer0_flag))
  184.         {
  185.                 if(KEY2==0)
  186.                 {
  187.                         Zheng=1;Fan=0;
  188.                 }
  189.                 else
  190.                 {
  191.                         Zheng=0;Fan=1;
  192.                 }
  193.         }
  194.         else
  195.         {
  196.                 Zheng=0;Fan=0;                                
  197.         }        
  198.         if(Timer0_flag==0) Timer0_flag=5;
  199. }


  200. void Guan(void)
  201. {
  202.         ET0=0;
  203.         EX1=0;
  204.         ET1=0;        
  205. }


  206. void keyscan()                         //按键扫描函数
  207. {
  208.         uint i=0;
  209.         if(key1==0)   //按键K1启动按钮。只有该位启动时,后面的几位才有效。启动T0计数开始发出脉冲。
  210.         {
  211.                 delayms(10);
  212.                 if(key1==0)
  213.                 {
  214.                         while(!key1);
  215.                         KEY1=5;
  216.                         Fan=0;
  217.                         Zheng=0;
  218.                         ENA=1;
  219.                         KEY2=0;//初始化为正转。
  220.                   Timer0_BiaoZhi=0;
  221.                         Timer0_flag=4;
  222.                         
  223.                         ZhongDuanKaiQi();//开启中断        
  224.                         Timer0_init();//                初始化并开始发出脉场外中断已经开启。
  225.                         EX1=1;                                        //外中断开启;测速,显示速度。五次后结束关闭外中断1。出现问题!!!
  226.                         
  227.                         write_command(0x80);
  228.                         for(i=0;i<strlen(lcd_desktop11);i++)//显示正转。
  229.                         write_data(lcd_desktop12[i]);
  230.                 }
  231.         }
  232.         
  233.   if((key2==0)&&(KEY1=5)) //按键K2按下,(正转)只改变转向(标志位改变输出端口)
  234.         {
  235.                 delayms(10);
  236.                 if(key2==0)
  237.                 {
  238.                         while(!key2);
  239.                         KEY2=0;                //正转标志,电机正向旋转。
  240.                         //KEY2=(~1);
  241.                         xiangwei_test();
  242.                         KEY1=5;
  243.                 }
  244.         }
  245.         
  246.         if((key3==0)&&(KEY1=5)) //按键K3按下,(反转)只改变转向
  247.         {
  248.                 delayms(10);
  249.                 if(key3==0)
  250.                 {
  251.                         while(!key3);
  252.                         KEY2=~0;                        //反转标志。
  253.                         //KEY2=(~0);
  254.                         xiangwei_test();
  255.                         KEY1=5;
  256.                 }
  257.         }
  258.    if((key4==0)&&(KEY1==5))        //按键K4按下,(加速)改变装入的数值?循环次数?执行if里面的语句,通过size++来改变幅值的频率
  259.          {
  260.                  delayms(10);
  261.                  if(key4==0)
  262.                  {
  263.                          while(!key4);
  264.                          if(Timer0_BiaoZhi<4)
  265.                          {
  266.                                  Timer0_BiaoZhi++;
  267.                          }
  268.                          else
  269.                          {
  270.                                  Timer0_BiaoZhi=4;
  271.                          }
  272.                           EX1=1;
  273.                           KEY1=5;
  274.                  }
  275.                
  276.          }
  277.          
  278.          if((key5==0)&&(KEY1==5))         //按键K5按下,(减速)对其它标志位没有影响。
  279.          {
  280.                  delayms(5);
  281.                  if(key5==0)
  282.                  {
  283.                          while(!key5);
  284.                          if(Timer0_BiaoZhi==0)
  285.                          {
  286.                                  Timer0_BiaoZhi=0;
  287.                          }
  288.                          else
复制代码
附程序和电路图,各位大佬可以下载试试仿真,因为自己看不出来有什么问题了,希望有人能解惑!

51黑论坛_直流电机驱动.zip (2.68 MB, 下载次数: 13)



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

使用道具 举报

沙发
ID:213173 发表于 2020-5-14 21:59 | 只看该作者
粗略看一下就有明显错误
错误的部分
182行 if(P2^3==1)
189行 if(P2^4==1)

纠正:
sbit P2_3=P2^3;
sbit P2_4=P2^4;

void xiangwei_test(void)
{
        uchar i=0;
        if(P2_3==1)
        {
                write_command(0x01);
                write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop13[i]);//反转。
                j++;//反转
        }
       
        if(P2_4==1)
        {
                write_command(0x01);
                write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop12[i]);//正转。
                j++;
        }
}
错误的部分:
256行 if((key2==0)&&(KEY1=5))
269行 if((key3==0)&&(KEY1=5))
纠正:
if(key2==0 && KEY1==5)
if(key3==0 && KEY1==5)
回复

使用道具 举报

板凳
ID:749922 发表于 2020-5-15 11:10 | 只看该作者
wulin 发表于 2020-5-14 21:59
粗略看一下就有明显错误
错误的部分
182行 if(P2^3==1)

但是修改了一下仿真的时候屏幕还是没变化,然后有[8051 CORE] division by zero 的问题,具体是哪里还需要修改呢?
回复

使用道具 举报

地板
ID:749922 发表于 2020-5-15 11:13 | 只看该作者
wulin 发表于 2020-5-14 21:59
粗略看一下就有明显错误
错误的部分
182行 if(P2^3==1)

会不会是因为LCD的rw端接地导致的问题?
回复

使用道具 举报

5#
ID:213173 发表于 2020-5-15 12:22 | 只看该作者
774292147 发表于 2020-5-15 11:13
会不会是因为LCD的rw端接地导致的问题?

LCD部分本身没有问题,不能正常显示全都是因为按键程序不能正常调用LCD显示程序。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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