首页 > 编程知识 正文

lcd1602显示时钟(1602显示时钟和日期)

时间:2023-05-04 16:44:38 阅读:63884 作者:2748

DS1302时钟

DS1302是实时时钟芯片,适用于实时显示时间。 可以计时年、月、日、周、时、分、秒。

DS1302的针脚和原理图如下。

与CPU的连接需要sclk(7)、I/o (rst ) ) 3个引脚,VCC2和VCC1分别连接主电源和备用电源,X1和X2分别连接外部振荡器。 在CPU通信中,I/O用于传输数据,RST用作复位信号,SCLK用于控制数据字节的读写。

DS1302的读写时机如下。

程序中对芯片的操作主要参照芯片的时序状态,在时序中表示如果有对数据的操作RST则需要设置1,在读出数据的前8个时钟中,SCLK为高电平期间取得控制字信息,在该过程中I/O数据不发生变化将数据读取到最后8个时钟,但对SCLK的控制与前8个时钟相反。 写数据和读数据的过程相似之处只是稍后读写的SCLK时钟控制信号不同。

DS1302的时钟寄存器如下。

第六位选择时钟或RAM,第零位用于读写选择。 对于第1、2、3位,使秒、分、时、日、月、周、年和控制字地址依次对应。

LCD1602液晶

LCD1602是用于显示字母、数字、符号等的点阵型液晶模块。 使用它来显示所需的文字、数字、符号等,比数码管和LED点阵更有用。

LCD1602的针脚图示如下。

引脚1、2是接地和电源,引脚4是通过RS控制数据和命令的选择,引脚5是通过R/W控制读写的选择控制,引脚6是使能控制信号。 第七至第十四个分别对应于数据的8位。

LCD1602的读写时机如下。

写入时机:

提前期:

RS控制数据和命令的选择,读写数据时设定高电平,否则设定低电平; R/W用于控制读写选择,写入动作时为低电平(第1图),读出动作时为高电平) (第2图); 读写过程需要e给出高脉冲。

与LCD1602的状态字对应的命令:

状态字

高6位对应于数据的地址,第7位是读写使能控制位。

对应的命令:

模式设定命令为0x38。 清除画面显示为0x01; 数据指针被清除为0x02。

显示开关和光标设置:

程序

以下是通过LCD1602显示DS1302时钟信息的例程。

程序分为4个文件信息,关于其内容可以参照相关注释信息。 1、用于定义1602.h文件(见1602.c )、LCD1602的关联管脚和函数声明。

类型字节布尔; sbit RS=P2^6; //复位侧sbit RW=P2^5; //写入数据侧sbit EN=P2^7; //有效侧# defineuintunsignedint # defineucharunsignedcharvoiddelay (inti ); bit lcd_bz (; voidLCD_wcmd(intcmd; voidLCD_showstring(ucharr、uchar c、uchar *str ); voidLCD_wdat(uchardat; void lcd_init (;

2,1602.c文件包含LCD1602的初始化、数据和命令的读写控制。

/prep span style=' font-size :24 px '/span prename=' code ' class=' CPP ' # includere g51.h # includeintrins.h # j250; j({_NOP_ ); _nop_ (); _nop_ (); _nop_ (); ()//侧忙,判断液晶屏是否忙。 boolLCD_BZ({boolresult; RS=0; RW=1; EN=1; _nop_ (); _nop_ (); _nop_ (); _nop_ ();

result = (bool)(P0 & 0x80);//检测P0最高位是否为1.EN = 0;return result;//返回判断的结果。}//写命令函数。void lcd_wcmd_8bit(int cmd){while(lcd_bz());RS = 0;RW = 0;EN = 0;//先为低电平。_nop_();_nop_();P0 = cmd; //获得数据。_nop_();_nop_();_nop_();_nop_();EN = 1; //将电平拉高。_nop_();_nop_();_nop_();_nop_();EN = 0; //再拉低。} //写命令函数。void lcd_wcmd(int cmd){while(lcd_bz());RS = 0;RW = 0;EN = 0; //先为低电平。_nop_();_nop_();P0 = cmd;//获得高四位数据。_nop_();_nop_();_nop_();_nop_();EN = 1;//拉高。_nop_();_nop_();_nop_();_nop_();EN = 0;//再拉低。P0 = (cmd & 0x0f)<<4; //再获得低四位数据。_nop_();_nop_();_nop_();_nop_();EN = 1; //将电平拉高。_nop_();_nop_();_nop_();_nop_();EN = 0; //再拉低。}void lcd_showstring(uchar r,uchar c,uchar *str){uchar i=0;code uchar DDRAM[] = {0x80,0xc0}; //设定显示的位置。lcd_wcmd(DDRAM[r] | c);for(i=0;str[i] && i<16;i++)lcd_wdat(str[i]);for(;i<16;i++)lcd_wdat(' ');}//数据写入的函数。void lcd_wdat(uchar dat){while(lcd_bz());RS = 1;RW = 0;EN = 0;//先处于低电平。P0 = dat; //获得数据高四位。_nop_();_nop_();_nop_();_nop_();EN = 1;_nop_();_nop_(); //再产生一个负脉冲。_nop_();_nop_();EN = 0;RS = 1;RW = 0;EN = 0;_nop_();_nop_();_nop_();_nop_();P0 = (dat & 0x0f)<<4;//同理获得低四位。_nop_();_nop_();_nop_();_nop_();EN = 1;_nop_();_nop_();_nop_();_nop_();EN = 0;}//LCD初始化。void lcd_init(){lcd_wcmd_8bit(0x38);delay(1);lcd_wcmd_8bit(0x38);delay(1);lcd_wcmd_8bit(0x38);delay(1);lcd_wcmd(0x38);delay(1);lcd_wcmd(0x0c);delay(1);lcd_wcmd(0x02);delay(1);lcd_wcmd(0x01);delay(1);}

