sbit k3=P1^7; //开始走秒 uchar code duan_code[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管段码表 uchar display_code[]={
0x00,0x00,0xbf,0x00,0x00,0xbf,0x00,0x00};//显示格式,中间两个横杠 uchar bit_code[]={
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//数码管位选
uchar current_time[7]; //所读取的日期和时间 char adjust_flag=0; //调节标志 void delayms(uint x) //延时函数ms级 {
uchar i;
while(x--) for(i=0;i++;i<120); }
void write_byte(uchar x) //写一个字节函数 {
uchar i; for(i=0;i<8;i++) { sda=x&1; clk=1; clk=0; x>>=1; } }
uchar read_byte(void) //读一个字节函数 {
uchar i,b,t; for(i=0;i<8;i++) { b>>=1; t=sda;
- 10 -
b|=t<<7; clk=1; clk=0; }
return b/16*10+b; }
uchar read_data(uchar addr) //读取数据函数 {
uchar dat; rst=0; clk=0; rst=1;
write_byte(addr); dat=read_byte(); clk=1; rst=0; return dat; }
void write_data(uchar addr,uchar dat) //写入控制字和输入函数 { clk=0; rst=1;
write_byte(addr); write_byte(dat); clk=0; rst=0; }
void set_1302() //设置ds1302函数 {
write_data(0x8e,0x00); //关闭写保护。
write_data(0x82,(current_time[1]/10<<4)|(current_time[1]));//初始化分
- 11 -
write_data(0x84,(current_time[2]/10<<4)|(current_time[2]));//初始化时 write_data(0x8e,0x80); //打开写保护。 }
void gettime() //单片机从ds1302读取的时间数据 {
current_time[0]=read_data(0x81); current_time[1]=read_data(0x83); current_time[2]=read_data(0x85); }
void int0() interrupt 0 //{
if(k1==0) // {
adjust_flag=1; //
current_time[2]=(current_time[2]+1)$;
} else if(k2==0) // {
adjust_flag=1; //
current_time[1]=(current_time[1]+1)`;
} else
if(k3==0) // {
set_1302(); //ds1302 adjust_flag=0; //示 }
- 12 -
中断函数 小时调整
正在调整 分钟调整
正在调整 确定 将调整后的时间写入结束调整,时间继续正常显
}
void main() //主函数 {
uchar i;
IE=0X81; //开总中断,同时开外部定时器0中断 while(1) {
if(adjust_flag==0)
gettime(); //扫描按键,当按键没有被按下时,单片机从ds1302读取时间数据 display_code[0]=duan_code[current_time[2]/10];//小时为的十位 display_code[1]=duan_code[current_time[2]];//小时位的个位 display_code[3]=duan_code[current_time[1]/10];//分钟位的十位 display_code[4]=duan_code[current_time[1]];//分钟为的个位 display_code[6]=duan_code[current_time[0]/10];//秒位的十位 display_code[7]=duan_code[current_time[0]];//秒位的个位
for(i=0;i<8;i++) //对数码管进行动态扫描 {
P2=bit_code[i];
P0=display_code[i]; delayms(5);
} } }
5 心得体会
通过本次设计,使我们对单片机的了解有了更加深一步,我发现只有动手做才会孰能技巧,还有对材料的整理和理解。这次设计运用到的知识很多方面,尤其是单片机,像AT89C51,引脚多,硬件内部线路接通,所以用起来很方便,还有ds1302芯片与单片机之间的连接,以及如入使用ds1302芯片。当然也要对这些元器件作相应调查。主要就是电路原理图,还有对引脚的作用熟悉。对于软件方面则是灵活运用单片机有关的程序语言,还有很多扩展功能,由于知识匮乏,但是理论知识还是比较详细的。我们最大的成功之处是在这整个过程,动脑寻求解决一个一个问题的办法,对程序是不断思索,务必写出很简单的程序来,使得电子时钟能做成功!
- 13 -
6 参考文献
《单片机原理及其接口技术》(第二版) 清华大学出版社 《新概念51单片机C语言教程》 电子工业出版社 《单片机C语言程序设计实训100例》 电子工业出版社 7 结束语
本设计利用单片机AT89C51控制串行实时时钟芯片DS1302构成数字时钟电路, 实现计时功能。该电路使用简单的三线接口,为单片机节省大量的接口资源,时钟芯片DS1302带有后备电池,具备对后背电源进行涓细电流充电的能力,保证电路断电后仍保存时间和数据信息,这些优点解决了目前常用实时时钟占用单片机资源多以及计时不可靠等缺点。该时钟功能强大,性能优越,能为很多领域,特别是对时钟工作的精确性和可靠性有较高要求的场合,提供较好的实时时钟。但是,由于DS1302易受环境影响,会使该电路出现时钟精度不高、时钟混乱等问题,还有继续研究和改进。
- 14 -