基于51单片机和ds1302的可调时钟

雨啸青锋 发布于 2022-01-23 501 次阅读


单片机采用stc89c52rc,基于51实验普中板

按钮4个,

在显示时间状态下,按下k1进入设置,按下k4,时间星期日期切换

进入设置后,K1退出设置不保存;k2切换设置位,k3设置,按一下加1;k4保存设置并且退出

以下是按钮原理图

通过ds1302时钟芯片来运行时钟

 

数码管显示由74HC245芯片驱动

软件设计:

ds1302的读取

/***
函数名称: ds_1302_write
功能:数据字节写入
输入:addr地址 date数据
****/
void ds_1302_write(u8 addr,u8 date)//写入
{ 
u8 i = 0;
CE = 0;_nop_();
sCLK = 0;_nop_();
CE = 1;_nop_();

for (i = 0;i<8;i++)
{
I_O = addr&0x01;
addr>>=1;
sCLK = 1;
_nop_();
sCLK = 0;
_nop_();
}

for (i = 0;i<8;i++)
{
I_O = date&0x01;
date>>=1;
sCLK = 1;
_nop_();
sCLK = 0;
_nop_();
}

}

/***
函数名称: ds_1302_read
功能:数据字节读取
输入:addr 地址
输出:value 数据
****/
u8 ds_1302_read(u8 addr)//读出
{
u8 i = 0;
u8 temp = 0;
u8 value = 0;
CE = 0;_nop_();
sCLK = 0;_nop_();
CE = 1;_nop_();


for (i = 0;i<8;i++)
{
I_O = addr&0x01;
addr>>=1;
sCLK = 1;
_nop_();
sCLK = 0;
_nop_();
}

for(i = 0;i<8;i++)
{

temp = I_O;
value = (temp<<7)|(value>>1);
_nop_();
sCLK = 1;
_nop_();
sCLK = 0;
_nop_();
}
CE = 0;
_nop_();
sCLK = 1;
_nop_();
I_O = 0;
_nop_();
I_O = 1;
_nop_();
//value = BCD_ten(value);
return value; 
}

数码管显示的驱动

#include "smg.h"

//共阴极数码管显示 0~F 的段码数据
u8 smg_code[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

#define SMG_A_DP_PORT P0


void smg_d(u8 i){//位置

switch(i)
{
case 0: LSC=1;LSB=1;LSA=1;break;
case 1: LSC=1;LSB=1;LSA=0;break;
case 2: LSC=1;LSB=0;LSA=1;break;
case 3: LSC=1;LSB=0;LSA=0;break;
case 4: LSC=0;LSB=1;LSA=1;break;
case 5: LSC=0;LSB=1;LSA=0;break;
case 6: LSC=0;LSB=0;LSA=1;break;
case 7: LSC=0;LSB=0;LSA=0;break;
}

}

/***
* 函 数 名 : smg_
* 函数功能:数码管显示
* 输入 位数,显示数字
***/
void smg_(u8 i,u8 x){//位数,显示数字
smg_d(i);
SMG_A_DP_PORT = smg_code[x];
delay_10us(100);
SMG_A_DP_PORT =0x00;
}

时间显示

if (menu_set.set == 0){//显示时间
if (menu_set.menu == 0)
{
t = gREAD_RTC[4];//时1
t = ds_1302_read(t);
smg_(0,t/16);smg_(1,t%16);

t = gREAD_RTC[5];//分2
t = ds_1302_read(t);
smg_(3,t/16);smg_(4,t%16);

t = gREAD_RTC[6];//秒3
t = ds_1302_read(t);
smg_(6,t/16);smg_(7,t%16);
}
if (menu_set.menu == 1)
{
t = gREAD_RTC[2]; //周4
t = ds_1302_read(t);
smg_(0,t/16);smg_(1,t%16);
}
if (menu_set.menu == 2)
{
smg_(0,2);smg_(1,0);
t = gREAD_RTC[0]; //年5
t = ds_1302_read(t);
smg_(2,t/16);smg_(3,t%16);

t = gREAD_RTC[1]; //月6
t = ds_1302_read(t);
smg_(4,t/16);smg_(5,t%16);

t = gREAD_RTC[3]; //日7
t = ds_1302_read(t);
smg_(6,t/16);smg_(7,t%16);
}

时间设置时候的闪烁

if (menu_set.set == 1)//设置位
{
//显示时分秒
if (menu_set.set_bit == 6)//设置秒
{
t = time_date[4];//时
smg_(0,t/10);
smg_(1,t%10);

t = time_date[5];//分
smg_(3,t/10);
smg_(4,t%10);

t = time_date[6];//秒
smg_(6,t/10);
if (menu_set.LED_flashing == 1) smg_(7,t%10); 
}

void time0_init(void)//定时器0配置
{
TMOD|=0X01;//定时器 0 模式,工作方式 1
TH0=0XFC; 
TL0=0X18;
ET0 = 1;
TR0=1;;//打开定时器
EA=1;

}
void time0() interrupt 1
{
static u16 i;
TH0=0XFC;
TL0=0X18;
i++;
if(i >= 500)
{
i = 0;
menu_set.LED_flashing =!menu_set.LED_flashing;
}
}

完整代码下载:https://gitee.com/yxqf/clock_51

嘿,大家好,小名尧尧,网名雨啸青锋,00后的小站主,某校高中生
最后更新于 2022-01-23