您的当前位置:首页正文

1602显示万年历

2023-04-01 来源:伴沃教育


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(); }

} }

因篇幅问题不能全部显示,请点此查看更多更全内容