51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能Word格式文档下载.docx
《51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能Word格式文档下载.docx(10页珍藏版)》请在冰豆网上搜索。
//液晶读/写控制
sbitLCD_EN=P2^6;
//液晶使能控制
sbitPSB=P2^1;
//并口控制
sbitRES=P2^3;
ucharcodedis1[]={"
电子设计天地"
};
//液晶显示的汉字ucharcodedis2[]={"
有志者,事竟成!
"
ucharcodedis4[]={'
0'
'
1'
2'
3'
4'
5'
6'
7'
8'
9'
unsignedchartemp;
#definedelayNOP();
{_nop_();
_nop_();
voidlcd_pos(ucharX,ucharY);
//确定显示位置
unsignedcharl_tmpdate[7]={0,7,16,19,10,1,9};
//秒分时日月周年09-10-1916:
07:
00
codeunsignedchar
write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
//秒分时日月周年最低位读写位
read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
voidWrite_Ds1302_byte(unsignedchartemp);
voidWrite_Ds1302(unsignedcharaddress,unsignedchardat);
unsignedcharRead_Ds1302(unsignedcharaddress);
voidRead_RTC(void);
//readRTC
voidSet_RTC(void);
//setRTC
voidInitTIMER0(void);
//initaltimer0
/*******************************************************************//**//*延时函数*//**//*******************************************************************/voiddelay(unsignedintm)//延时程序{unsignedinti,j;
for(i=0;
i<
m;
i++)
for(j=0;
j<
10;
j++);
}/*******************************************************************//**//*检查LCD忙状
态*/
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
*//**//*******************************************************************/bitlcd_busy(){bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
delayNOP();
result=(bit)(P0&
0x80);
LCD_EN=0;
return(result);
}/*******************************************************************//**//*写指令数据到
LCD*/
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
*//**//*******************************************************************/voidlcd_wcmd(ucharcmd){while(lcd_busy());
LCD_RW=0;
P0=cmd;
delay
(1);
}/*******************************************************************//**//*写显示数据到
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
*//**//*******************************************************************/voidlcd_wdat(uchardat){while(lcd_busy());
LCD_RS=1;
P0=dat;
}/*******************************************************************//**//*LCD初始化设定*//**//*******************************************************************/voidlcd_init(){P0=0xFF;
P2=0xFF;
(40);
PSB=1;
//并口方式。
RES=0;
RES=1;
(10);
lcd_wcmd(0x30);
(100);
(37);
lcd_wcmd(0x08);
lcd_wcmd(0x10);
lcd_wcmd(0x0C);
//显示开,关光标
lcd_wcmd(0x01);
//清除LCD的显示内容
lcd_wcmd(0x06);
}voidmain(){uchari;
InitTIMER0();
Set_RTC();
lcd_init();
//初始化LCD
while
(1){if(ReadRTC_Flag){ReadRTC_Flag=0;
Read_RTC();
lcd_pos(0,0);
//设置显示位置为第一行的第1个字符
i=0;
while(dis1[i]!
='
\0'
)
{//显示字符
lcd_wdat(dis1[i]);
i++;
}lcd_pos(1,0);
//设置显示位置为第二行的第1个字符i=0;
while(dis2[i]!
){lcd_wdat(dis2[i]);
//显示字符
}lcd_pos(2,0);
lcd_wdat(dis4[l_tmpdate[6]/16]);
//DS1302是BCD码,进行处理得到十位与个位数。
lcd_pos(2,1);
lcd_wdat(dis4[l_tmpdate[6]%16]);
lcd_pos(2,2);
lcd_wdat('
-'
);
lcd_pos(2,3);
lcd_wdat(dis4[l_tmpdate[4]/16]);
lcd_pos(2,4);
lcd_wdat(dis4[l_tmpdate[4]%16]);
lcd_pos(2,5);
lcd_pos(2,6);
lcd_wdat(dis4[l_tmpdate[3]/16]);
lcd_pos(2,7);
lcd_wdat(dis4[l_tmpdate[3]%16]);
//设置显示位置为第三行的第1个字符
lcd_pos(3,0);
//设置显示位置为第四行的第1个字符
lcd_wdat(dis4[l_tmpdate[2]/16]);
lcd_pos(3,1);
lcd_wdat(dis4[l_tmpdate[2]%16]);
lcd_pos(3,2);
:
'
lcd_pos(3,3);
lcd_wdat(dis4[l_tmpdate[1]/16]);
lcd_pos(3,4);
lcd_wdat(dis4[l_tmpdate[1]%16]);
lcd_pos(3,5);
lcd_pos(3,6);
lcd_wdat(dis4[l_tmpdate[0]/16]);
lcd_pos(3,7);
lcd_wdat(dis4[l_tmpdate[0]%16]);
}}}/*********************************************************/
/**/
/*设定显示位置*/
/*********************************************************/
voidlcd_pos(ucharX,ucharY){ucharpos;
if(X==0)
{X=0x80;
}
elseif(X==1)
{X=0x90;
elseif(X==2)
{X=0x88;
elseif(X==3)
{X=0x98;
pos=X+Y;
lcd_wcmd(pos);
//显示地址}voidInitTIMER0(void){TMOD|=0x01;
//定时器设置16位
TH0=0xef;
//初始化值
TL0=0xf0;
ET0=1;
TR0=1;
EA=1;
}voidWrite_Ds1302_Byte(unsignedchartemp){unsignedchari;
for(i=0;
8;
i++)//循环8次写入数据{SCK=0;
SDA=temp&
0x01;
//每次传输低字节
temp>
>
=1;
//右移一位
SCK=1;
}}
/****************************************************************************/
voidWrite_Ds1302(unsignedcharaddress,unsignedchardat){
RST=0;
SCK=0;
RST=1;
//启动
Write_Ds1302_Byte(address);
//发送地址
Write_Ds1302_Byte(dat);
//发送数据
//恢复}/****************************************************************************/
unsignedcharRead_Ds1302(unsignedcharaddress){unsignedchari,temp=0x00;
i++)//循环8次读取数据{if(SDA)
temp|=0x80;
}RST=0;
//以下为DS1302复位的稳定时间
SDA=0;
SDA=1;
return(temp);
//返回}/****************************************************************************/
voidRead_RTC(void)//读取日历{unsignedchari,*p;
p=read_rtc_address;
//地址传递
7;
i++)//分7次读取秒分时日月周年{l_tmpdate[i]=Read_Ds1302(*p);
p++;
/***********************************************************************/
voidSet_RTC(void)//设定日历{unsignedchari,*p,tmp;
i++){//BCD处理
tmp=l_tmpdate[i]/10;
l_tmpdate[i]=l_tmpdate[i]%10;
l_tmpdate[i]=l_tmpdate[i]+tmp*16;
}Write_Ds1302(0x8E,0X00);
p=write_rtc_address;
//传地址
i++)//7次写入秒分时日月周年{Write_Ds1302(*p,l_tmpdate[i]);
}Write_Ds1302(0x8E,0x80);
}voidtim(void)interrupt1using1//中断,用于数码管扫描{staticunsignedchari,num;
TH0=0xf5;
TL0=0xe0;
//P0=table[l_tmpdisplay[i]];
//查表法得到要显示数字的数码段//P2=table1[i];
if(i==8){i=0;
num++;
if(20==num)//隔段时间读取1302的数据。
时间间隔可以调整{
ReadRTC_Flag=1;
//使用标志位判断
num=0;
}}}/*****END************/
以上经过在开发板上调试OK。
下面讲一下调试经验与大家分享。
首先用液晶显示DS1302分三步走。
第一步:
搞清楚液晶12864(带字库,方便使用),也就是怎样让其显示汉字及字符。
第二步:
搞清楚DS1302怎样用,怎样写入与显示出时间数据。
第三步:
把上面两步程序合在一起进行调试,当然要注意各端口的定义与连接。
这里并不能修改时间日期,以后会进一步研究。
总之,在液晶显示学习上又进一步了。
路要一步步走。