51单片机DS1302模块编程的时候,实验效果:秒显示每四秒更新一次,而不是一秒
时间:10-02
整理:3721RD
点击:
#include<reg51.h>
#include<intrins.h>
//定义DS1302使用的端口
sbit DSIO=P3^4;
sbit SCLK=P3^6;
sbit CE=P3^5;
//定义LCD使用的端口
sbit LCD_E=P2^7;
sbit LCD_RW=P2^5;
sbit LCD_RS=P2^6;
#define LCDIO P0
unsigned char code ds1302readaddr[7]={0x8B,0x81,0x83,0x85,0x87,0x89,0x8D};//读寄存器地址
unsigned char code ds1302writeaddr[7]={0x8A,0x80,0x82,0x84,0x86,0x88,0x8C};//写寄存器地址
unsigned char Time[7]={0x01,0,0,0,0x14,0x08,0x17};//星期 秒 分 时 日 月 年 //初始时间2017年8月3日00点00分00秒星期四 BCD码表示
void lcddisplay();
void ds1302write(unsigned char addr,unsigned char dat);
unsigned char ds1302read(unsigned char addr);
void ds1302init();
void ds1302readtime();
void lcd1602writecom(unsigned char com);
void lcd1602writedata(unsigned char dat);
void lcdinit();
void delayms(unsigned char c);
void main() //主程序,显示时间
{
lcdinit();//初始化LCD
ds1302init();//初始化ds1302
while(1)
{
ds1302readtime();//读取ds1302的数据
lcddisplay();//lcd显示ds1302的数据
}
}
void lcddisplay()
{
lcd1602writecom(0x80);//在第一行显示
lcd1602writedata('0'+Time[3]/16);
lcd1602writedata('0'+(Time[3]&0x0f)); //时
lcd1602writedata(':');
lcd1602writedata('0'+Time[2]/16);
lcd1602writedata('0'+(Time[2]&0x0f)); //分
lcd1602writedata(':');
lcd1602writedata('0'+Time[1]/16);
lcd1602writedata('0'+(Time[1]&0x0f)); //秒
lcd1602writecom(0xc0);
lcd1602writedata('2');
lcd1602writedata('0');
lcd1602writedata('0'+Time[6]/16); //年十位
lcd1602writedata('0'+(Time[6]&0x0f)); //年个位
lcd1602writedata('-');
lcd1602writedata('0'+Time[5]/16); //月十位
lcd1602writedata('0'+(Time[5]&0x0f)); //月个位
lcd1602writedata('-');
lcd1602writedata('0'+(Time[4]/16)); //日十位
lcd1602writedata('0'+(Time[4]&0x0f)); //日个位
lcd1602writedata('-');
lcd1602writedata('0'+(Time[0]&0x07)); //周
}
//DS1302程序段
//写入地址和数据
void ds1302write(unsigned char addr,unsigned char dat)
{
unsigned char n;
CE=0;
SCLK=0;
CE=1;
for(n=0;n<8;n++) //写入地址码
{
DSIO=addr&0x01;
addr>>=1;
SCLK=1;
SCLK=0;
}
for(n=0;n<8;n++) //写入数据码
{
DSIO=dat&0x01;
dat>>=1;
SCLK=1;
SCLK=0;
}
CE=0;
}
unsigned char ds1302read(unsigned char addr)//读取数据
{
unsigned char n,dat1,dat;
CE=0;
SCLK=0;
CE=1;
for(n=0;n<8;n++)
{
DSIO=addr&0x01;
addr>>=1;
SCLK=1;
SCLK=0;
}
_nop_();
for(n=0;n<8;n++)
{
dat1=DSIO&0x01;
dat1=dat1<<7;
dat=(dat>>1)|(dat1);
SCLK=1;
SCLK=0;
}
CE=0;
_nop_();
SCLK=1;
_nop_();
DSIO=0;
_nop_();
DSIO=1;
_nop_();
return dat;
}
void ds1302init() //初始化DS1302
{
unsigned char n;
ds1302write(0x8E,0x00); //关闭写保护
for(n=0;n<7;n++)
{
ds1302write(ds1302writeaddr[n],Time[n]);
}
ds1302write(0x8E,0x80); //开启写保护
}
void ds1302readtime() //读取时钟信息
{
unsigned char n;
for(n=0;n<7;n++)
{
Time[n]=ds1302read(ds1302readaddr[n]);
}
}
//LCD程序段
void lcd1602writecom(unsigned char com) //lcd1602写命令程序
{
LCD_E=0; //使能端为0
LCD_RS=0; //数据命令端为0,代表命令
LCD_RW=0; //读写端为0,代表写入
LCDIO=com; //输入端输入一个命令字节
delayms(4); //延迟40ns
LCD_E=1;
delayms(15); //使能端至少延迟150ns
LCD_E=0; //复位
}
void lcd1602writedata(unsigned char dat) //lcd1602写数据程序
{
LCD_E=0; //使能端为0
LCD_RS=1; //数据命令端为1,代表数据
LCD_RW=0; //读写端为0,代表写入
LCDIO=dat; //输入端输入一个命令字节
delayms(4); //延迟40ns
LCD_E=1;
delayms(15); //使能端至少延迟150ns
LCD_E=0; //复位
}
void lcdinit() //初始化LCD1602
{
lcd1602writecom(0x38);
lcd1602writecom(0x0c);
lcd1602writecom(0x06);
lcd1602writecom(0x01);
lcd1602writecom(0x80);
}
void delayms(unsigned char c) //误差 0us
{
unsigned char a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
#include<intrins.h>
//定义DS1302使用的端口
sbit DSIO=P3^4;
sbit SCLK=P3^6;
sbit CE=P3^5;
//定义LCD使用的端口
sbit LCD_E=P2^7;
sbit LCD_RW=P2^5;
sbit LCD_RS=P2^6;
#define LCDIO P0
unsigned char code ds1302readaddr[7]={0x8B,0x81,0x83,0x85,0x87,0x89,0x8D};//读寄存器地址
unsigned char code ds1302writeaddr[7]={0x8A,0x80,0x82,0x84,0x86,0x88,0x8C};//写寄存器地址
unsigned char Time[7]={0x01,0,0,0,0x14,0x08,0x17};//星期 秒 分 时 日 月 年 //初始时间2017年8月3日00点00分00秒星期四 BCD码表示
void lcddisplay();
void ds1302write(unsigned char addr,unsigned char dat);
unsigned char ds1302read(unsigned char addr);
void ds1302init();
void ds1302readtime();
void lcd1602writecom(unsigned char com);
void lcd1602writedata(unsigned char dat);
void lcdinit();
void delayms(unsigned char c);
void main() //主程序,显示时间
{
lcdinit();//初始化LCD
ds1302init();//初始化ds1302
while(1)
{
ds1302readtime();//读取ds1302的数据
lcddisplay();//lcd显示ds1302的数据
}
}
void lcddisplay()
{
lcd1602writecom(0x80);//在第一行显示
lcd1602writedata('0'+Time[3]/16);
lcd1602writedata('0'+(Time[3]&0x0f)); //时
lcd1602writedata(':');
lcd1602writedata('0'+Time[2]/16);
lcd1602writedata('0'+(Time[2]&0x0f)); //分
lcd1602writedata(':');
lcd1602writedata('0'+Time[1]/16);
lcd1602writedata('0'+(Time[1]&0x0f)); //秒
lcd1602writecom(0xc0);
lcd1602writedata('2');
lcd1602writedata('0');
lcd1602writedata('0'+Time[6]/16); //年十位
lcd1602writedata('0'+(Time[6]&0x0f)); //年个位
lcd1602writedata('-');
lcd1602writedata('0'+Time[5]/16); //月十位
lcd1602writedata('0'+(Time[5]&0x0f)); //月个位
lcd1602writedata('-');
lcd1602writedata('0'+(Time[4]/16)); //日十位
lcd1602writedata('0'+(Time[4]&0x0f)); //日个位
lcd1602writedata('-');
lcd1602writedata('0'+(Time[0]&0x07)); //周
}
//DS1302程序段
//写入地址和数据
void ds1302write(unsigned char addr,unsigned char dat)
{
unsigned char n;
CE=0;
SCLK=0;
CE=1;
for(n=0;n<8;n++) //写入地址码
{
DSIO=addr&0x01;
addr>>=1;
SCLK=1;
SCLK=0;
}
for(n=0;n<8;n++) //写入数据码
{
DSIO=dat&0x01;
dat>>=1;
SCLK=1;
SCLK=0;
}
CE=0;
}
unsigned char ds1302read(unsigned char addr)//读取数据
{
unsigned char n,dat1,dat;
CE=0;
SCLK=0;
CE=1;
for(n=0;n<8;n++)
{
DSIO=addr&0x01;
addr>>=1;
SCLK=1;
SCLK=0;
}
_nop_();
for(n=0;n<8;n++)
{
dat1=DSIO&0x01;
dat1=dat1<<7;
dat=(dat>>1)|(dat1);
SCLK=1;
SCLK=0;
}
CE=0;
_nop_();
SCLK=1;
_nop_();
DSIO=0;
_nop_();
DSIO=1;
_nop_();
return dat;
}
void ds1302init() //初始化DS1302
{
unsigned char n;
ds1302write(0x8E,0x00); //关闭写保护
for(n=0;n<7;n++)
{
ds1302write(ds1302writeaddr[n],Time[n]);
}
ds1302write(0x8E,0x80); //开启写保护
}
void ds1302readtime() //读取时钟信息
{
unsigned char n;
for(n=0;n<7;n++)
{
Time[n]=ds1302read(ds1302readaddr[n]);
}
}
//LCD程序段
void lcd1602writecom(unsigned char com) //lcd1602写命令程序
{
LCD_E=0; //使能端为0
LCD_RS=0; //数据命令端为0,代表命令
LCD_RW=0; //读写端为0,代表写入
LCDIO=com; //输入端输入一个命令字节
delayms(4); //延迟40ns
LCD_E=1;
delayms(15); //使能端至少延迟150ns
LCD_E=0; //复位
}
void lcd1602writedata(unsigned char dat) //lcd1602写数据程序
{
LCD_E=0; //使能端为0
LCD_RS=1; //数据命令端为1,代表数据
LCD_RW=0; //读写端为0,代表写入
LCDIO=dat; //输入端输入一个命令字节
delayms(4); //延迟40ns
LCD_E=1;
delayms(15); //使能端至少延迟150ns
LCD_E=0; //复位
}
void lcdinit() //初始化LCD1602
{
lcd1602writecom(0x38);
lcd1602writecom(0x0c);
lcd1602writecom(0x06);
lcd1602writecom(0x01);
lcd1602writecom(0x80);
}
void delayms(unsigned char c) //误差 0us
{
unsigned char a,b;
for (; c>0; c--)
{
for (b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
你在void ds1302readtime() 函数中加一个延时四秒的函数
能告诉我具体是哪个吗?我真没看出来
LCDIO=dat; //输入端输入一个命令字节
delayms(4); //延迟40ns
LCD_E=1;
delayms(15); //使能端至少延迟150ns
LCD_E=0; //复位
这里可以不用delayms(),加几个 _nop_();就行了,最好能写个1602的查忙程序,看1602的手册有说明。
4秒刷新一次,时间是否连续的,另外4秒刷新一次这个时间是否是稳定的。