huaqinMCU DS1302 实验程序 数码管显示 时钟设置说明
"8 键"为时钟设置、时分切换、保存 "0 键"为加 "4 键"为减
/************************************************************************/
//
//
/************************************************************************/
#include
#define uchar unsigned char
#define uint unsigned int
//===以下 IO 定义请根据您硬件的连接修改===
sbit T_RST=P3^5;//ds1302-5
sbit T_IO=P3^4;//ds1302-6
sbit T_CLK=P3^6;//ds1302-7
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;//累加器 A 51 单片机原理中有介绍
sbit up=P3^1;
sbit down=P3^2;
sbit set=P3^0;
uchar a,b,clock_ss,clock_sg,clock_fs,clock_fg,clock_ms,clock_mg;
int hour,mie,sei;
uchar clk_time[3];
code uchar ledmap[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x40};
//数码管段码
//秒,分,时寄存器初始值
/******************DS1302:写入操作(上升沿)*********************/
void write_byte(uchar da)
{
uchar i;
ACC=da;
for(i=8;i>0;i--)
{
T_IO=ACC0;
T_CLK=0;
T_CLK=1;
ACC=ACC>>1;
}
}
/******************DS1302:读取操作(下降沿)*****************/
uchar read_byte(void)
{
uchar i;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
T_CLK = 1;
T_CLK = 0;
ACC7 = T_IO;
}
return(ACC);
}
/******************DS1302: 写 入 数 据 ( 先 送 地 址 , 再 写 数 据 )
***************************/
void write_1302(uchar addr,uchar da)
{
T_RST=0;
T_CLK=0;
T_RST=1;
write_byte(addr);
//写入地址
//停止工作
//重新工作
write_byte(da);
T_RST=0;
T_CLK=1;
}
/******************DS1302: 读 取 数 据 ( 先 送 地 址 , 再 读 数 据 )
**************************/
uchar read_1302(uchar addr)
{
//停止工作
//重新工作
//写入地址
uchar temp;
T_RST=0;
T_CLK=0;
T_RST=1;
write_byte(addr);
temp=read_byte();
T_RST=0;
T_CLK=1;
return(temp);
//停止工作
}
/***********************延时程序=a*1ms**************************************/
void delay(uchar a)
{
uchar i;
while(a-- !=0)
// led_disp();
for(i=0;i<125;i++);
{
}
}
/***********************显示程序**********************************************/
/* DS1302 秒,分,时寄存器是 BCD 码形式: 用 16 求商和余进行"高 4 位"和"低 4 位"分
离 */
/****************************************************************************/
void led_disp()
{
uchar cant1,cant2;
if(b==0)
{
cant1=0;cant2=0;
clock_ms=clk_time[0]/ 16;
clock_mg=clk_time[0]%16;
clock_fg=clk_time[1]%16;
clock_fs=clk_time[1]/ 16;
mie=clock_fs*10+ clock_fg;
clock_ss=clk_time[2]/ 16;
hour=clock_ss*10+ clock_sg; //用 16 求商和余进行"高 4 位"和"低 4 位"分离
clock_sg=clk_time[2]%16;//BCD*to*10
}
if(b==1)
{
cant1++;
cant2=0;
clock_ss=hour/ 10;
clock_sg=hour%10;
clock_fs=mie/ 10;
clock_fg=mie%10;
clock_ms=sei/10;
clock_mg=sei%10;
if(b==2)
cant1=0;
cant2++;
clock_ss=hour/ 10;
clock_sg=hour%10;
clock_fs=mie/ 10;
clock_fg=mie%10;
clock_ms=sei/10;
clock_mg=sei%10;
}
{
}
if(cant1<=3)
{
P2=0;
P0=ledmap[clock_ss];
delay(1);
P0=0X00;
P2=1;
P0=ledmap[clock_sg];//时个位
delay(1);P0=0X00;}
if(cant1==5)
cant1=0;
P2=2;
P0=ledmap[10];//显示"-"数组里的 0x40
delay(1);
P0=0X00;
if(cant2<=3)
{
P2=3;
P0=ledmap[clock_fs];//分十位
delay(1);
P0=0X00;
P2=4;
P0=ledmap[clock_fg];//时个位
delay(1);P0=0X00;
}
if(cant2==5)
cant2=0;
P2=5;
P0=ledmap[10];//显示"-"数组里的 0x40
delay(1);
P0=0X00;
P2=6;
P0=ledmap[clock_ms];//秒十位
delay(1);
P0=0X00;
P2=7;
P0=ledmap[clock_mg];
delay(1);P0=0X00;
}
/***********************
按
键
延
时
程
序
=a*1ms**************************************/
void delayAJ(uchar a)
{
uchar i;
while(a--)
{
for(i=0;i<125;i++);
{
led_disp();
}
}
}
void key()
{
uchar clock_s1, clock_s2, clock_f1, clock_f2;
delayAJ(5);
if(set==0)
{
delayAJ(5);//消抖
if(set==0)
{
b++;
delayAJ(5);
}
while(!set)
{
delayAJ(5);
}
}
if(b!=0)//时分设定
{
if(up==0)
{
delayAJ(5);//消抖
if(up==0)
{
if(b==1)
{
hour++;
if(hour>=24)
{
hour=0;
}
delayAJ(10);
}
if(b==2)
{
mie++;
if(mie>=60)
{
mie=0;
}
delayAJ(10);
}//以上时钟+设定
}
}
if(down==0)
{
delayAJ(5);//消抖
if(down==0)
{
delayAJ(5);
if(b==1)
{
hour--;
if(hour<0)
{
hour=23;
}
delayAJ(10);
}
if(b==2)
{
mie--;
if(mie<0)
{
mie=59;
}
delayAJ(10);
}//以上时钟-设定
}
}
//********************以下是转 BCD 码的程序 DS1302 认 BCD 码
clock_s1=hour/10;
clock_s2=hour%10;
clock_s1=clock_s1&0xff;
clock_s2=clock_s2&0xff;
clock_s1<<=4;
clock_s1=clock_s1|clock_s2;//
10to16
clock_f1=mie/10;
clock_f2=mie%10;
clock_f1=clock_f1&0xff; //全 1 出 1 与运算
clock_f2=clock_f2&0xff;
clock_f1<<=4;
clock_f1=clock_f1|clock_f2;//
10to16
//*******************************************转 BCD 码的程序 DS1302 认 BCD 码
}
if(b==3)
{
b=0;
write_1302(0x8e,0x00); //WP=0 写操作
write_1302(0x80,0x01);//0x80 是写秒数据此处写进"01"秒
write_1302(0x82,clock_f1);//0x82 是写分数据
write_1302(0x84,clock_s1);//0x84 是写时数据
write_1302(0x8e,0x80); //WP=1 写保护
delay(255);
}
}
/************************主程序**********************************************/
void main(void)
{
temp=0x80;
uchar
uchar i;
b=0;
P3=0xff;
while(1)
{
temp=0x81;//读的初始地址
for(i=0;i<3;i++)//分别把秒分时数据读出分 3 次读好一次地址加 2" temp+=2;"
{
clk_time[i]=read_1302(temp);
temp+=2;
}
key();//键盘扫描
}
}