找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1081|回复: 1
收起左侧

仿真出来了,然后连上lcd1602只有第二行黑格,其他数字都没有呀,咋回事哦。求解...

[复制链接]
ID:870180 发表于 2021-1-5 20:15 | 显示全部楼层 |阅读模式
  1. /**************************************************************************************
  2. *                              LCD1602电子时钟                                                                                                  *
  3. 实现现象:下载程序后,LCD屏上第一行会显示出日期,第二行显示时间和当前温度。按下K1,进入时间调节
  4.                  模式,按下K2让光标往左移,按下K3让光标处的数字增1,按下K4让光标处的数字减1
  5. 注意事项:                                                                                                                                                                  
  6. ***************************************************************************************/
  7. //--头文件声明,数据类型声明--//
  8. #include <reg52.h>
  9. #include <intrins.h>
  10. typedef unsigned char uint8;
  11. typedef unsigned int uint16;

  12. #define key P3
  13. #define no_key 0xff                                        //无按键按下
  14. #define key_state0 0                                //状态定义
  15. #define key_state1 1
  16. #define key_state2 2
  17. //---------端口声明---------//
  18. sbit lcden = P2^7;
  19. sbit lcdrs = P2^6;
  20. sbit lcdrw = P3^6;

  21. sbit key1  = P3^2;
  22. sbit key2  = P3^3;
  23. sbit key3  = P3^4;
  24. sbit key4  = P3^5;

  25. sbit dq    = P3^7;                                        //DS18B20数据线
  26. //---------函数声明---------//
  27. void lcd_init();                                        //LCD屏幕初始化
  28. void wcom();                                                //LCD写命令
  29. void wdat();                                                //LCD写数据
  30. void display();                                                //显示函数
  31. void timeshow();                                        //时间显示
  32. void dateshow();                                        //日期显示
  33. void weekshow();                                        //星期显示
  34. void keyscan();                                                //按键扫描
  35. void key_disposal();                                //键值处理
  36. void day_jud();                                                //日期处理
  37. void ds18b20_init();                                //18B20模块初始化
  38. uint8 byte_read();                                        //读去18B20一个字节
  39. void byte_write();                                        //写入18B20一个字节
  40. void temp_read();                                        //温度读取函数
  41. void temp_display(uint8 position,uint16 tvalue1);                //温度显示函数
  42. //---------变量定义---------//
  43. uint8 time_1s,time_500ms;
  44. uint8 second,minute = 59,hour = 23;
  45. uint8 day = 1,month = 1,week = 1;                        //设定初始
  46. uint16 year = 2019,tvalue;
  47. //uint8 temp;
  48. uint8 cursor;                                                                //要调节的位置
  49. uint8 key_value;
  50. bit f_twinkle,f_mode,f_pressing,f_set;

  51. uint8 code table1[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};                        //字符℃


  52. //---------长延时---------//
  53. void delayms(uint16 k){
  54.         uint16 i,j;
  55.         for(i=k;i>0;i--)
  56.                 for(j=110;j>0;j--);
  57. }

  58. //---------短延时---------//
  59. void delayus(uint8 time_1us){
  60.         while(time_1us--);
  61. }

  62. //---------定时器初始化---------//
  63. void timer_init(){
  64.         EA = 0;
  65.         TR0 = 0;
  66.         TMOD = 0x01;
  67.         TH0 = 0x4C;                //50ms
  68.         TL0 = 0x00;

  69.         ET0 = 1;                //允许Timer0中断
  70.         ET1 = 1;
  71.         EA  = 1;
  72.         TR0 = 1;
  73. }

  74. //---------Timer0中断服务函数---------//
  75. void isr_timer0 () interrupt 1 using 0 {
  76.         TH0 = 0x4C;                //50ms
  77.         TL0 = 0x00;
  78.         keyscan();
  79.         if(++time_500ms >= 10){
  80.                 time_500ms = 0;
  81.                 f_twinkle = ~f_twinkle;
  82.         }
  83.         if(!f_set){
  84.                 if(++time_1s >= 20){
  85.                         time_1s = 0;
  86.                         second++;
  87.                 }
  88.         }
  89. }

  90. void ds18b20_init(){                                                //ds18b20初始化
  91.         dq = 1;        
  92.         _nop_();
  93.         dq = 0;
  94.         delayus(75);
  95.         dq = 1;
  96.         delayus(20);
  97.         dq = 1;
  98.         _nop_();
  99. }

  100. void wcom(uint8 com){                                                //LCD1602写命令
  101.         lcdrw = 0;
  102.         lcdrs = 0;
  103.         P0 = com;
  104.         lcden = 1;
  105.         delayms(3);
  106.         lcden = 0;
  107. }

  108. void wdat(uint8 dat){                                                //LCD1602写数据
  109.         lcdrw = 0;
  110.         lcdrs = 1;
  111.         P0 = dat;
  112.         lcden = 1;
  113.         delayms(3);
  114.         lcden = 0;        
  115. }

  116. void lcd_init(){                                                        //LCD初始化
  117.         wcom(0x38);
  118.         wcom(0x01);
  119.         wcom(0x06);
  120.         wcom(0x0c);
  121.         
  122.         wcom(0x86);
  123.         wdat(0x2d);                                                                //"-"
  124.         wcom(0x89);
  125.         wdat(0x2d);                                                                //"-"
  126.         wcom(0x80+0x40+0x04);
  127.         wdat(0x3a);                                                                //":"
  128.         wcom(0x80+0x40+0x07);
  129.         wdat(0x3a);                                                                //":"
  130. }

  131. void timeshow(uint8 position,uint8 time){                //时间显示,position为显示位置
  132.         uint8 i,j;
  133.         i = time/10;                                //shiwei
  134.         j = time%10;                                //gewei
  135.         wcom(0x80+0x40+position);
  136.         wdat(0x30+i);                                //shiwei
  137.         wdat(0x30+j);                                //gewei
  138. }

  139. void dateshow(uint8 position,uint8 date1){                //日期显示(月、日)
  140.         uint8 i,j;
  141.         i = date1/10;                                //shiwei
  142.         j = date1%10;                                //gewei
  143.         wcom(0x80+position);
  144.         wdat(0x30+i);                                //shiwei
  145.         wdat(0x30+j);                                //gewei
  146. }

  147. void yearshow(uint8 position,uint16 year1){                //年份显示
  148.         uint8 i,j,m,n;
  149.         i = year1/1000;                                //qianwei
  150.         j = year1/100%10;                        //baiwei
  151.         m = year1/10%10;
  152.         n = year1%10;
  153.         wcom(0x80+position);
  154.         wdat(0x30+i);                                //qianwei
  155.         wdat(0x30+j);                                //baiwei
  156.         wdat(0x30+m);                                //shiwei
  157.         wdat(0x30+n);                                //gewei
  158. }

  159. void weekshow(uint8 position,uint8 week1){                //星期显示
  160.         wcom(0x80+position);
  161.         switch(week1){
  162.                 case 1:wdat(0x4d);wdat(0x4f);wdat(0x4e);break;
  163.                 case 2:wdat(0x54);wdat(0x55);wdat(0x45);break;
  164.                 case 3:wdat(0x57);wdat(0x45);wdat(0x44);break;
  165.                 case 4:wdat(0x54);wdat(0x48);wdat(0x55);break;
  166.                 case 5:wdat(0x46);wdat(0x52);wdat(0x49);break;
  167.                 case 6:wdat(0x53);wdat(0x41);wdat(0x54);break;
  168.                 case 7:wdat(0x53);wdat(0x55);wdat(0x4e);break;
  169.                 default:break;
  170.         }
  171. }

  172. void day_jud(){                                                                        //日期处理(秒、分、时、日、月进位)
  173.         if(second > 59){
  174.                 second = 0;
  175.                 if(++minute > 59){
  176.                         minute = 0;
  177.                         if(++hour > 23){
  178.                                 hour = 0;
  179.                                 if(++week >= 8)        week = 1;
  180.                                 day++;
  181.                         }
  182.                 }
  183.         }
  184.         
  185.         if(minute > 59){
  186.                 minute = 0;
  187.                 if(++hour > 23){
  188.                         hour = 0;
  189.                         if(++week > 7)        week = 1;
  190.                         day++;
  191.                 }
  192.         }
  193.         
  194.         if(hour > 23){
  195.                 hour = 0;
  196.                 if(++week > 7)        week = 1;
  197.                 day++;
  198.         }
  199.         
  200.         if(day > 31 && (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)){
  201.                 day = 1;
  202.                 month++;
  203.                 if(month >= 12){
  204.                         month = 1;
  205.                         year++;
  206.                 }
  207.         }
  208.         else if(day > 30 && (month == 4 || month == 6 || month == 9 || month == 11)){
  209.                 day = 1;
  210.                 month++;
  211.         }
  212.         else if(day > 29 && month == 2 && ((year%4 == 0 && year%100 != 0) || year%400 == 0)){
  213.                 day = 1;
  214.                 month++;
  215.         }
  216.         else if(day > 28 && month == 2){
  217.                 day = 1;
  218.                 month++;
  219.         }
  220. }

  221. void display(){                                                                                //显示函数
  222.         if(!f_mode){                                                                        //时间显示模式
  223.                 yearshow(2,year);
  224.                 dateshow(7,month);
  225.                 dateshow(0x0a,day);
  226.                 weekshow(0x0d,week);
  227.                
  228.                 timeshow(2,hour);
  229.                 timeshow(5,minute);
  230.                 timeshow(0x08,second);
  231.                 temp_read();                                                                //读取温度
  232.                 temp_display(0x0b,tvalue);                                        //温度显示
  233.         }
  234.         else{                                                                                        //时间调节模式
  235.                 wcom(0x80+0x40+0x0d);
  236.                 wdat(0x53);                                                                        //"S"
  237.                 wdat(0x45);                                                                        //"E"
  238.                 wdat(0x54);                                                                        //"T"

  239.                 if(f_twinkle && !f_pressing){                                //闪烁标志位,0.5秒取反一次,为1则相应位置显示空白
  240.                         if(cursor == 0) {                                                //按压标志位,按键按下时为1,不闪烁
  241.                                 wcom(0x82);                                                        //要显示空白的位置
  242.                                 wdat(0x20);                                                        //4位空白(实现闪烁效果)
  243.                                 wdat(0x20);
  244.                                 wdat(0x20);
  245.                                 wdat(0x20);
  246.                         }
  247.                         if(cursor == 1) {
  248.                                 wcom(0x87);                                                        //要显示空白的位置
  249.                                 wdat(0x20);                                                        //2位空白
  250.                                 wdat(0x20);
  251.                         }
  252.                         if(cursor == 2) {
  253.                                 wcom(0x8a);
  254.                                 wdat(0x20);
  255.                                 wdat(0x20);
  256.                         }
  257.                         if(cursor == 3) {
  258.                                 wcom(0x8d);
  259.                                 wdat(0x20);
  260.                                 wdat(0x20);
  261.                                 wdat(0x20);
  262.                         }
  263.                         if(cursor == 4) {
  264.                                 wcom(0x80+0x42);
  265.                                 wdat(0x20);
  266.                                 wdat(0x20);
  267.                         }
  268.                         if(cursor == 5) {
  269.                                 wcom(0x80+0x45);
  270.                                 wdat(0x20);
  271.                                 wdat(0x20);
  272.                         }
  273.                         if(cursor == 6) {
  274.                                 wcom(0x80+0x48);
  275.                                 wdat(0x20);
  276.                                 wdat(0x20);
  277.                         }
  278.                 }
  279.                 else {                                                                                //正常显示
  280.                         yearshow(2,year);
  281.                         dateshow(7,month);
  282.                         dateshow(0x0a,day);
  283.                         weekshow(0x0d,week);
  284.                         timeshow(2,hour);
  285.                         timeshow(5,minute);
  286.                         timeshow(0x08,second);
  287.                 }
  288.         }
  289. }

  290. void keyscan(){                                                                                //按键扫描
  291.         static uint8 key_state;
  292.         
  293.         switch(key_state){
  294.                 case key_state0:                                                        //未按下
  295.                         if(!key1 || !key2 || !key3 || !key4){
  296.                                 key_state = key_state1;
  297.                         }
  298.                 break;
  299.                 case key_state1:                                                        //有键按下
  300.                         f_pressing = 1;
  301.                         if(!key1){
  302.                                 f_set = ~f_set;                                                //秒走时停止
  303.                                 f_mode = ~f_mode;                                        //模式切换
  304.                                 key_value = 1;
  305.                                 key_state = key_state2;
  306.                         }
  307.                         else if(!key2){
  308.                                 key_value = 2;
  309.                                 key_state = key_state2;
  310.                         }
  311.                         else if(!key3){
  312.                                 key_value = 3;
  313.                                 key_state = key_state2;
  314.                         }
  315.                         else if(!key4){
  316.                                 key_value = 4;
  317.                                 key_state = key_state2;
  318.                         }
  319.                         else{
  320.                                 key_state = key_state0;
  321.                                 f_pressing = 0;                                                //如果不清零,假如按键是无效按下,调节模式时就会停止闪烁
  322.                         }
  323.                 break;
  324.                 case key_state2:                                                        //松开按键
  325.                         if(key1 && key2 && key3 && key4){
  326.                                 f_pressing = 0;
  327.                                 key_state = key_state0;
  328.                         }
  329.                 break;
  330.         }
  331. }

  332. void key_disposal(){                                                                //键值处理
  333.         if(!f_pressing){                                                                //松开按键才处理
  334.                 if(key_value == 1){
  335.                         key_value = 0;
  336.                         cursor = 0;                                                                //光标位置清零
  337.                         lcd_init();                                                                //清屏
  338.                 }
  339.                 else if(key_value == 2){
  340.                         key_value = 0;
  341.                         cursor++;                                                                //光标+(光标即闪烁的位置,实际上LCD上并无光标)
  342.                         if(cursor > 6){
  343.                                 cursor = 0;
  344.                         }
  345.                 }
  346.                 else if((key_value == 3) && f_mode){                //光标所处位置值+
  347.                         key_value = 0;
  348.                         if(cursor == 0){
  349.                                 year++;
  350.                         }
  351.                         else if (cursor == 1){
  352.                                 if(++month > 12) month = 1;
  353.                         }
  354.                         else if(cursor == 2){
  355.                                 if(++day > 31) day = 1;
  356.                         }
  357.                         else if(cursor == 3){
  358.                                 if(++week > 7) week = 1;
  359.                         }
  360.                         else if(cursor == 4){
  361.                                 if(++hour > 23) hour = 0;
  362.                         }
  363.                         else if(cursor == 5){
  364.                                 if(++minute > 59) minute = 0;
  365.                         }
  366.                         else if(cursor == 6){
  367.                                 if(++second > 59) second = 0;
  368.                         }
  369.                 }
  370.                 else if((key_value == 4) && f_mode){                //光标所处位置值-
  371.                         key_value = 0;
  372.                         if(cursor == 0 && year > 0){
  373.                                 year--;
  374.                         }
  375.                         else if (cursor == 1 && month > 1){
  376.                                 month--;
  377.                         }
  378.                         else if(cursor == 2 && day > 1){
  379.                                 day--;
  380.                         }
  381.                         else if(cursor == 3 && week > 1){
  382.                                 week--;
  383.                         }
  384.                         else if(cursor == 4 && hour > 0){
  385.                                 hour--;
  386.                         }
  387.                         else if(cursor == 5 && minute > 0){
  388.                                 minute--;
  389.                         }
  390.                         else if(cursor == 6 && second > 0){
  391.                                 second--;
  392.                         }
  393.                 }
  394.         }
  395. }

  396. uint8 byte_read(){                                                                        //ds18b20 读字节
  397.         uint8 i,j,dat;
  398.         for(i = 0; i < 8 ; i++){
  399.                 dq = 0;
  400.                 _nop_();
  401.                 dq = 1;
  402.                 _nop_();
  403.                 j = dq;
  404.                 delayus(10);
  405.                 dq = 1;
  406.                 _nop_();
  407.                 dat = (j << 7 | dat >> 1);
  408.         }
  409.         return(dat);
  410. }

  411. void byte_write(uint8 data1){                                                //ds18b20 写字节
  412.         uint8 i;
  413.         for(i = 0; i < 8 ; i++){
  414.                 dq = 0;
  415.                 _nop_();
  416.                 dq = data1&0x01;
  417.                 delayus(10);
  418.                 dq = 1;
  419.                 _nop_();
  420.                 data1 >>= 1;
  421.         }
  422. }

  423. void temp_read(){                                                                        //读温度
  424.         float data1;
  425.         uint8 i,j;
  426.         ds18b20_init();
  427.         byte_write(0xcc);                                                                //向DS18B20发跳过读ROM命令
  428.         byte_write(0x44);                                                                //启动DS18B20进行温度转换命令,转换结果存入内部RAM
  429.         delayus(80);
  430.         ds18b20_init();
  431.         byte_write(0xcc);                                                                //向DS18B20发跳过读ROM命令
  432.         byte_write(0xbe);                                                                //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  433.         delayus(80);
  434.         i = byte_read();                                                                //内部RAM 低位
  435.         j = byte_read();                                                                //内部RAM 高位
  436.         data1 = (j*256 + i) * 6.25;                                                //取出温度值
  437.         tvalue = (uint16)data1;                                                        //强制转换
  438. }

  439. void temp_display(uint8 position,uint16 tvalue1){        //温度显示
  440.         uint8 i,j,m;
  441.         i = tvalue1/1000;
  442.         j = tvalue1%1000/100;
  443.         m = tvalue1%100/10;                                                                //取出十位 个位 十分位
  444.         wcom(0x80 + 0x40 + position);
  445.         wdat(0x30 + i);
  446.         wdat(0x30 + j);
  447.         wdat(0x2e);                                                                                //"."
  448.         wdat(0x30 + m);
  449.         wdat(0x00);                                                                                //自编字符
  450. }

  451. void main(){
  452.         uint8 i;
  453.         wcom(0x40);
  454.         for(i = 0; i < 8 ; i++){
  455.                 wdat(table1[i]);                                                        //写入自编字符
  456.         }
  457.         
  458.         timer_init();
  459.         lcd_init();
  460.         while(1){
  461.                 // if(++temp > 2){
  462.                         // temp = 0;
  463.                 // }
  464.                 // switch(temp){
  465.                         // case 0:day_jud();break;
  466.                         // case 1:key_disposal();break;
  467.                         // case 2:display();break;
  468.                 // }
  469.                 day_jud();
  470.                 key_disposal();
  471.                 display();
  472.         }
  473. }
复制代码

回复

使用道具 举报

ID:328014 发表于 2021-1-5 22:41 | 显示全部楼层
解决此问题在51hei至少有20个以上的帖子,既有软件问题也有硬件问题,这个随便找2个吧,搜索"1602 格":
http://www.51hei.com/bbs/dpj-187378-1.html
http://www.51hei.com/bbs/dpj-160754-1.html
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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