作品采用STC15W1K16S单片机和DS1302设计,配合B站上传的视频更佳。
B站搜索基于DS1302的数字时钟设计(UP凌净清河)即可查到相关视频(预计2018年6月30日下午会审核完毕)。
主要亮点:
1.时间按位设置
2.周数自动计算
3.对输入的日期有严格的合法性判断
4.数码管单个位闪烁效果
次要亮点:
1.较少的单片机IO口占用
2.38译码器转24线译码使用
请注意!为防止低成本盗用(虽然写的不怎么样),展示出的代码删去部分函数(和语句)
/*##############################################################################################
设计名称:基于DS1302的数字时钟
设计者:清河
平台:STC15W1K16S
硬件部分
数码管显示:位选使用74HC138改为2-4线译码、段选使用74HC573提高带载能力
74HC595静态显示:使用74HC595驱动一位共阴极数码管静态显示当前星期
独立按键:共4个,用于进行各项调整
DS1302:配电池,实现断电走时
LED指示灯:指示当前所处状态和闹钟开启与否
蜂鸣器:使用5V有源蜂鸣器,提供闹钟功能
软件部分
使用定时器0实现对DS1302数据的定时读取,间隔500ms,以便更新当前的显示值,读取到的值以全局变量形式储存
可以考虑使用定时器1实现数码管中间秒指示的闪烁
##############################################################################################*/
#include
#include
sbit SCLK=P1^6;
sbit RST=P5^4;
sbit DSIO=P1^7;
sbit SER=P1^2;
sbit RCLK=P1^3;
sbit SRCLK=P1^4;
sbit S1=P1^0;
sbit S2=P1^1;
sbit bell=P3^7;
sbit SET=P3^6;
sbit UP=P3^5;
sbit DOWN=P3^4;
sbit SHOW=P3^3;
sbit setled=P3^1;
sbit clkled=P3^0;
unsigned char code smgduan[11]={0x3f,0x0a,0x57,0x4f,0x6a,0x6d,0x7d,0x0b,0x7f,0x6f,0x00};
unsigned char code smgduan_dp[12]={0xbf,0x8a,0xd7,0xcf,0xea,0xed,0xfd,0x8b,0xff,0xef,0x00,0x80};
unsigned char code hcwei[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};
unsigned char code READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
unsigned char code WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
unsigned char TIME[7]={0,0x34,0x19,0x17,0x06,0x07,0x18};
unsigned int time_trans[7]={0,0,0,0,0,0,0};
unsigned char display_time[4]={0,0,0,0};
unsigned char display_monthday[4]={1,1,1,1};
unsigned char display_year[4]={2,2,2,2};
unsigned char display_second[4]={0,0,9,9};
unsigned char display_week=0;
unsigned char clock[4]={0,8,3,0};
unsigned char set_time[4]={0,0,0,1};
unsigned char set_monthday[4]={0,0,0,2};
unsigned char set_year[4]={0,0,0,3};
unsigned char set_clock[4]={0,8,3,0};
unsigned char set_write[7]={0,0,0,0,0,0,0};
bit flag_display=1;
bit flag_SET=0;
bit flag_clock=0;
bit flag_clock_arrive=0;
bit flag_exit=0;
unsigned char display_mod=0;
unsigned char set_mod=0;
unsigned char flashbit=0;
unsigned char t0_cnt=0
unsigned int year_temp;
void Ds1302Write(unsigned char addr, unsigned char dat)
{
unsigned char n;RST = 0;_nop_();SCLK = 0;_nop_();RST = 1; _nop_();
for (n=0; n<8; n++){DSIO = addr & 0x01;addr >>= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();}
for (n=0; n<8; n++){DSIO = dat & 0x01;dat >>= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();} RST = 0;_nop_();
}
unsigned char Ds1302Read(unsigned char addr)
{
unsigned char n,dat,dat1;RST = 0;_nop_();SCLK = 0;_nop_();RST = 1;_nop_();
for(n=0; n<8; n++){DSIO = addr & 0x01;addr >>= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();}_nop_();
for(n=0; n<8; n++){dat1 = DSIO;dat = (dat>>1) | (dat1<<7);SCLK = 1;_nop_();SCLK = 0;_nop_();}
RST = 0;_nop_(); SCLK = 1;_nop_();DSIO = 0;_nop_();DSIO = 1;_nop_();return dat;
}
void Ds1302Init()
{unsigned char n;Ds1302Write(0x8E,0X00);for(n=0;n<7;n++){Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80);}
void Ds1302ReadTime()
{unsigned char n;for(n=0;n<7;n++){TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);}}
void TimeReset()
{
unsigned char n;TR0=0;
Ds1302Write(0x8E,0X00);for (n=0; n<7; n++){Ds1302Write(WRITE_RTC_ADDR[n],set_write[n]);}
Ds1302Write(0x8E,0x80);for(n=0;n<4;n++){clock[n]=set_clock[n];}TR0=1;
}
void delay(unsigned int cnt)
{while(cnt--);}
void hc595send(unsigned char dat)
{unsigned char a;SRCLK=0;RCLK=0;for(a=0;a<8;a++){SER=dat>>7;dat<<=1;SRCLK=1;_nop_();_nop_();SRCLK=0;}RCLK=1;_nop_();_nop_();RCLK=0;}
void time_assign()
{
display_time[0]=time_trans[2]/10;display_time[1]=time_trans[2]%10;display_time[2]=time_trans[1]/10;display_time[3]=time_trans[1]%10;
display_monthday[0]=time_trans[4]/10;display_monthday[1]=time_trans[4]%10;display_monthday[2]=time_trans[3]/10;display_monthday[3]=time_trans[3]%10;
display_year[0]=2;display_year[1]=0;display_year[2]=(time_trans[6]%100)/10;display_year[3]=time_trans[6]%10;
display_week=time_trans[5];display_second[0]=10;display_second[1]=11;display_second[2]=time_trans[0]/10;display_second[3]=time_trans[0]%10;
if(flag_display){hc595send(hcwei[display_week]);}else{hc595send(0x00);}
if(display_time[0]==clock[0]&&display_time[1]==clock[1]&&display_time[2]==clock[2]&&display_time[3]==clock[3]){flag_clock_arrive=1;}else{flag_clock_arrive=0;}
}
void smgdisplay(unsigned char smg_temp[])
{
unsigned char i;
for(i=0;i<4;i++)
{
switch(i)
{
case(0):S1=0;S2=1; break;
case(1):S1=0;S2=0; break;
case(2): S1=1;S2=0; break;
case(3):S1=1;S2=1; break;
}
if(flag_SET)
{
switch(set_mod)
{
case 0:P2=smgduan_dp[smg_temp[i]];break;
case 1:P2=smgduan[smg_temp[i]];break;
case 2:P2=smgduan[smg_temp[i]];break;
case 3:P2=smgduan_dp[smg_temp[i]];break;
}
}
else
{
switch(display_mod)
{
case 0:P2=smgduan_dp[smg_temp[i]];break;
case 1:P2=smgduan[smg_temp[i]];break;
case 2:P2=smgduan[smg_temp[i]];break;
case 3:P2=smgduan_dp[smg_temp[i]];break;
case 4:P2=smgduan_dp[smg_temp[i]];break;
}
}
delay(100);
P2=0x00;
}
}
void clockoo()
{
if(flag_clock&&flag_clock_arrive&&t0_cnt==9){bell=~bell;}else{bell=0;}
}
unsigned char Leap(unsigned int year)
{
if(year%100==0){if(year%400==0)return 1;else return 0;}else{if(year%4==0)return 1;else return 0;}
}
void sys_init()
{
setled=1;clkled=1;bell=0;hc595send(0x76);TMOD=0x11;TL0=(65536-50000)/256;TH0=(65536-50000)%256;ET0=1;EA=1;TR0=1
}
void main()
{
sys_init();
while(1)
{
if(flag_display)
{
switch(display_mod)
{
case 0:smgdisplay(display_time);break;
case 1:smgdisplay(display_monthday);break;
case 2:smgdisplay(display_year);break;
case 3:smgdisplay(display_second);break;
case 4:smgdisplay(clock);break;
default :display_mod=0;break;
}
}
if(SET==0){delay(150);if(SET==0){flag_SET=1;setled=0;}while(!SET);}
if(!flag_SET)
{
if(UP==0){delay(200);if(UP==0){flag_display=~flag_display;}while(!UP);}
if(DOWN==0){delay(250);if(DOWN==0){flag_clock=!flag_clock;clkled=!flag_clock;}while(!DOWN);}
if(SHOW==0&&flag_display){delay(200);if(SHOW==0){display_mod++;if(display_mod>4)display_mod=0;}while(!SHOW);}
}
else
{
while(flag_SET)
{
switch(set_mod)
{
case 0:smgdisplay(set_time);break;
case 1:smgdisplay(set_monthday);break;
case 2:smgdisplay(set_year);break;
case 3:smgdisplay(set_clock);break;
default:set_mod=0;break;
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』