51单片机和DS1302的问题求助!

qq_45491646 2020-06-11 03:10:50
最近在学习使用DS1302模块,遇到一个问题。就是我需要把DS1302的时间在LCD上显示,但是我LCD显示出的时间是程序里初始化的时间,而不是当前实时的时间,求大佬指导一下。 下面是我的程序: #include<reg51.h>#include <intrins.h> //包含_nop_( )空函数指令的头文件#define uchar unsigned char#define uint unsigned intsbit IO=P1^2; //输入输出sbit SCLK=P1^1; //时钟sbit RST=P1^0; //复位sbit RS=P2^5; //位变量sbit RW=P2^6; //位变量sbit E=P2^7; //位变量 //---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年 最低位读写位;-------//uchar READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; uchar WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---////---存储顺序是秒分时日月周年,存储格式是用BCD码---//uchar TIME[6]={0,0,0x12,0x01,0x01,0x13};void Lcd_Display(); //LCD显示函数void delay(uint j); //延时函数void check_busy(void); //忙标志检测函数void write_command(uchar com); //写命令函数void write_data(uchar dat); //写数据函数void Lcd_Init(void); //LCD初始化函数void Ds1302_Write(uchar addr, uchar dat); //DS1302写命令函数uchar Ds1302_Read(uchar addr); //DS1302读一个地址的数据void Ds1302_Init(); //初始化DS1302void Ds1302_ReadTime(); //读取时钟信息/*************************************主函数****************************************/void main(){ Lcd_Init(); Ds1302_Init(); while(1) Lcd_Display(); }/****************************1ms延时函数****************************************/void delay(uint j){ uchar i=250; for(;j>0;j--) { while(--i); i=249; while(--i); i=250; }}/****************************液晶显示器初始化函数****************************************/void Lcd_Init(void){ write_command(0x38); //写入命令0x38:8位两行 显示,5×7点阵字符 write_command(0x0c); //写入命令0x0C:开整体 显示,光标关,无黑块 write_command(0x06); //写入命令0x06,0x05左 write_command(0x01); //写入命令0x01:清屏 delay(1);}/****************************写命令函数****************************************/void write_command(uchar com){ check_busy(); E=0; RS=0; RW=0; P0=com; E=1; _nop_( ); E=0; delay(1);}/****************************写数据函数****************************************/void write_data(uchar dat){ check_busy(); E=0; RS=1; RW=0; P0=dat; E=1; _nop_(); E=0; delay(1); }/****************************检查忙标志函数****************************************/void check_busy(void) { uchar dt; do { dt=0xff; E=0; RS=0; RW=1; E=1; dt=P0; }while(dt&0x80); E=0;}/*******************************初始化DS1302*************************************/void Ds1302_Init(){ uchar n; Ds1302_Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能 for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年 { Ds1302_Write(WRITE_RTC_ADDR[n],TIME[n]); } Ds1302_Write(0x8E,0x80); //打开写保护功能}/***************************向DS1302写命令(地址+数据)*********************************/void Ds1302_Write(uchar addr, uchar dat){ uchar n; RST = 0; _nop_(); SCLK = 0;//先将SCLK置低电平。 _nop_(); RST = 1; //然后将RST(CE)置高电平。 _nop_(); for (n=0; n<8; n++)//开始传送八位地址命令 { IO = addr & 0x01;//数据从低位开始传送 addr >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0; _nop_(); } for (n=0; n<8; n++)//写入8位数据 { IO = dat & 0x01; dat >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0; _nop_(); } RST = 0;//传送数据结束 _nop_();}/******************************读取一个地址的数据*******************************/uchar Ds1302_Read(uchar addr){ uchar n,dat,dat1; RST = 0; _nop_(); SCLK = 0;//先将SCLK置低电平。 _nop_(); RST = 1;//然后将RST(CE)置高电平。 _nop_(); for(n=0; n<8; n++)//开始传送八位地址命令 { IO = addr & 0x01;//数据从低位开始传送 addr >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0;//DS1302下降沿时,放置数据 _nop_(); } _nop_(); for(n=0; n<8; n++)//读取8位数据 { dat1 = IO;//从最低位开始接收 dat = (dat>>1) | (dat1<<7); SCLK = 1; _nop_(); SCLK = 0;//DS1302下降沿时,放置数据 _nop_(); } RST = 0; _nop_(); //以下为DS1302复位的稳定时间,必须的。 SCLK = 1; _nop_(); IO = 0; _nop_(); IO = 1; _nop_(); return dat; }/*********************************读取时钟信息***************************************/void Ds1302_ReadTime(){ uchar n; for (n=0; n<6; n++)//读取6个字节的时钟信号:秒分时日月周年 { TIME[n] = Ds1302_Read(READ_RTC_ADDR[n]); } }/********************************LCD显示函数*************************************/void Lcd_Display(){ Ds1302_ReadTime(); write_command(0x80+0X40); write_data('0'+TIME[2]/16); //时 write_data('0'+(TIME[2]&0x0f)); write_data('-'); write_data('0'+TIME[1]/16); //分 write_data('0'+(TIME[1]&0x0f)); write_data('-'); write_data('0'+TIME[0]/16); //秒 write_data('0'+(TIME[0]&0x0f)); write_command(0x80); write_data('2'); write_data('0'); write_data('0'+TIME[5]/16); //年 write_data('0'+(TIME[5]&0x0f)); write_data('-'); write_data('0'+TIME[4]/16); //月 write_data('0'+(TIME[4]&0x0f)); write_data('-'); write_data('0'+TIME[3]/16); //日 write_data('0'+(TIME[3]&0x0f)); }
...全文
204 点赞 收藏 3
写回复
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Adolf518 2020-06-22
DS1302首次初始化把时间写进去,再将初始化时间的代码注释掉重新编译再烧录一次就OK
回复
xuyaqi029 2020-06-11
注释掉DS1302初始化语句再编译,就不会每次上电就是初始化时间。
回复
zgl7903 2020-06-11
详细看DS1302的手册, 里面有一个控制位用于启动RTC时钟
回复
相关推荐
发帖
单片机/工控
创建于2007-09-28

2.6w+

社区成员

硬件/嵌入开发 单片机/工控
申请成为版主
帖子事件
创建了帖子
2020-06-11 03:10
社区公告
暂无公告