📄 ds1302.txt
字号:
用51控制DS1302的时钟程序
用51控制DS1302的时钟程序,通过数码管显示出来,具体数码管接口可能不一样,改一下就好了。这里采用6个数码管显示时钟,有两个数码管是倒过来放的,用四个数码管显示小数点
先放ds1302的头文件
//以下是DS1302的头文件程序
sbit T_CLK=P1^2;
sbit T_IO =P1^1;
sbit T_RST=P1^0;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
//********DS1302读写程序***************
/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
***********************************************************************/
void RTInputByte(unsigned char d)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; //相当于汇编中的 RRC
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
设 计:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
unsigned char RTOutputByte(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);
}
/********************************************************************
函 数 名:Write1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
***********************************************************************/
void Write1302(unsigned char ucAddr, unsigned char ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); // 地址,命令
RTInputByte(ucDa); // 写1Byte数据
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 数 名:Read1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
***********************************************************************/
unsigned char Read1302(unsigned char ucAddr)
{
unsigned char ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); // 地址,命令
ucData = RTOutputByte(); // 读1Byte数据
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 数 名:Set1302()
功 能:设置初始时间
说 明:先写地址,后读命令/数据(寄存器多字节方式)
调 用:Write1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
void Set1302(unsigned char *pClock)
{
unsigned char i;
unsigned char ucAddr = 0x80;
Write1302(0x8e,0x00); // 控制命令,WP=0,写操作
for(i =7; i>0; i--)
{
Write1302(ucAddr,*pClock); // 秒 分 时 日 月 星期年
pClock++;
ucAddr +=2;
}
Write1302(0x8e,0x80); // 控制命令,WP=1,写保护
}
//以下是DS1302的主程序
#include <REGX51.H>
#include "ds1302.h"
#define leddata P0
#define sec 0x80
#define min 0x82
#define hou 0x84
#define read 0x01
sbit MODE=P3^4;
sbit SET=P3^5;
sbit UP=P3^6;
sbit DOWN=P3^7;
sbit led0=P2^0;
sbit led1=P2^3;
sbit led2=P2^7;
sbit led3=P2^4;
sbit led4=P2^6;
sbit led5=P2^5;
void delays(unsigned char);
void display(void);
void Scan_Key(void);
void id_case1_key();
void Set_id(unsigned char ,unsigned char);
unsigned char hour,minute,second,id=0,timecount,re_disp=0,dotglint=0;
bit flag;
unsigned char code tab[]={0x48,0xEE,0x54,0xC4,0xE2,0xC1,0x41,0xEC,0x40,0xC0,0x60};
unsigned char inittime[7]={0x00,0x00,0x12,0x16,0x11,0x06,0x04};
// 秒 分钟 小时 日 月 年 星期
void t0(void) interrupt 1 using 0
{
TH0=(65535-50000)/256; //50ms定时
TL0=(65535-50000)%256;
timecount++;re_disp++;
if(timecount>9)
{
timecount=0;
flag=~flag;
}
if(re_disp>200){re_disp=0;if(id)id=0;}
}
void delays(unsigned char k)
{
unsigned char i,j;
for(i=0;i<k;i++)
for(j=0;j<100;j++);
}
void display(void)
{
if(dotglint==2){leddata=0xff;}
else
{
if(flag&hour) //用flag判断,用于在调时间时闪烁
{
led0=0;leddata=0xff;delays(10);led0=1;
led1=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led1=1;
}
else
{
leddata=tab[Read1302(hou+1)/16];led0=0;delays(10);led0=1;
if(dotglint==0){leddata=tab[Read1302(hou+1)%16]&0xbf;}
if(dotglint==1){leddata=tab[Read1302(hou+1)%16]&~((unsigned char)~flag<<6);}
if(dotglint==2){leddata=0xff;}
led1=0;delays(10);led1=1;
}
if(flag&minute)
{
led2=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led2=1;
led3=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led3=1;
}
else
{
if(dotglint==0){leddata=tab[Read1302(min+1)/16]&0xbf;}
if(dotglint==1){leddata=tab[Read1302(min+1)/16]&~((unsigned char)~flag<<6);}
if(dotglint==2){leddata=0xff;}
led2=0;delays(10);led2=1;
if(dotglint==0){leddata=tab[Read1302(min+1)%16]&0xbf;}
if(dotglint==1){leddata=tab[Read1302(min+1)%16]&~((unsigned char)~flag<<6);}
if(dotglint==2){leddata=0xff;}
led3=0;delays(10);led3=1;
}
if(flag&second)
{
led4=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led4=1;
led5=0;leddata=0xff;delays(10);led5=1;
}
else
{
if(dotglint==0){leddata=tab[Read1302(sec+1)/16]&0xbf;}
if(dotglint==1){leddata=tab[Read1302(sec+1)/16]&~((unsigned char)~flag<<6);}
if(dotglint==2){leddata=0xff;}
led4=0;delays(10);led4=1;
leddata=tab[Read1302(sec+1)%16];led5=0;delays(10);led5=1;
}
}
}
void Scan_Key(void)
{
display();
if(!MODE){while(!MODE)display();{dotglint++;if(dotglint==3){dotglint=0;}}}
if(!SET)
{
while(!SET)display();
re_disp=0;
id++;if(id>3)id=0;
}
if(id==0){hour=0;minute=0;second=0;}
if(id==1){hour=1;id_case1_key();}
if(id==2){hour=0;minute=1;id_case1_key();}
if(id==3){minute=0;second=1;id_case1_key();}
}
void id_case1_key(void)
{
display();
if (!DOWN) //减少
{
while(!DOWN)display();
re_disp=0;
Set_id(id,0);
}
if (!UP) //增加
{
while(!UP)display();
re_disp=0;
Set_id(id,1);
}
}
//根据选择调整相应项目并写入DS1302
void Set_id(unsigned char sel,unsigned char sel_1)
{
signed char max,mini,address,item;
if(sel==1) {address=hou; max=23;mini=0;} //小时
if(sel==2) {address=min; max=59;mini=0;} //分钟
if(sel==3) {address=sec; max=0;mini=0;} //秒
item=Read1302(address+1)/16*10+Read1302(address+1)%16;
if (sel_1==0) item--; else item++;
if(item>max) item=mini;
if(item<mini) item=max;
Write1302(0x8e,0x00);//允许写操作
Write1302(address,item/10*16+item%10);
Write1302(0x8e,0x80);//写保护,禁止写操作
}
void main()
{
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
Write1302(0x90,0xa5);//打开充电二级管 一个二级管串联一个2K电阻
Write1302(0x8e,0x80);//写保护,禁止写操作
if(!UP&!DOWN)Set1302(inittime);
while(1)
{
Scan_Key();
}
}
思想有多远,我们就能走多远!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -