找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3155|回复: 5
收起左侧

超牛仿真LCD显示

[复制链接]
ID:475247 发表于 2020-3-23 16:37 | 显示全部楼层 |阅读模式
00001.jpg

仿真LCD显示
  1. #include <reg52.h>
  2. #include <stdio.h>
  3. // 管脚定义
  4. sbit COM0=P3^5;
  5. sbit COM1=P3^4;
  6. sbit COM2=P3^3;
  7. sbit COM3=P3^2;
  8. sbit BI_4=P3^7;
  9. sbit RTC_CLK=P3^0;
  10. sbit RTC_IO=P3^1;
  11. sbit RTC_RST=P3^7; // 复用
  12. //P3 口模式寄存器
  13. sfr P3M1=0xb1;
  14. sfr P3M0=0xb2;
  15. seg_code[10] = { ~0x03,~0x9f,~0x25,~0x0d,~0x99,~0x49,~0x41,~0x1f,~0x01,~0x09 };
  16. unsigned char ScanCoun=0; // 动态扫描显示位数计数器
  17. unsigned char DisplayBuf[4] = { 1,2,3,4 }; //4 位数字对应的显示暂存
  18. // 段码缓冲区
  19. unsigned char SegBuf[4] = { 0x00,0x00,0x00,0x00 };//COM1 、COM2、COM3、COM4的段码
  20. bit bi_4a=0; //COM0 对应的4a
  21. bit bi_4b=0; //COM1 对应的4a
  22. bit bi_4c=0; //COM2 对应的4a


  23. // 延时
  24. void dly(unsigned char x)
  25. {
  26.         unsigned char i;
  27.         for (i=0; i<x; i++);
  28. }

  29. void rtc_wr_time(unsigned char *p_wt_time)
  30. {
  31.         unsigned char i;
  32.         unsigned char tmp1;
  33.         dly(30);
  34.         RTC_RST=1;
  35.         rtc_wt_byte(0xbe); //burst 写入时间
  36.         for (i=0; i<8; i++)
  37.         {
  38.                 tmp1=*p_wt_time++;
  39.                 rtc_wt_byte(tmp1);
  40.                
  41.         }
  42.         RTC_CLK=0;
  43.         RTC_RST=0;
  44. }


  45. void rtc_rd_time(unsigned char *p_rd_time)
  46. {
  47.         unsigned char i;
  48.         unsigned char tmp1;
  49.         dly(30);
  50.         RTC_RST=1;
  51.         rtc_wt_byte(0xbf); //burst 读取时间
  52.         RTC_IO=1;
  53.         for (i=0; i<8; i++)
  54.         {
  55.                 tmp1=rtc_rd_byte();
  56.                 *p_rd_time++=tmp1;
  57.         }
  58.         RTC_CLK=0;
  59.         RTC_RST=0;
  60. }

  61. void ini_rtc()
  62. {
  63.         RTC_CLK=0;
  64.         RTC_RST=0;
  65.         dly(30);
  66.         
  67.         RTC_RST=1;
  68.         rtc_wt_byte(0x8e); // 写CONTROL 寄存器
  69.         rtc_wt_byte(0x00); // 值: 去掉写保护
  70.         RTC_RST=0; // 复位
  71.         RTC_RST=1; // 正常工作
  72.         rtc_wt_byte(0x90); // 写TRICKLE CHARGE寄R存器
  73.         rtc_wt_byte(0xa9); // 值: 使能充电,串联2 个二极管,串联2k 欧姆的电阻
  74.         RTC_CLK=0;
  75.         RTC_RST=0;
  76. }



  77. // 把4 位数字的SEG放到COM1、COM2、COM3、COM4对应的段码

  78.   //LCD 的管脚定义与LED不同,它不是一个COM对应一位数字,而是对应每个数字的一部分SEG
  79.   // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  80.   // < 1f 1a 2f 2a 3f 3a 4f 4a > -- ----
  81.   COM0
  82.   // < 1g 1b 2g 2b 2g 3b 4g 4b > -- ----
  83.   COM1
  84.   // < 1e 1c 2e 2c : 3e 3c 4e 4c > -- ----
  85.   COM2
  86.   // 1d 1h 2d 2h 3d 3h 4d -- ----
  87.   COM3

  88. /**************** 显示代码**************/
  89. void Seg2Seg()
  90. {
  91.         unsigned char SegXX;
  92.         SegBuf[0]=0;
  93.         SegBuf[1]=0;
  94.         SegBuf[2]=0x08;
  95.         SegBuf[3]=0;
  96.         bi_4a=0;
  97.         bi_4b=0;
  98.         bi_4c=0;
  99.         
  100.         SegXX=seg_code[DisplayBuf[0]]; // 第1 位数字
  101.         
  102.         if (SegXX&0x80) SegBuf[0]|=0x40;
  103.         if (SegXX&0x40) SegBuf[1]|=0x40;
  104.         if (SegXX&0x20) SegBuf[2]|=0x40;
  105.         if (SegXX&0x10) SegBuf[3]|=0x80;
  106.         if (SegXX&0x08) SegBuf[2]|=0x80;
  107.         if (SegXX&0x04) SegBuf[0]|=0x80;
  108.         if (SegXX&0x02) SegBuf[1]|=0x80;
  109.         if (SegXX&0x01) SegBuf[3]|=0x40;
  110.         
  111.         SegXX=seg_code[DisplayBuf[1]]; // 第2 位数字
  112.         
  113.         if (SegXX&0x80) SegBuf[0]|=0x10;
  114.         if (SegXX&0x40) SegBuf[1]|=0x10;
  115.         if (SegXX&0x20) SegBuf[2]|=0x10;
  116.         if (SegXX&0x10) SegBuf[3]|=0x20;
  117.         if (SegXX&0x08) SegBuf[2]|=0x20;
  118.         if (SegXX&0x04) SegBuf[0]|=0x20;
  119.         if (SegXX&0x02) SegBuf[1]|=0x20;
  120.         if (SegXX&0x01) SegBuf[3]|=0x10;
  121.         
  122.         SegXX=seg_code[DisplayBuf[2]]; // 第3 位数字
  123.         
  124.         if (SegXX&0x80) SegBuf[0]|=0x02;
  125.         if (SegXX&0x40) SegBuf[1]|=0x02;
  126.         if (SegXX&0x20) SegBuf[2]|=0x02;
  127.         if (SegXX&0x10) SegBuf[3]|=0x04;
  128.         if (SegXX&0x08) SegBuf[2]|=0x04;
  129.         if (SegXX&0x04) SegBuf[0]|=0x04;
  130.         if (SegXX&0x02) SegBuf[1]|=0x04;
  131.         if (SegXX&0x01) SegBuf[3]|=0x02;
  132.         
  133.         SegXX=seg_code[DisplayBuf[3]]; // 第4 位数字
  134.         
  135.         if (SegXX&0x80) bi_4a=1;
  136.         if (SegXX&0x40) bi_4b=1;
  137.         if (SegXX&0x20) bi_4c=1;
  138.         if (SegXX&0x10) SegBuf[3]|=0x01;
  139.         if (SegXX&0x08) SegBuf[2]|=0x01;
  140.         if (SegXX&0x04) SegBuf[0]|=0x01;
  141.         if (SegXX&0x02) SegBuf[1]|=0x01;
  142. }


  143. /* 一个BCD码转化成两个十进制数(如: 0x79 转化成0x07 和0x09)*/
  144. BcdToDec(unsigned char BcdValue,unsigned char *pDecValue)
  145. {
  146.         //if (BcdValue>=0x9a||(BcdValue&0x0f)>=0x0a) return 0;
  147.         *pDecValue++=(BcdValue&0xf0)>>4;
  148.         *pDecValue=BcdValue&0x0f;
  149.         //return 1;
  150. }


  151. /****************  初始化MCS51内部资源  ********************/
  152. InitInterResource()
  153. {
  154.         IE=0; // 关全部中断
  155.         TCON=0; // 清全部中断请求
  156.         IP=0; // 清中断优先级
  157.         TMOD=0x01; //T0 工作方式1(16 位定时器)
  158.         TH0=0x00; //T0 定时器辅初值
  159.         TL0=0x00;
  160.         TR0=1; // 允许T0 定时
  161.         ET0=1; // 允许T0 中断
  162.         EA=0; // 关全局中断
  163.         RTC_RST=0;
  164. }

  165. void main()
  166. {
  167.         InitInterResource();
  168.         ini_rtc(); // 初始化DS1302
  169.         rtc_wr_time(ClockBuffer); // 写入时间初始值
  170.         EA=1; // 开全局中断
  171.         while(1)
  172.         {
  173.                
  174.         }  
  175. }


  176. /***************  开定时中断 *************/
  177. //定时器0 中断服务程序, 5ms定时器, 4 位数码管动态显示驱动
  178. void tmr0_p(void) interrupt 1
  179. {
  180.         TL0=0x78; // 重新定时5ms
  181.         TH0=0xec;
  182.         Seg2Seg();
  183.         P3M1=0x3c;
  184.         P3M0=0x00;
  185.         switch(ScanCoun) // 动态扫描显示
  186.         {
  187.         case 0: //COM0 正向驱动
  188.                 P1= SegBuf[0];
  189.                 BI_4= bi_4a;
  190.                 COM0=0;
  191.                 P3M1=0x1c; // 除COM0输出外,其余COM设为输入
  192.                 P3M0=0x00;
  193.                 break;
  194.         case 1: //COM0 反向驱动
  195.                 P1= ~SegBuf[0];
  196.                 BI_4= ~bi_4a;
  197.                 COM0=1;
  198.                 P3M1=0x1c;
  199.                
  200.                
  201.                 P3M0=0x00;
  202.                 break;
  203.         case 2: //COM1 正向驱动
  204.                 P1= SegBuf[1];
  205.                 BI_4= bi_4b;
  206.                 COM1=0;
  207.                 P3M1=0x2c;
  208.                 P3M0=0x00;
  209.                 break;
  210.         case 3: //COM1 反向驱动
  211.                 P1= ~SegBuf[1];
  212.                 BI_4= ~bi_4b;
  213.                 COM1=1;
  214.                 P3M1=0x2c;
  215.                 P3M0=0x00;
  216.                 break;
  217.         case 4: //COM2 正向驱动
  218.                 P1= SegBuf[2];
  219.                 BI_4= bi_4c;
  220.                 COM2=0;
  221.                 P3M1=0x34;
  222.                 P3M0=0x00;
  223.                 break;
  224.         case 5: //COM2 反向驱动
  225.                 P1= ~SegBuf[2];
  226.                 BI_4= ~bi_4c;
  227.                 COM2=1;
  228.                 P3M1=0x34;
  229.                 P3M0=0x00;
  230.                 break;
  231.         case 6: //COM3 正向驱动
  232.                 P1= SegBuf[3];
  233.                 COM3=0;
  234.                 P3M1=0x38;
  235.                 P3M0=0x00;
  236.                 RTC_RST=0;
  237.                
  238.                
  239.                 rtc_rd_time(ClockBuffer); // 读时间
  240.                 BcdToDec(ClockBuffer[0],DisplayBuf+2); // 秒送入显示缓冲
  241.                 BcdToDec(ClockBuffer[1],DisplayBuf); // 分送入显示缓冲
  242.                 BI_4= ~bi_4c;
  243.                 break;
  244.         case 7: //COM3 反向驱动
  245.                 P1= ~SegBuf[3];
  246.                 COM3=1;
  247.                 P3M1=0x38;
  248.                 P3M0=0x00;
  249.                 break;
  250.         }
  251.         ScanCoun++; // 下一位
  252.         if (ScanCoun>7) ScanCoun=0;
  253. }
复制代码

祥见附件
仿LCD显示.rar (22.39 KB, 下载次数: 66)
回复

使用道具 举报

ID:469417 发表于 2020-3-26 07:13 | 显示全部楼层
超级棒!好东西!顶一个!
回复

使用道具 举报

ID:471066 发表于 2020-3-31 09:40 | 显示全部楼层
真的很不错,正要用呢!
回复

使用道具 举报

ID:473186 发表于 2020-3-31 09:52 | 显示全部楼层
很好啊,正在找这方面的东东!
回复

使用道具 举报

ID:767459 发表于 2020-9-4 17:00 | 显示全部楼层
楼主好好。
附件的《仿LCD显示.DSN》,由于我没有安有相应软件,不能打开。有哪位好心人帮打开转成PDF呀
回复

使用道具 举报

ID:333678 发表于 2020-9-20 19:31 | 显示全部楼层
很好的资料,多谢楼主的分享。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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