1602显示万年历 D
bit ReadRTC_Flag;//定义读DS1302标志 unsigned 周年
unsigned char l_tmpdisplay[18]; code
unsigned
char
write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位 code
unsigned
char
read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //读的地址
/******************************************************************/
/* 函数声明 */
/******************************************************************/
void Write_Ds1302_byte(unsigned char temp);
char
l_tmpdate[7]={59,42,22,22,1,2,13};//秒分时日月
void Write_Ds1302( unsigned char
address,unsigned char dat );
unsigned char Read_Ds1302 ( unsigned char address );
void Read_RTC(void);//read RTC void Set_RTC(void); //set RTC void InitTIMER0(void);//inital timer0
/*------------------------------------------------ uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); }
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/ void DelayMs(unsigned char t) { while(t--) {
//大致延时1mS DelayUs2x(245); DelayUs2x(245); } }
/*------------------------------------------------ 判忙函数
------------------------------------------------*/ bit LCD_Check_Busy(void)
{
DataPort= 0xFF; RS_CLR; RW_SET; EN_CLR; _nop_(); EN_SET;
return (bit)(DataPort & 0x80); }
/*------------------------------------------------ 写入命令函数 ------------------------------------------------*/ void LCD_Write_Com(unsigned char com) {
while(LCD_Check_Busy()); //忙则等待 RS_CLR; RW_CLR; EN_SET; DataPort= com; _nop_(); EN_CLR; }
/*------------------------------------------------ 写入数据函数 ------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) {
while(LCD_Check_Busy()); //忙则等待 RS_SET; RW_CLR; EN_SET; DataPort= Data; _nop_(); EN_CLR; }
/*------------------------------------------------ 清屏函数
------------------------------------------------*/ void LCD_Clear(void) {
LCD_Write_Com(0x01); DelayMs(5); }
/*------------------------------------------------ 写入字符串函数 ------------------------------------------------*/ void { if (y == 0) {
LCD_Write_Com(0x80 + x); } else {
LCD_Write_Com(0xC0 + x); } while (*s) {
LCD_Write_Data( *s); s ++; } }
/*------------------------------------------------ 写入字符函数
LCD_Write_String(unsigned char
x,unsigned char y,unsigned char *s)
void { if (y == 0) {
LCD_Write_Com(0x80 + x); } else {
LCD_Write_Com(0xC0 + x); }
LCD_Write_Data( Data); } */
/*------------------------------------------------------ 写入数字函数 字符的地址加0x30显示数字
--------------------------------------------------------- */ void {
LCD_Write_Char(unsigned char
x,unsigned char y,unsigned char Data)
LCD_Write_num(unsigned char
x,unsigned char y,unsigned char num)
if (y == 0) {
LCD_Write_Com(0x80 + x); } else {
LCD_Write_Com(0xC0 + x); }
LCD_Write_Data( 0x30+num); }
/*------------------------------------------------ 初始化函数
------------------------------------------------*/ void LCD_Init(void) {
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38); DelayMs(5);
LCD_Write_Com(0x38); DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/ LCD_Write_Com(0x01); /*显示清屏*/ LCD_Write_Com(0x06); /*显示光标移动设置*/ DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/ }
/******************************************************************/
/* 写一个字节 */
/******************************************************************/
void Write_Ds1302_Byte(unsigned char temp) {
unsigned char i;
for (i=0;i<8;i++) //循环8次 写入数据
{
SCK=0;
SDA=temp&0x01; //每次传输低字节 temp>>=1; //右移一位 SCK=1; } }
/******************************************************************/
/* 写入DS1302 */
/******************************************************************/ void { RST=0; _nop_(); SCK=0; _nop_(); RST=1;
_nop_(); //启动
Write_Ds1302( unsigned char
address,unsigned char dat )
Write_Ds1302_Byte(address); //发送地址 Write_Ds1302_Byte(dat); //发送数据 RST=0; //恢复 }
/******************************************************************/
/* 读出DS1302数据 */
/******************************************************************/
unsigned char Read_Ds1302 ( unsigned char address ) {
unsigned char i,temp=0x00; RST=0; _nop_(); _nop_(); SCK=0; _nop_(); _nop_(); RST=1; _nop_();
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++) { if(SDA)
temp|=0x80; SCK=0;
temp>>=1; _nop_(); _nop_(); _nop_(); SCK=1; } RST=0;
_nop_(); 稳定时间 _nop_(); RST=0; SCK=0; _nop_(); _nop_(); _nop_();
//循环8次 读取数据 //每次传输低字节 //右移一位 //以下为DS1302复位的
_nop_(); SCK=1; _nop_(); _nop_(); SDA=0; _nop_(); _nop_(); SDA=1; _nop_(); _nop_();
return (temp); //返回 }
/******************************************************************/
/* 读时钟数据 */
/******************************************************************/
void Read_RTC(void) //读取 日历 {
unsigned char i,*p;
p=read_rtc_address; //地址传递
for(i=0;i<7;i++) //分7次读取 秒分时日月周年 {
l_tmpdate[i]=Read_Ds1302(*p); p++; } }
/******************************************************************/
/* 设定时钟数据 */
/******************************************************************/
void Set_RTC(void) //设定 日历 {
unsigned char i,*p,tmp; for(i=0;i<7;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; //传地址
for(i=0;i<7;i++) //7次写入 秒分时日月周年 {
Write_Ds1302(*p,l_tmpdate[i]); p++; }
Write_Ds1302(0x8E,0x80); }
/******************************************************************/
/* 定时器中断函数 */
/******************************************************************/ void tim(void) interrupt 1 using 1
//中断,用于数码管扫描 {
static unsigned char num; TH0=0xf5; TL0=0xe0; num++;
if(10==num) //隔段时间读取1302的数据。时间间隔可以调整 {
ReadRTC_Flag=1; //使用标志位判断 num=0; } }
/*------------------------------------------ 显示部分 ------------------------------------------*/ void displaylcd(void) {
LCD_Init(); LCD_Clear();
LCD_Write_num(0,1,l_tmpdisplay[0]); LCD_Write_num(1,1,l_tmpdisplay[1]); //秒 LCD_Write_String(2,1,\":\");
LCD_Write_num(3,1,l_tmpdisplay[3]); LCD_Write_num(4,1,l_tmpdisplay[4]); //分 LCD_Write_String(5,1,\":\");
LCD_Write_num(6,1,l_tmpdisplay[6]); LCD_Write_num(7,1,l_tmpdisplay[7]); //时 LCD_Write_String(9,0,\"w\"); LCD_Write_String(10,0,\"e\"); LCD_Write_String(11,0,\"e\"); LCD_Write_String(12,0,\"k\"); LCD_Write_String(13,0,\":\");
LCD_Write_num(14,0,l_tmpdisplay[8]); LCD_Write_num(15,0,l_tmpdisplay[9]);//周 LCD_Write_String(2,0,\"-\");
LCD_Write_num(3,0,l_tmpdisplay[11]);//日 LCD_Write_num(4,0,l_tmpdisplay[12]); LCD_Write_String(5,0,\"-\");
LCD_Write_num(6,0,l_tmpdisplay[16]);//月 LCD_Write_num(7,0,l_tmpdisplay[17]); LCD_Write_num(0,0,l_tmpdisplay[14]);
LCD_Write_num(1,0,l_tmpdisplay[15]); //年
l_tmpdisplay[0]=l_tmpdate[2]/16; l_tmpdisplay[1]=l_tmpdate[2]&0x0f;
l_tmpdisplay[3]=l_tmpdate[1]/16; l_tmpdisplay[4]=l_tmpdate[1]&0x0f;
l_tmpdisplay[6]=l_tmpdate[0]/16; l_tmpdisplay[7]=l_tmpdate[0]&0x0f;
l_tmpdisplay[8]=l_tmpdate[5]/16; l_tmpdisplay[9]=l_tmpdate[5]&0x0f;
l_tmpdisplay[11]=l_tmpdate[4]/16; l_tmpdisplay[12]=l_tmpdate[4]&0x0f;
l_tmpdisplay[14]=l_tmpdate[6]/16; l_tmpdisplay[15]=l_tmpdate[6]&0x0f;
l_tmpdisplay[16]=l_tmpdate[3]/16;
l_tmpdisplay[17]=l_tmpdate[3]&0x0f; }
/******************************************************************/
/* 定时器0初始化 */
/******************************************************************/
void InitTIMER0(void) {
TMOD|=0x01;//定时器设置 16位 TH0=0xef;//初始化值 TL0=0xf0; ET0=1; TR0=1; EA=1; }
/******************************************************************/
/* 主函数
*/
/******************************************************************/ void main(void) { char i;
InitTIMER0(); //初始化定时器0 //Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽
displaylcd(); while(1) {
if(ReadRTC_Flag==1) {
ReadRTC_Flag=0; Read_RTC();
displaylcd(); }
} }
因篇幅问题不能全部显示,请点此查看更多更全内容