3、DS1302时钟.c文件,其中含有DS1302时钟的引脚定义及时钟信息的读写等相关操作。

#include <reg52.h>#include <intrins.h>sbit SCK = P3^6; //时钟线sbit IO = P3^4; //数据线sbit RST = P3^5; //DS1302复位线。bit ReadRTC_Flag; //读DS1302的标志。//七项数据:秒分时日月周年。unsigned char l_tmpdate[7] = {0,0,12,15,5,3,8};//用来存放转化好的时间数据。unsigned char l_tmpdisplay[8];//7个数据的写地址。code unsigned char write_rtc_add[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//7个数据的读地址。code unsigned char read_rtc_add[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};//函数的声明。void Write_Ds1302_byte(unsigned char temp);void write_Ds1302(unsigned char add,unsigned char dat);unsigned char Read_Ds1302(unsigned char add);void Read_RTC(void);void Set_RTC(void);void InitTIMER0(void);//定时器的初始化。void InitTIMER0(void){TMOD |= 0x01;TH0 = 0xef;TL0 = 0xf0;ET0 = 1;TR0 = 1;EA = 1;}//向1302中发送一个字节数据。void Write_Ds1302_Byte(unsigned char temp){unsigned char i;for(i=0;i<8;i++) //循环8位依次写入数据。{SCK = 0;IO = temp & 0x01;//传输时从低到高。temp>>=1; //右移1位。SCK = 1;}}//向1302中写入数据。参数有要写入的地址和数据。void Write_Ds1302(unsigned char add,unsigned char dat){RST = 0;_nop_();SCK = 0;_nop_();RST = 1;_nop_();Write_Ds1302_Byte(add);//发送地址。Write_Ds1302_Byte(dat);//发送数据。RST = 0;}//从1302中的读出数据。unsigned char Read_Ds1302(unsigned char add){unsigned char i,temp=0x00;RST = 0;_nop_();_nop_();SCK = 0;_nop_();_nop_();RST = 1;_nop_();_nop_();Write_Ds1302_Byte(add); //发送地址,找到地址。for(i=0;i<8;i++) //循环8次读出数据。{if(IO)//传输从低到高。temp |= 0x80;SCK = 0;temp>>=1;//右移1位。_nop_();_nop_();_nop_();SCK = 1;}RST = 0;//之后为DS1302复位。_nop_();_nop_();//RST = 0; //试验时去掉该句没有影响。SCK = 0;_nop_();_nop_();_nop_();_nop_();SCK = 1;_nop_();_nop_();IO = 0;_nop_();_nop_();IO = 1;_nop_();_nop_();return temp;//将读到的数据返回。}//从时钟中读取数据。void Read_RTC(void){unsigned char i,*p;p = read_rtc_add; //读日历数据对应的地址。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码转化出来,因为1302中用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_add;//传送地址。for(i=0;i<7;i++)//将数据依次写入。{Write_Ds1302(*p,l_tmpdate[i]);p++;}Write_Ds1302(0x8e,0x80); //打开写入保护,不能再写入。}//定时器中断函数。void 俊逸的樱桃(void) interrupt 1 using 1{static unsigned char i,num;TH0 = 0xf5;TL0 = 0xe0;i++;if(i==8){i=0;num++;if(10==num) //间隔一定时间读取1302中数据,更新数码管数据。{ReadRTC_Flag = 1; //置标志位,从而进行判断。num = 0;}}}

4、LCD显示1302时钟.c文件,这是主函数所在文件,用来将从DS1302获得的信息在LCD1602中显示的操作。

#include <reg51.h>#include <intrins.h>#include <string.h>#define uchar unsigned char#define uint unsigned intuchar *week[] = {"sun","mon","tus","wes","thu","fri","sat"}; //cjdxy,周一到周日。uchar lcd_buf1[] = "date 00-00-00 "; //日期信息。uchar lcd_buf2[] = "俊逸的樱桃e 00:00:00 "; //时间信息。//从其他文件引进的函数。extern void InitTIMER0(void);extern void lcd_init();extern void lcd_showstring(uchar ,uchar ,uchar *);extern uchar l_tmpdate[7];extern bit ReadRTC_Flag;extern void delay(int i);extern void Read_RTC(); extern void Set_RTC();//将日期和时间信息转化为数字字符。void format_date俊逸的樱桃e(int d,uchar * a){*a = (d >> 4) + '0';*(a+1) = (d & 0x0f) + '0';}void main(){lcd_init(); //LCD的初始化。InitTIMER0(); //初始化定时器0。//Set_RTC();//写入时钟值(写入时钟初值),如果不用改时间可以不用这一项。while(1){if(ReadRTC_Flag){ReadRTC_Flag = 0;Read_RTC();//日期转换。format_date俊逸的樱桃e(l_tmpdate[6],lcd_buf1+5);format_date俊逸的樱桃e(l_tmpdate[4],lcd_buf1+8);format_date俊逸的樱桃e(l_tmpdate[3],lcd_buf1+11);//星期转换。strcpy(lcd_buf1 + 13,week[l_tmpdate[5]-1]);//定义一个字符串char a[20],和一个字符串c[]="i am a teacher!";//把c复制到a中就可以这样用:strcpy(a,c);//时间转换。format_date俊逸的樱桃e(l_tmpdate[2],lcd_buf2+5);format_date俊逸的樱桃e(l_tmpdate[1],lcd_buf2+8);format_date俊逸的樱桃e(l_tmpdate[0],lcd_buf2+11);lcd_showstring(0,0,lcd_buf1); //将lcd_buf1和lcd_buf2字符输出。lcd_showstring(1,0,lcd_buf2);}}}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。