|
DS1302时钟用lcd2602显示时间时不是程序写的初始化时间,用数码管显示就显示正常,请大神看看程序哪里写错了。
#include "reg51.h"
#include "intrins.h"
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit SCLK=P3^6;
sbit DSIO=P3^4;
sbit CE=P3^5;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
u8 code READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
u8 code WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
/*---DS1302时钟初始化2021年8月2日星期一18点37分00秒。---*/
/*---存储顺序是秒分时日月周年,存储格式是用BCD码---*/
u8 TIME[7]={0X00,0x37,0x18,0x02,0x08,0x01,0x18};
/*******************************************************************************
* 函 数 名 : Lcd1602_Delay1ms
* 函数功能 : 延时函数
* 输 入 : c
* 输 出 : 无
*******************************************************************************/
void Lcd1602_Delay1ms(u16 c) //误差 0us
{
u8 a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/*******************************************************************************
* 函 数 名 : Lcd1602_writecom
* 函数功能 : 写命令函数
* 输 入 : com
* 输 出 : 无
*******************************************************************************/
void Lcd1602_writecom(u8 com)
{
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
P0=com;
Lcd1602_Delay1ms(1);
LCD_EN=1;
Lcd1602_Delay1ms(5);
LCD_EN=0;
}
/*******************************************************************************
* 函 数 名 : Lcd1602_writedat
* 函数功能 : 写数据函数
* 输 入 : data
* 输 出 : 无
*******************************************************************************/
void Lcd1602_writedat(u8 dat)
{
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
Lcd1602_Delay1ms(1);
LCD_EN=1;
Lcd1602_Delay1ms(5);
LCD_EN=0;
}
/*******************************************************************************
* 函 数 名 : Lcd1602_init
* 函数功能 : 初始化函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Lcd1602_init()
{
Lcd1602_writecom(0x06);//模式设置命令
Lcd1602_Delay1ms(5);
Lcd1602_writecom(0x0C);//显示开关控制命令
Lcd1602_Delay1ms(5);
Lcd1602_writecom(0x38);//功能设置命令
Lcd1602_Delay1ms(5);
Lcd1602_writecom(0x01);//清屏命令
}
/*******************************************************************************
* 函 数 名 : Ds1302Write
* 函数功能 : 向DS1302命令(地址+数据)
* 输 入 : addr,dat
* 输 出 : 无
*******************************************************************************/
void Ds1302Write(u8 addr,u8 dat)
{
u8 i;
CE=0;
_nop_();
SCLK=0;
_nop_();
CE=1;
_nop_();
for(i=0;i<8;i++)//传8位地址指令
{
DSIO=addr & 0x01;//经过位于运算后得到addr的最低位,要循环8此才能把addr的8位地址指令发送完成
addr>>=1;//addr向右移以为,addr=0x80=10000000>>=01000000
SCLK=1;//上升沿的时候才会将地址指令发送给DS1302
_nop_();
SCLK=0;//地址指令发送完成后将SCLK至下降沿
_nop_();
}
_nop_();
for(i=0;i<8;i++)//写数据到DS1302里面去
{
DSIO=dat & 0x01;//经过位于运算后得到addr的最低位,要循环8此才能把addr的8位地址指令发送完成
addr>>=1;//addr向右移以为,addr=0x80=10000000>>=01000000
SCLK=1;//上升沿的时候才会将地址指令发送给DS1302
_nop_();
SCLK=0;//地址指令发送完成后将SCLK至下降沿
_nop_();
}
CE = 0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。
}
/*******************************************************************************
* 函 数 名 : Ds1302Read
* 函数功能 : 向DS1302命令(地址+数据)
* 输 入 : addr
* 输 出 : dat
*******************************************************************************/
u8 Ds1302Read(u8 addr)
{
u8 i,dat1,dats;
CE=0;
_nop_();
SCLK=0;
_nop_();
CE=1;
_nop_();
for(i=0;i<8;i++)//传8位地址指令
{
DSIO=addr & 0x01;//经过位于运算后得到addr的最低位,要循环8此才能把addr的8位地址指令发送完成
addr>>=1;//addr向右移以为,addr=0x80=10000000>>=01000000
SCLK=1;//上升沿的时候才会将地址指令发送给DS1302
_nop_();
SCLK=0;//地址指令发送完成后将SCLK至下降沿
_nop_();
}
_nop_();
for(i=0;i<8;i++)//写数据到DS1302里面去
{
dat1=DSIO;//将DS1302发送过来的数据储存在dat1中
dats=(dats >> 1)|(dat1 << 7);
SCLK=1;//上升沿的时候才会将地址指令发送给DS1302
_nop_();
SCLK=0;//地址指令发送完成后将SCLK至下降沿
_nop_();
}
CE = 0;
_nop_(); //以下为DS1302复位的稳定时间,必须的。
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return (dats);//将得到的数据反馈给函数
}
/*******************************************************************************
* 函 数 名 : Ds1302Init
* 函数功能 : 初始化DS1302.
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Ds1302Init()
{
u8 n;
Ds1302Write(0x8E,0x00); //禁止写保护,就是关闭写保护功能
for (n=0;n<7;n++)//写入7个字节的时钟信号:分秒时日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80); //打开写保护功能
}
/*******************************************************************************
* 函 数 名 : Ds1302ReadTime
* 函数功能 : 读取时钟信息
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Ds1302ReadTime()
{
u8 n;
for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
{
TIME[n]= Ds1302Read(READ_RTC_ADDR[n]);
}
}
/*******************************************************************************
* 函数名 : LcdDisplay()
* 函数功能 : 显示函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void LcdDisplay()
{
Ds1302ReadTime();
Lcd1602_writecom(0x80+0X40);
Lcd1602_writedat('0'+TIME[6]/16); //时
Lcd1602_writedat('0'+(TIME[6]&0x0f));
Lcd1602_writedat('-');
Lcd1602_writedat('0'+TIME[1]/16); //分
Lcd1602_writedat('0'+(TIME[1]&0x0f));
Lcd1602_writedat('-');
Lcd1602_writedat('0'+TIME[0]/16); //秒
Lcd1602_writedat('0'+(TIME[0]&0x0f));
Lcd1602_writecom(0x80);
Lcd1602_writedat('2');
Lcd1602_writedat('0');
Lcd1602_writedat('0'+TIME[6]/16); //年
Lcd1602_writedat('0'+(TIME[6]&0x0f));
Lcd1602_writedat('-');
Lcd1602_writedat('0'+TIME[4]/16); //月
Lcd1602_writedat('0'+(TIME[4]&0x0f));
Lcd1602_writedat('-');
Lcd1602_writedat('0'+TIME[3]/16); //日
Lcd1602_writedat('0'+(TIME[3]&0x0f));
Lcd1602_writedat(0x8D);
Lcd1602_writedat('0'+(TIME[5]&0x07)); //星期
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main(void)
{
Ds1302Init();
Lcd1602_init();
while(1)
{
LcdDisplay();
}
} |
|