仿真LCD显示 - #include <reg52.h>
- #include <stdio.h>
- // 管脚定义
- sbit COM0=P3^5;
- sbit COM1=P3^4;
- sbit COM2=P3^3;
- sbit COM3=P3^2;
- sbit BI_4=P3^7;
- sbit RTC_CLK=P3^0;
- sbit RTC_IO=P3^1;
- sbit RTC_RST=P3^7; // 复用
- //P3 口模式寄存器
- sfr P3M1=0xb1;
- sfr P3M0=0xb2;
- seg_code[10] = { ~0x03,~0x9f,~0x25,~0x0d,~0x99,~0x49,~0x41,~0x1f,~0x01,~0x09 };
- unsigned char ScanCoun=0; // 动态扫描显示位数计数器
- unsigned char DisplayBuf[4] = { 1,2,3,4 }; //4 位数字对应的显示暂存
- // 段码缓冲区
- unsigned char SegBuf[4] = { 0x00,0x00,0x00,0x00 };//COM1 、COM2、COM3、COM4的段码
- bit bi_4a=0; //COM0 对应的4a
- bit bi_4b=0; //COM1 对应的4a
- bit bi_4c=0; //COM2 对应的4a
- // 延时
- void dly(unsigned char x)
- {
- unsigned char i;
- for (i=0; i<x; i++);
- }
- void rtc_wr_time(unsigned char *p_wt_time)
- {
- unsigned char i;
- unsigned char tmp1;
- dly(30);
- RTC_RST=1;
- rtc_wt_byte(0xbe); //burst 写入时间
- for (i=0; i<8; i++)
- {
- tmp1=*p_wt_time++;
- rtc_wt_byte(tmp1);
-
- }
- RTC_CLK=0;
- RTC_RST=0;
- }
- void rtc_rd_time(unsigned char *p_rd_time)
- {
- unsigned char i;
- unsigned char tmp1;
- dly(30);
- RTC_RST=1;
- rtc_wt_byte(0xbf); //burst 读取时间
- RTC_IO=1;
- for (i=0; i<8; i++)
- {
- tmp1=rtc_rd_byte();
- *p_rd_time++=tmp1;
- }
- RTC_CLK=0;
- RTC_RST=0;
- }
- void ini_rtc()
- {
- RTC_CLK=0;
- RTC_RST=0;
- dly(30);
-
- RTC_RST=1;
- rtc_wt_byte(0x8e); // 写CONTROL 寄存器
- rtc_wt_byte(0x00); // 值: 去掉写保护
- RTC_RST=0; // 复位
- RTC_RST=1; // 正常工作
- rtc_wt_byte(0x90); // 写TRICKLE CHARGE寄R存器
- rtc_wt_byte(0xa9); // 值: 使能充电,串联2 个二极管,串联2k 欧姆的电阻
- RTC_CLK=0;
- RTC_RST=0;
- }
- // 把4 位数字的SEG放到COM1、COM2、COM3、COM4对应的段码
- //LCD 的管脚定义与LED不同,它不是一个COM对应一位数字,而是对应每个数字的一部分SEG
- // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- // < 1f 1a 2f 2a 3f 3a 4f 4a > -- ----
- COM0
- // < 1g 1b 2g 2b 2g 3b 4g 4b > -- ----
- COM1
- // < 1e 1c 2e 2c : 3e 3c 4e 4c > -- ----
- COM2
- // 1d 1h 2d 2h 3d 3h 4d -- ----
- COM3
- /**************** 显示代码**************/
- void Seg2Seg()
- {
- unsigned char SegXX;
- SegBuf[0]=0;
- SegBuf[1]=0;
- SegBuf[2]=0x08;
- SegBuf[3]=0;
- bi_4a=0;
- bi_4b=0;
- bi_4c=0;
-
- SegXX=seg_code[DisplayBuf[0]]; // 第1 位数字
-
- if (SegXX&0x80) SegBuf[0]|=0x40;
- if (SegXX&0x40) SegBuf[1]|=0x40;
- if (SegXX&0x20) SegBuf[2]|=0x40;
- if (SegXX&0x10) SegBuf[3]|=0x80;
- if (SegXX&0x08) SegBuf[2]|=0x80;
- if (SegXX&0x04) SegBuf[0]|=0x80;
- if (SegXX&0x02) SegBuf[1]|=0x80;
- if (SegXX&0x01) SegBuf[3]|=0x40;
-
- SegXX=seg_code[DisplayBuf[1]]; // 第2 位数字
-
- if (SegXX&0x80) SegBuf[0]|=0x10;
- if (SegXX&0x40) SegBuf[1]|=0x10;
- if (SegXX&0x20) SegBuf[2]|=0x10;
- if (SegXX&0x10) SegBuf[3]|=0x20;
- if (SegXX&0x08) SegBuf[2]|=0x20;
- if (SegXX&0x04) SegBuf[0]|=0x20;
- if (SegXX&0x02) SegBuf[1]|=0x20;
- if (SegXX&0x01) SegBuf[3]|=0x10;
-
- SegXX=seg_code[DisplayBuf[2]]; // 第3 位数字
-
- if (SegXX&0x80) SegBuf[0]|=0x02;
- if (SegXX&0x40) SegBuf[1]|=0x02;
- if (SegXX&0x20) SegBuf[2]|=0x02;
- if (SegXX&0x10) SegBuf[3]|=0x04;
- if (SegXX&0x08) SegBuf[2]|=0x04;
- if (SegXX&0x04) SegBuf[0]|=0x04;
- if (SegXX&0x02) SegBuf[1]|=0x04;
- if (SegXX&0x01) SegBuf[3]|=0x02;
-
- SegXX=seg_code[DisplayBuf[3]]; // 第4 位数字
-
- if (SegXX&0x80) bi_4a=1;
- if (SegXX&0x40) bi_4b=1;
- if (SegXX&0x20) bi_4c=1;
- if (SegXX&0x10) SegBuf[3]|=0x01;
- if (SegXX&0x08) SegBuf[2]|=0x01;
- if (SegXX&0x04) SegBuf[0]|=0x01;
- if (SegXX&0x02) SegBuf[1]|=0x01;
- }
- /* 一个BCD码转化成两个十进制数(如: 0x79 转化成0x07 和0x09)*/
- BcdToDec(unsigned char BcdValue,unsigned char *pDecValue)
- {
- //if (BcdValue>=0x9a||(BcdValue&0x0f)>=0x0a) return 0;
- *pDecValue++=(BcdValue&0xf0)>>4;
- *pDecValue=BcdValue&0x0f;
- //return 1;
- }
- /**************** 初始化MCS51内部资源 ********************/
- InitInterResource()
- {
- IE=0; // 关全部中断
- TCON=0; // 清全部中断请求
- IP=0; // 清中断优先级
- TMOD=0x01; //T0 工作方式1(16 位定时器)
- TH0=0x00; //T0 定时器辅初值
- TL0=0x00;
- TR0=1; // 允许T0 定时
- ET0=1; // 允许T0 中断
- EA=0; // 关全局中断
- RTC_RST=0;
- }
- void main()
- {
- InitInterResource();
- ini_rtc(); // 初始化DS1302
- rtc_wr_time(ClockBuffer); // 写入时间初始值
- EA=1; // 开全局中断
- while(1)
- {
-
- }
- }
- /*************** 开定时中断 *************/
- //定时器0 中断服务程序, 5ms定时器, 4 位数码管动态显示驱动
- void tmr0_p(void) interrupt 1
- {
- TL0=0x78; // 重新定时5ms
- TH0=0xec;
- Seg2Seg();
- P3M1=0x3c;
- P3M0=0x00;
- switch(ScanCoun) // 动态扫描显示
- {
- case 0: //COM0 正向驱动
- P1= SegBuf[0];
- BI_4= bi_4a;
- COM0=0;
- P3M1=0x1c; // 除COM0输出外,其余COM设为输入
- P3M0=0x00;
- break;
- case 1: //COM0 反向驱动
- P1= ~SegBuf[0];
- BI_4= ~bi_4a;
- COM0=1;
- P3M1=0x1c;
-
-
- P3M0=0x00;
- break;
- case 2: //COM1 正向驱动
- P1= SegBuf[1];
- BI_4= bi_4b;
- COM1=0;
- P3M1=0x2c;
- P3M0=0x00;
- break;
- case 3: //COM1 反向驱动
- P1= ~SegBuf[1];
- BI_4= ~bi_4b;
- COM1=1;
- P3M1=0x2c;
- P3M0=0x00;
- break;
- case 4: //COM2 正向驱动
- P1= SegBuf[2];
- BI_4= bi_4c;
- COM2=0;
- P3M1=0x34;
- P3M0=0x00;
- break;
- case 5: //COM2 反向驱动
- P1= ~SegBuf[2];
- BI_4= ~bi_4c;
- COM2=1;
- P3M1=0x34;
- P3M0=0x00;
- break;
- case 6: //COM3 正向驱动
- P1= SegBuf[3];
- COM3=0;
- P3M1=0x38;
- P3M0=0x00;
- RTC_RST=0;
-
-
- rtc_rd_time(ClockBuffer); // 读时间
- BcdToDec(ClockBuffer[0],DisplayBuf+2); // 秒送入显示缓冲
- BcdToDec(ClockBuffer[1],DisplayBuf); // 分送入显示缓冲
- BI_4= ~bi_4c;
- break;
- case 7: //COM3 反向驱动
- P1= ~SegBuf[3];
- COM3=1;
- P3M1=0x38;
- P3M0=0x00;
- break;
- }
- ScanCoun++; // 下一位
- if (ScanCoun>7) ScanCoun=0;
- }
复制代码
祥见附件
仿LCD显示.rar
(22.39 KB, 下载次数: 66)
|