📄 ds1302.c
字号:
#include <at89x51.h>
sbit T_CLK = P2^5; //实时时钟时钟线引脚
sbit T_IO = P2^6; //实时时钟数据线引脚
sbit T_RST = P2^7; //实时时钟复位线引脚
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit rs=P1^2;
sbit rw=P1^3;
sbit e=P1^4;
sbit set=P3^4; //设置
sbit add=P3^5; //加
sbit dec=P3^6; //减
void show();
void keyscan();
void inishow();
unsigned char hex_bcd(unsigned char hex_data);
unsigned char bcd_hex(unsigned char bcd_data);
unsigned char code tab[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
unsigned char code buf[7]={0x00,0x00,0x0c,0x0d,0x0a,0x01,0x0a};//初始时间格式为: 秒 分 时 日 月 星期 年
unsigned char data ucCurtime[7];
unsigned char a,yearh,yearl,monh,monl,dah,dal,hoh,hol,wekl,mih,mil,seh,sel;
unsigned char Addr;
//延时
void delay()
{
unsigned char y;
for(y=0;y<75;y++);
}
/********************************************************************
* 名称: InputByte
* 功能: 向1302写数据
***********************************************************************/
void InputByte(unsigned char ucDa)
{
unsigned char i;
ACC = ucDa;
for(i=8; i>0; i--)
{
T_IO = ACC0; //相当于汇编中的 RRC
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
* 名称: OutputByte
* 功能: 从1302读数据
***********************************************************************/
unsigned char OutputByte(void)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
* 名称: W1302
* 功能: 向1302写数据
***********************************************************************/
void W1302(unsigned char ucAddr, unsigned char ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
InputByte(ucAddr); // 地址,命令
InputByte(ucDa); // 写1Byte数据
T_CLK = 1;
T_RST =0;
}
/********************************************************************
* 名称: R1302
* 功能: 从1302读数据
***********************************************************************/
unsigned char R1302(unsigned char ucAddr)
{
unsigned char ucDa,a;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
InputByte(ucAddr); // 地址,命令
a = OutputByte(); // 读1Byte数据
ucDa=bcd_hex(a);
T_CLK = 1;
T_RST =0;
return(ucDa);
}
/********************************************************************
* 名称: Set1302
* 功能: 设置初始时间
* 调用: W1302()
* 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void set1302(unsigned char *pSecDa)
{
unsigned char i;
unsigned char ucAddr = 0x80;
W1302(0x8e,0x00); // 控制命令,WP=0,写操作?
for(i=0;i<7;i++)
{
W1302(ucAddr,hex_bcd(*pSecDa)); // 秒 分 时 日 月 星期 年
pSecDa++;
ucAddr +=2;
}
W1302(0x8e,0x80); // 控制命令,WP=1,写保护?
}
/********************************************************************
* 名称: write_com
* 功能: 写命令到1602
* 返回值: 无
***********************************************************************/
void write_com(unsigned char j)//写命令
{
e=0;
rs=0;
rw=0;
e=1;
P0=j;
e=0;
delay();
}
/********************************************************************
* 名称: write_dat
* 功能: 写数据到1602
* 返回值: 无
***********************************************************************/
void write_dat(unsigned char dat)//写数据
{
e=0;
rs=1;
rw=0;
e=1;
P0=dat;
e=0;
delay();
}
/********************************************************************
* 名称: init
* 功能: 初始化1602
* 返回值: 无
***********************************************************************/
void init()//初始化lcd
{
write_com(0x01);
write_com(0x38);
write_com(0x38);
write_com(0x0e);
write_com(0x06);
write_com(0x0c);
}
/********************************************************************
* 名称: write1602
* 功能: 向1602指定地址写数据
* 返回值: 无
***********************************************************************/
void write1602(unsigned char add,unsigned char dat)//写入显示数据
{
write_com(add);
write_dat(dat);
}
/********************************************************************
* 名称: hex_bcd
* 功能: 将16进制转成bcd码
* 返回值: bcd_data
***********************************************************************/
unsigned char hex_bcd(unsigned char hex_data)
{
unsigned char temp=0,bcd_data=0;
temp=hex_data%100;
bcd_data=bcd_data|temp/10<<4;
bcd_data=bcd_data|temp%10;
return bcd_data;
}
/********************************************************************
* 名称: bcd_hex
* 功能: 将bcd码转成16进制
* 返回值: temp
***********************************************************************/
unsigned char bcd_hex(unsigned char bcd_data)
{
unsigned char temp=0;
temp=((bcd_data>>4)*10)+(bcd_data&0x0f);
return temp;
}
/********************************************************************
* 名称: keyscan
* 功能: 键盘扫描程序
* 返回值: 无
***********************************************************************/
void keyscan()
{
unsigned char keynum;
if(set==0);
delay();
if(set==0)
{
while(!set);
delay();
while(!set);
keynum++;
if(keynum==1)
{
TR0=0;
write_com(0x0f);
write_com(0xce);
}
if(keynum==2)
{
write_com(0xc8);
}
if(keynum==3)
{
write_com(0xc5);
}
if(keynum==4)
{
write_com(0x8b);
}
if(keynum==5)
{
write_com(0x88);
}
if(keynum==6)
{
write_com(0x85);
}
if(keynum==7)
{
keynum=0;
write_com(0x0c);
set1302(ucCurtime);
TR0=1;
}
}
if(keynum!=0)
{
if(add==0)
delay();
if(add==0)
{
while(!add);
delay();
while(!add);
if(keynum==1)
{
ucCurtime[5]++;
if(ucCurtime[5]>7)
ucCurtime[5]=1;
write_com(0xce);
write_dat(tab[ucCurtime[5]%10]);
write_com(0xce);
}
if(keynum==2)
{
ucCurtime[1]++;
if(ucCurtime[1]>59)
ucCurtime[1]=0;
write_com(0xc9);
write_dat(tab[ucCurtime[1]%10]);
write_com(0xc8);
write_dat(tab[ucCurtime[1]/10]);
write_com(0xc8);
}
if(keynum==3)
{
ucCurtime[2]++;
if(ucCurtime[2]>23)
ucCurtime[2]=0;
write_com(0xc6);
write_dat(tab[ucCurtime[2]%10]);
write_com(0xc5);
write_dat(tab[ucCurtime[2]/10]);
write_com(0xc5);
}
if(keynum==4)
{
ucCurtime[3]++;
if(ucCurtime[4]==1||ucCurtime[4]==3||ucCurtime[4]==5||ucCurtime[4]==7||ucCurtime[4]==8||ucCurtime[4]==10||ucCurtime[4]==12)
{
if(ucCurtime[3]>31)
ucCurtime[3]=01;
}
if(ucCurtime[4]==4||ucCurtime[4]==6||ucCurtime[4]==9||ucCurtime[4]==11)
{
if(ucCurtime[3]>30)
ucCurtime[3]=01;
}
if(ucCurtime[4]==2)
{
if(((ucCurtime[6]+2000)%4==0&&(ucCurtime[6]+2000)%100!=0)||((ucCurtime[6]+2000)%400==0))
{
if(ucCurtime[3]>29)
ucCurtime[3]=01;
}
else
{
if(ucCurtime[3]>28)
ucCurtime[3]=01;
}
}
write_com(0x8c);
write_dat(tab[ucCurtime[3]%10]);
write_com(0x8b);
write_dat(tab[ucCurtime[3]/10]);
write_com(0x8b);
}
if(keynum==5)
{
ucCurtime[4]++;
if(ucCurtime[4]>12)
ucCurtime[4]=01;
write_com(0x89);
write_dat(tab[ucCurtime[4]%10]);
write_com(0x88);
write_dat(tab[ucCurtime[4]/10]);
write_com(0x88);
}
if(keynum==6)
{
ucCurtime[6]++;
if(ucCurtime[6]==100)
ucCurtime[6]=0;
write_com(0x86);
write_dat(tab[ucCurtime[6]%10]);
write_com(0x85);
write_dat(tab[ucCurtime[6]/10]);
write_com(0x85);
}
}
if(dec==0)
{
while(!dec);
delay();
while(!dec);
if(keynum==1)
{
if(ucCurtime[5]==1)
ucCurtime[5]=0x08;
ucCurtime[5]--;
write_com(0xce);
write_dat(tab[ucCurtime[5]%10]);
write_com(0xce);
}
if(keynum==2)
{
if(ucCurtime[1]==0)
ucCurtime[1]=60;
ucCurtime[1]--;
write_com(0xc9);
write_dat(tab[ucCurtime[1]%10]);
write_com(0xc8);
write_dat(tab[ucCurtime[1]/10]);
write_com(0xc8);
}
if(keynum==3)
{
if(ucCurtime[2]==0)
ucCurtime[2]=24;
ucCurtime[2]--;
write_com(0xc6);
write_dat(tab[ucCurtime[2]%10]);
write_com(0xc5);
write_dat(tab[ucCurtime[2]/10]);
write_com(0xc5);
}
if(keynum==4)
{
if(ucCurtime[4]==1||ucCurtime[4]==3||ucCurtime[4]==5||ucCurtime[4]==7||ucCurtime[4]==8||ucCurtime[4]==10||ucCurtime[4]==12)
{
if(ucCurtime[3]==01)
ucCurtime[3]=32;
}
if(ucCurtime[4]==4||ucCurtime[4]==6||ucCurtime[4]==9||ucCurtime[4]==11)
{
if(ucCurtime[3]==01)
ucCurtime[3]=31;
}
if(ucCurtime[4]==2)
{
if(((ucCurtime[6]+2000)%4==0&&(ucCurtime[6]+2000)%100!=0)||((ucCurtime[6]+2000)%400==0))
{
if(ucCurtime[3]==01)
ucCurtime[3]=30;
}
else
{
if(ucCurtime[3]==01)
ucCurtime[3]=29;
}
}
ucCurtime[3]--;
write_com(0x8c);
write_dat(tab[ucCurtime[3]%10]);
write_com(0x8b);
write_dat(tab[ucCurtime[3]/10]);
write_com(0x8b);
}
if(keynum==5)
{
if(ucCurtime[4]==1)
ucCurtime[4]=13;
ucCurtime[4]--;
write_com(0x89);
write_dat(tab[ucCurtime[4]%10]);
write_com(0x88);
write_dat(tab[ucCurtime[4]/10]);
write_com(0x88);
}
if(keynum==6)
{
if(ucCurtime[6]==0)
ucCurtime[6]=100;
ucCurtime[6]--;
write_com(0x86);
write_dat(tab[ucCurtime[6]%10]);
write_com(0x85);
write_dat(tab[ucCurtime[6]/10]);
write_com(0x85);
}
}
}
}
void show()
{
Addr = 0x81;
for (a=0;a<7;a++)
{
ucCurtime[a]=R1302(Addr);//格式为: 秒 分 时 日 月 星期 年
Addr += 2;
}
yearh=ucCurtime[6]/10;
yearl=ucCurtime[6]%10;
monh=ucCurtime[4]/10;
monl=ucCurtime[4]%10;
dah=ucCurtime[3]/10;
dal=ucCurtime[3]%10;
hoh=ucCurtime[2]/10;
hol=ucCurtime[2]%10;
mih=ucCurtime[1]/10;
mil=ucCurtime[1]%10;
seh=ucCurtime[0]/10;
sel=ucCurtime[0]%10;
wekl=ucCurtime[5]%10;
write1602(0x85,tab[yearh]);
write1602(0x86,tab[yearl]);
write1602(0x88,tab[monh]);
write1602(0x89,tab[monl]);
write1602(0x8b,tab[dah]);
write1602(0x8c,tab[dal]);
write1602(0xc5,tab[hoh]);
write1602(0xc6,tab[hol]);
write1602(0xc8,tab[mih]);
write1602(0xc9,tab[mil]);
write1602(0xcb,tab[seh]);
write1602(0xcc,tab[sel]);
write1602(0x8d,0x57);
write1602(0x8e,0x65);
write1602(0xce,tab[wekl]);
}
void inishow()
{
write1602(0x80,0x44);
write1602(0x81,0x61);
write1602(0x82,0x74);
write1602(0x83,0x65);
write1602(0x84,0x3a);//显示date:
write1602(0x87,0x2d);//显示年
write1602(0x8a,0x2d);//显示月
write1602(0xc0,0x54);
write1602(0xc1,0x69);
write1602(0xc2,0x6d);
write1602(0xc3,0x65);
write1602(0xc4,0x3a);//显示time:
write1602(0xc7,0x3a);//显示小时
write1602(0xca,0x3a);//显示小时
write1602(0x8f,0x6b);//显示wek:
}
/********************************************************************
* 名称: main
* 功能: 主程序
* 返回值: 无
***********************************************************************/
void main()
{
init();//LCD初始化
inishow();
set1302(buf);
TMOD=0X01;
TH0=0XDC;
TL0=0X00;
EA=1;
ET0=1;
TR0=1;
while(1)
{
keyscan();
}
}
void timer0() interrupt 1
{
TH0=0XDC;
show();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -