用单片机IO口直接驱动段式LCD的方法Word格式文档下载.docx
《用单片机IO口直接驱动段式LCD的方法Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《用单片机IO口直接驱动段式LCD的方法Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。
原因分析:
纽扣电池电压,1/2bias是,大于,所以会出现阴影。
解决办法:
选择工作电压小于3V的单片机和电压等于3V的电池(如2节干电池)
6.程序源代码
点击下载
代码
/******************************************************************
段式LCD驱动实验
外部晶体:
12MHz
作者:
日期:
*****************************************************************/
#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<
x;
i++);
}
//ds1302写1字节
voidrtc_wt_byte(unsignedcharsent_buf)
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;
//ds1302读1字节
unsignedcharrtc_rd_byte(void)
{unsignedchari,read_buf;
RTC_IO=1;
//RTC_IO置1,保证为输入状态
{read_buf=read_buf>
RTC_CLK=0;
dly(5);
if(RTC_IO)read_buf=read_buf|0x80;
elseread_buf=read_buf&
0x7f;
returnread_buf;
//ds1302写入时间
voidrtc_wr_time(unsignedchar*p_wt_time)
unsignedchartmp1;
dly(30);
RTC_RST=1;
rtc_wt_byte(0xbe);
//burst写入时间
{tmp1=*p_wt_time++;
rtc_wt_byte(tmp1);
RTC_RST=0;
//ds1302读出时间
voidrtc_rd_time(unsignedchar*p_rd_time)
rtc_wt_byte(0xbf);
//burst读取时间
{tmp1=rtc_rd_byte();
*p_rd_time++=tmp1;
//ds1302初始化
voidini_rtc()
rtc_wt_byte(0x8e);
//写CONTROL寄存器
rtc_wt_byte(0x00);
//值:
去掉写保护
//复位
//正常工作
rtc_wt_byte(0x90);
//写TRICKLECHARGER寄存器
rtc_wt_byte(0xa9);
使能充电,串联2个二极管,串联2k欧姆的电阻
//把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;
0x40)SegBuf[1]|=0x40;
0x20)SegBuf[2]|=0x40;
0x10)SegBuf[3]|=0x80;
0x08)SegBuf[2]|=0x80;
0x04)SegBuf[0]|=0x80;
0x02)SegBuf[1]|=0x80;
0x01)SegBuf[3]|=0x40;
SegXX=seg_code[DisplayBuf[1]];
//第2位数字
0x80)SegBuf[0]|=0x10;
0x40)SegBuf[1]|=0x10;
0x20)SegBuf[2]|=0x10;
0x10)SegBuf[3]|=0x20;
0x08)SegBuf[2]|=0x20;
0x04)SegBuf[0]|=0x20;
0x02)SegBuf[1]|=0x20;
0x01)SegBuf[3]|=0x10;
SegXX=seg_code[DisplayBuf[2]];
//第3位数字
0x80)SegBuf[0]|=0x02;
0x40)SegBuf[1]|=0x02;
0x20)SegBuf[2]|=0x02;
0x10)SegBuf[3]|=0x04;
0x08)SegBuf[2]|=0x04;
0x04)SegBuf[0]|=0x04;
0x02)SegBuf[1]|=0x04;
0x01)SegBuf[3]|=0x02;
SegXX=seg_code[DisplayBuf[3]];
//第4位数字
0x80)bi_4a=1;
0x40)bi_4b=1;
0x20)bi_4c=1;
0x10)SegBuf[3]|=0x01;
0x08)SegBuf[2]|=0x01;
0x04)SegBuf[0]|=0x01;
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;
//关全局中断
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设为输入
break;
case1:
//COM0反向驱动
P1=~SegBuf[0];
BI_4=~bi_4a;
COM0=1;
case2:
//COM1正向驱动
P1=SegBuf[1];
BI_4=bi_4b;
COM1=0;
P3M1=0x2c;
case3:
//COM1反向驱动
P1=~SegBuf[1];
BI_4=~bi_4b;
COM1=1;
case4:
//COM2正向驱动
P1=SegBuf[2];
BI_4=bi_4c;
COM2=0;
P3M1=0x34;
case5:
//COM2反向驱动
P1=~SegBuf[2];
BI_4=~bi_4c;
COM2=1;
case6:
//COM3正向驱动
P1=SegBuf[3];
COM3=0;
P3M1=0x38;
rtc_rd_time(ClockBuffer);
//读时间
BcdToDec(ClockBuffer[0],DisplayBuf+2);
//秒送入显示缓冲
BcdToDec(ClockBuffer[1],DisplayBuf);
//分送入显示缓冲
case7:
//COM3反向驱动
P1=~SegBuf[3];
COM3=1;
ScanCoun++;
//下一位
if(ScanCoun>
7)ScanCoun=0;