萌新小白,第一次发帖,望见谅!这是我以前做的一个实验,用protues仿真,DS1302读取时间,LCD1602显示出读取的时间。
附件带源文件和仿真工程。
实验效果图:
LCD显示DS1302的时间
单片机源程序如下:
- #include <reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define WRITE_SECOND 0x80
- #define WRITE_MINUTE 0x82
- #define WRITE_HOUR 0x84
- #define READ_SECOND 0x81
- #define READ_MINUTE 0x83
- #define READ_HOUR 0x85
- #define WRITE_PROTECT 0x8E
- sbit IO=P1^0;
- sbit SCLK=P1^1;
- sbit RST=P1^2;
- sbit LCD_RS=P2^0;
- sbit LCD_RW=P2^1;
- sbit LCD_E=P2^2;
- uchar DATE[]={"DATE:2000-00-00"};
- uchar TIME[]={"TIME:00:00:00 "};
- uchar date_time[7];
- void delay_ms(uint x)
- {
- uint i,j;
- for(i=x;i>0;i--)
- {
- for(j=112;j>0;j--);
- }
- }
- void write_ds1302(uchar date)//写入地址或者数据(控制字)
- {
- uint i;
- SCLK=0;//开始准备传输
- for(i=0;i<8;i++)
- {
- IO=date&0x01;//读取每一位的值
- SCLK=1;
- delay_ms(2);
- SCLK=0;
- date>>=1;//右移一位
- }
- }
- uchar read_ds1302()//读取数据
- {
- uint i;
- uchar date=0x00;
- for(i=0;i<8;i++)
- {
- date>>=1;
- if(IO==1)//如果读取出来的值是1,则将数据定为1,不是就定为0
- date|=0x80;
- SCLK=1;
- delay_ms(2);
- SCLK=0;
- }
- return date/16*10+date%16;//16进制转换成10进制
- }
- void write_time(uchar addr,uchar date)//写入你要修改的时间值
- {
- RST=0;//初始化CE线,复位
- SCLK=0;//时钟总线清零
- RST=1;//CE置1,传输开始
- write_ds1302(addr);//传入你要写入的时间(时间或者日历地址)
- write_ds1302(date);//写入你要修改的时间值
- SCLK=1;//时间线拉高
- RST=0;//写入结束
- }
- uchar read_time(uchar addr)//读取你需要的时间值
- {
- uchar dat;
- RST=0;//初始化CE线,复位
- SCLK=0;//时钟总线清零
- RST=1;//CE置1,传输开始
- write_ds1302(addr);//传入你要读取的时间地址
- dat=read_ds1302();//读取时间值
- SCLK=1;//时间线拉高
- RST=0;//读取结束
- return dat;
- }
- void LCD_write_commd(uchar com)//写入命令,如显示地址或者是写入CGRAM,此次代码没有这个功能
- {
- LCD_RS=0;//写命令
- LCD_RW=0;
- P0=com;
- delay_ms(2);
- LCD_E=1;
- delay_ms(2);
- LCD_E=0;
- }
- void LCD_write_date(uchar dat)//写入数据,这次是写入字符码,显示在液晶屏上
- {
- LCD_RS=1;//写数据
- LCD_RW=0;
- P0=dat;
- delay_ms(2);
- LCD_E=1;
- delay_ms(2);
- LCD_E=0;
- }
- void init_LCD1602()//初始化
- {
- LCD_write_commd(0x38);
- delay_ms(2);
- LCD_write_commd(0x0c);
- delay_ms(2);
- LCD_write_commd(0x06);
- delay_ms(2);
- LCD_write_commd(0x01);
- delay_ms(2);
- }
- void set_lcd_pos(uchar p)//设置显示位置
- {
- LCD_write_commd(p|0x80);
- }
- void LCD_print(uchar p,uchar *s)//显示
- {
- uint i;
- set_lcd_pos(p);
- for(i=0;i<16;i++)
- {
- LCD_write_date(s[i]);
- delay_ms(10);
- }
- }
- void Get_time()//读取时间
- {
- uchar i,addr=0x81;
- for(i=0;i<7;i++)
- {
- date_time[i]=read_time(addr);
- addr+=2;
- }
- }
- void Format_Datetime(uchar d,uchar *a)//将日期和时间值转换成数字字符
- {
- a[0]=d/10+'0';
- a[1]=d%10+'0';
- }
- void init_DS1302()//DS1302初始化
- {
- write_time(WRITE_PROTECT,0x00);
- write_time(WRITE_SECOND,0x56);
- write_time(WRITE_MINUTE,0x34);
- write_time(WRITE_HOUR,0x12);
- write_time(WRITE_PROTECT,0x80);
-
- }
- void main()
- {
- //init_DS1302();
- init_LCD1602();//初始化液晶屏
- while(1)
- {
- Get_time();
- Format_Datetime(date_time[6],DATE+7);
- Format_Datetime(date_time[4],DATE+10);
- Format_Datetime(date_time[3],DATE+13);
- Format_Datetime(date_time[2],TIME+5);
- Format_Datetime(date_time[1],TIME+8);
- Format_Datetime(date_time[0],TIME+11);
- LCD_print(0x00,DATE);
- LCD_print(0x40,TIME);
- }
-
- }
复制代码
所有资料51hei提供下载:
DS1302 LCD1602显示.rar
(64.47 KB, 下载次数: 92)
|