📄 ds1302.c
字号:
#include<at89x51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
/***************************变量定义*******************************/
uchar second,minute,hour,date,month,year,day;//定义时间变量
uchar inittime[7]={0x55,0x57,0x10,0x19,0x02,0x04,0x09}; //初始化后设置为:06年3月29日星期3 19点10分0秒
uchar readad[2];
/**************************端口定义*****************************/
sbit ds1302_RST = P3^0;
sbit ds1302_SCLK = P3^1;
sbit ds1302_IO = P3^2;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_E=P2^2;
/**************************函数声明******************************/
void delay(uchar count);
void ds1302_init();
void RTInputByte(uchar d);
uchar RTOutputByte(void);
void W1302(uchar ucAddr, uchar ucDa);
uchar R1302(uchar ucAddr);
void Set1302(uchar *);
void updatatime(void);
void delayms(uint count);
//void LCD_wrn(unsigned char word[]);
void LCD_WC(uchar com);
void LCD_WD(uchar date);
void LCD_init();
void LCD1602(uchar i,uchar j,uchar k);
void main()
{
uchar i;
uchar time[] = "Time:";
uchar date1[] = "Date:";
LCD_init();
ds1302_init();
for(i=0;i<5;i++)
{
LCD1602(1,i,time[i]);
}
for(i=0;i<4;i++)
{
LCD1602(2,i,CH[i]);
}
while(1)
{
updatatime();
}
}
/**************************延时子程序******************************/
void delay(uchar count)
{
uchar i,j;
for(i=0;i<count;i++)
for(j=0;j<20;j++);
}
/*
void ds1302send(uchar com,uchar dat)
{ uchar i;
RST = 0;
SCLK = 0;
RST = 1;
for(i=0;i<8;i++)
{ com = com >> 1; //先发送R/W位
IO = CY;
SCLK = 1;
SCLK = 0;
}
for(i=0;i<8;i++)
{ dat = dat >> 1; //低位先发送
IO = CY;
SCLK = 1;
SCLK = 0;
}
RST = 0;
}
uchar ds1302read(uchar com)
{ uchar i;
uchar dat;
RST = 0;
SCLK = 0;
RST = 1;
for(i=0;i<8;i++)
{ com = com >> 1; //先发送R/W位
IO = CY;
SCLK = 1;
SCLK = 0;
}
delay(1); //Tcdd延时时间和下面的for基本一样0.000082S,但下面的就不可以,会出现每2S时间才变化一次
//for(i=0;i<1;i++)
//for(j=0;j<25;j++);
for(i=0;i<8;i++)
{ dat = dat|IO;
dat =_cror_(dat,1); //低位先接收
SCLK = 1;
SCLK = 0;
}
RST = 0;
return dat;
}
*/
void ds1302_init()
{
ds1302_RST = 0;
ds1302_SCLK = 0;
ds1302_IO = 0;
Set1302(inittime);
/* ds1302send(0x8e,0x00);//打开写保护
ds1302send(0x80,0x58);//启动时钟,并设置秒
ds1302send(0x82,0x59);//设置分钟
ds1302send(0x84,0x23);//设置小时
ds1302send(0x86,0x31);//设置日期
ds1302send(0x88,0x12);//设置月份
ds1302send(0x8a,0x04);//设置星期
ds1302send(0x8c,0x09);//设置年份
ds1302send(0x90,0xa5);//启动充电器
ds1302send(0x8e,0x80);//写保护/
*/
}
void updatatime(void)
{
uchar i=5;
//uchar i=4;
year=R1302(0x8d); //读取年
LCD1602(2,i,year /16 +0x30);
LCD1602(2,i+1,year %16 +0x30);
LCD1602(2,i+2,'-');
month=R1302(0x89); //读取月份
LCD1602(2,i+3,month /16 +0x30);
LCD1602(2,i+4,month %16 +0x30);
LCD1602(2,i+5,'-');
date=R1302(0x87); //读取日期
LCD1602(2,i+6,date /16 +0x30);
LCD1602(2,i+7,date %16 +0x30);
day=R1302(0x8b);
lcd1602(2,i+9,day /16 +'0');
LCD1602(2,i+9,'W'); //读取星期
LCD1602(2,i+10,day %16 +0x30);
hour=R1302(0x85); //读取小时
LCD1602(1,i,hour /16 +0x30);
LCD1602(1,i+1,hour %16 +0x30);
LCD1602(1,i+2,':');
minute=R1302(0x83); //读取分钟
LCD1602(1,i+3,minute /16 +0x30);
LCD1602(1,i+4,minute %16 +0x30);
LCD1602(1,i+5,':');
second=R1302(0x81); //读取秒
LCD1602(1,i+6,second /16 +0x30);
LCD1602(1,i+7,second %16 +0x30);
}
/****************LCD1602驱动**************************/
void delayms(uint count)
{
uint i,j;
for(i=0;i<count;i++)
for(j=0;j<110;j++);
}
void LCD_WC(uchar com)
{
LCD_RS=0;
P0=com;
LCD_RW=0;
delayms(1);
LCD_E=1;
delayms(1);
LCD_E=0;
}
void LCD_WD(uchar date)
{
LCD_RS=1;
P0=date;
LCD_RW=0;
delayms(1);
LCD_E=1;
delayms(1);
LCD_E=0;
}
void LCD_init()
{
delayms(1);
LCD_WC(0x38);
LCD_WC(0x0c);
}
/*
void LCD_wrn(unsigned char word[])
{
unsigned char i;
for(i=0;i<11;i++)
{
LCD_WD(word[i]);
}
}
*/
void LCD1602(uchar i,uchar j,uchar k)
{
if(i==1)
{
LCD_WC(0x80+j);
}
else
{
LCD_WC(0x80+0x40+j);
}
LCD_WD(k);
}
//********DS1302读写程序***************//
/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
***********************************************************************/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
ds1302_IO = ACC0; /*相当于汇编中的 RRC */
ds1302_SCLK = 1;
ds1302_SCLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = ds1302_IO;
ds1302_SCLK = 1;
ds1302_SCLK = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:W1302()
功 能:往DS1302写入数据
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
ds1302_RST = 0;
ds1302_SCLK = 0;
ds1302_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
RTInputByte(ucDa); /* 写1Byte数据*/
ds1302_SCLK = 1;
ds1302_RST = 0;
}
/********************************************************************
函 数 名:R1302()
功 能:读取DS1302某地址的数据
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
ds1302_RST = 0;
ds1302_SCLK = 0;
ds1302_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
ds1302_SCLK = 1;
ds1302_RST = 0;
return(ucData);
}
/********************************************************************
函 数 名:Set1302()
功 能:设置初始时间
***********************************************************************/
void Set1302(uchar *pClock)
{
uchar i;
uchar ucAddr = 0x80;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/
for(i =7; i>0; i--)
{
W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(0x8e,0x80); /* 控制命令,WP=1,写保护*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -