用单片机IO口直接驱动段式LCD的方法.docx
- 文档编号:23553829
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:16
- 大小:343.93KB
用单片机IO口直接驱动段式LCD的方法.docx
《用单片机IO口直接驱动段式LCD的方法.docx》由会员分享,可在线阅读,更多相关《用单片机IO口直接驱动段式LCD的方法.docx(16页珍藏版)》请在冰豆网上搜索。
用单片机IO口直接驱动段式LCD的方法
用单片机IO口直接驱动段式LCD的方法
用IO口驱动段式LED(数码管)的方法相信大家比较清楚,但用IO口直接驱动段式LCD的方法相对复杂一些。
在网上搜了一下单片机IO口驱动段式LCD的方法,大部分资料讲得不够清晰、具体,而且简单问题复杂化。
后来查了LCD的显示原理,结合网上的相关介绍,发现IO口直接驱动段式LCD原理比较简单,用几句话就可以描述清楚:
和LED的显示原理不一样:
LED是加正向电压发光,而LCD必须交替加正、反向电压才会持续显示(可以做个实验,如果把恒定电压加到LCD的一段上,该段会显示一下,但马上不能显示,而且长时间加恒定电压,会加速LCD的老化和损坏)
2.常听说1/2bias,1/3biasLCD,是什么意思呢对于1/2biasLCD,假如LCD的显示电压是3V,则1/2bias是,也就是说在±3V电压作用时,LCD有显示;±及以下的电压作用时没有显示
3.普通单片机IO口不能直接输出半高电平(),但可以用相等的上下拉电阻实现,当IO口设置为输入(高阻)时,由于上下拉电阻的分压作用,则产生一个半高电平()
知道了以上3点后,动态驱动LCD就不是难事了,对于4*8段的LCD(4个COM,8个SEG,显示电压为3V,1/2bias),驱动方法如下:
1、四个COM采用交替扫描的方式,每个COM在相邻两次扫描时又进行电压交变的方式。
2、若扫描到某一个COM时,该COM输出3V(0V):
与该COM相连的SEG输出与COM相反,ΔV=±3V,则该相连点亮;
与该COM相连的SEG输出与COM相同,ΔV=0,则该相连点不亮。
3、其他没有扫描到的COM,单片机IO口为输入,从而产生1/2bias(),不管SEG为何值,ΔV<±,故该点不亮。
本人用4*8段的LCD自制了一个数字钟表,验证了以上方法的可行性,现把制作过程罗列如下
1.原理图
说明:
由于管脚不够用,所以时钟芯片DS1302的RST和LCD的一个SEG是复用的,只要在这个SEG无效的时候去读取时间就可以了,另外,3PIN串口是ISP下载程序用的。
2.备料
3.焊接
4.实验结果
5.不足之处
通过实验结果可以发现,不显示的SEG也有阴影
原因分析:
纽扣电池电压,1/2bias是,大于,所以会出现阴影。
解决办法:
选择工作电压小于3V的单片机和电压等于3V的电池(如2节干电池)
6.程序源代码
点击下载
代码
/
段式LCD驱动实验
外部晶体:
12MHz
作者:
日期:
*****/
#include<>
#include<>
//管脚定义
sbitCOM0=P3^5;
sbitCOM1=P3^4;
sbitCOM2=P3^3;
sbitCOM3=P3^2;
sbitBI_4=P3^7;
sbitRTC_CLK=P3^0;
sbitRTC_IO=P3^1;
sbitRTC_RST=P3^7;//复用
//P3口模式寄存器
sfrP3M1=0xb1;
sfrP3M0=0xb2;
//当前时间(BCD码):
秒、分、时、日、月、星期、年
unsignedcharClockBuffer[8]={0x34,0x12,0x08,0x20,0x03,0x05,0x09};
//0~9的段码查询表
//位序D7D6D5D4D3D2D1D0
//段ABCDEFGDOT
codeunsignedcharseg_code[10]={~0x03,~0x9f,~0x25,~0x0d,~0x99,~0x49,~0x41,~0x1f,~0x01,~0x09};
unsignedcharScanCoun=0;//动态扫描显示位数计数器
unsignedcharDisplayBuf[4]={1,2,3,4};//4位数字对应的显示暂存
//段码缓冲区
unsignedcharSegBuf[4]={0x00,0x00,0x00,0x00};//COM1、COM2、COM3、COM4的段码
bitbi_4a=0;//COM0对应的4a
bitbi_4b=0;//COM1对应的4a
bitbi_4c=0;//COM2对应的4a
//延时
voiddly(unsignedcharx)
{unsignedchari;
for(i=0;i } //ds1302写1字节 voidrtc_wt_byte(unsignedcharsent_buf) {unsignedchari; for(i=0;i<8;i++) {RTC_CLK=0; if(sent_buf&0x01)RTC_IO=1; elseRTC_IO=0; RTC_CLK=1; dly(5); sent_buf=sent_buf>>1; } RTC_CLK=0; dly(5); } //ds1302读1字节 unsignedcharrtc_rd_byte(void) {unsignedchari,read_buf; RTC_IO=1;//RTC_IO置1,保证为输入状态 for(i=0;i<8;i++) {read_buf=read_buf>>1; RTC_CLK=0; dly(5); if(RTC_IO)read_buf=read_buf|0x80; elseread_buf=read_buf&0x7f; RTC_CLK=1; dly(5); } RTC_CLK=0; dly(5); returnread_buf; } //ds1302写入时间 voidrtc_wr_time(unsignedchar*p_wt_time) {unsignedchari; unsignedchartmp1; 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; } //ds1302读出时间 voidrtc_rd_time(unsignedchar*p_rd_time) {unsignedchari; unsignedchartmp1; 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; } //ds1302初始化 voidini_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);//写TRICKLECHARGER寄存器 rtc_wt_byte(0xa9);//值: 使能充电,串联2个二极管,串联2k欧姆的电阻 RTC_CLK=0; RTC_RST=0; } //把4位数字的SEG放到COM1、COM2、COM3、COM4对应的段码 //LCD的管脚定义与LED不同,它不是一个COM对应一位数字,而是对应每个数字的一部分SEG //123456789101112131415 //<1f1a2f2a3f3a4f4a>------COM0 //<1g1b2g2b2g3b4g4b>------COM1 //<1e1c2e2c: 3e3c4e4c>------COM2 //1d1h2d2h3d3h4d------COM3 voidSeg2Seg() {unsignedcharSegXX; 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(unsignedcharBcdValue,unsignedchar*pDecValue) {//if(BcdValue>=0x9a||(BcdValue&0x0f)>=0x0a)return0; *pDecValue++=(BcdValue&0xf0)>>4; *pDecValue=BcdValue&0x0f; //return1; } //初始化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; } voidmain() { InitInterResource(); ini_rtc();//初始化DS1302 rtc_wr_time(ClockBuffer);//写入时间初始值 EA=1;//开全局中断 while (1) { } } //定时器0中断服务程序,5ms定时器,4位数码管动态显示驱动 voidtmr0_p(void)interrupt1 { TL0=0x78;//重新定时5ms TH0=0xec; Seg2Seg(); P3M1=0x3c; P3M0=0x00; switch(ScanCoun)//动态扫描显示 { case0: //COM0正向驱动 P1=SegBuf[0]; BI_4=bi_4a; COM0=0; P3M1=0x1c;//除COM0输出外,其余COM设为输入 P3M0=0x00; break; case1: //COM0反向驱动 P1=~SegBuf[0]; BI_4=~bi_4a; COM0=1; P3M1=0x1c; P3M0=0x00; break; case2: //COM1正向驱动 P1=SegBuf[1]; BI_4=bi_4b; COM1=0; P3M1=0x2c; P3M0=0x00; break; case3: //COM1反向驱动 P1=~SegBuf[1]; BI_4=~bi_4b; COM1=1; P3M1=0x2c; P3M0=0x00; break; case4: //COM2正向驱动 P1=SegBuf[2]; BI_4=bi_4c; COM2=0; P3M1=0x34; P3M0=0x00; break; case5: //COM2反向驱动 P1=~SegBuf[2]; BI_4=~bi_4c; COM2=1; P3M1=0x34; P3M0=0x00; break; case6: //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; case7: //COM3反向驱动 P1=~SegBuf[3]; COM3=1; P3M1=0x38; P3M0=0x00; break; } ScanCoun++;//下一位 if(ScanCoun>7)ScanCoun=0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 IO 直接 驱动 段式 LCD 方法