1、 基于 AVR 单片机的 RTC 实时时钟 引言: 本次我们小组设计的是基于 AVR 单片机的 RTC 实时时钟,它能提供日历 /时钟 /秒表的功能,它走时准确,耗电低 设计原理: 该实时时钟使用了 AVR 单片机,主要利用其中的 DS1302 时钟芯片 , 1602 液晶屏和 CTC 分频模式。 一 日历时钟设计: 1.芯片选择 对于时钟设计我们直接使用了 DS1302 时钟芯片,该芯片利用了外加的 12M 的晶振进行计时,自带了万年历的功能,使用十分方便。 本身有后备电源引脚,可以外接后备电源保持实时工作。内有年月日时分秒的寄存器, 可直接写入读取,缺点是较难起振,感觉会受温度影响 2.液
2、晶屏使用 为了方便的显示时间,我们还采用了 1602 液晶屏 .1602 液晶屏功耗小,体积小,显示内容丰富,操作灵活,具有双行 16 字显示。 3.时钟程序设计 1)DS1302 程序 主要函数: DS1302Init()/初始化时钟芯片 ,DS1302_WriteB()/写入单字节数据 DS1302_readB()/读取单字节数据, DS1302_setT()/时间设置 DS1302_getT()/ 获取时间 2)1602 程序 主要函数 Init1602()/初始化 1602, Gotoxy()/显示位置设置 Write1602()/在 1602 中显示数据 3)其他常用程序 Keych
3、eck()/小 键盘检查, Delay_ms()/延时函数 BCD2ACSII()/编码转换 , display()/显示 1602 4.程序设计原理 DS1302:通过拉高拉低 RST 电平进行片选,当时钟信号来临时,先向 DS1302写入操作的地址信息,在第二个时钟信号进行数据操作,读取或写入,每次操作完注意进行写保护防 止误写入数据导致时钟停止 1602:通过 RS,R/W,EN进行控制操作,通过 D0D7 进行数据写入 二 秒表设计 1. 芯片选择 直接使用 ATMEga16 本身的分频功能 。 2. 定时器程序设计 timer()/定时器驱动及 1602 显示, time()/中断执
4、行的函数 3. 程序设计原理: 利用定时器 timer1中的 256 分频,先对 TCCR1 寄存器预存数据,存入的数据为( 65525-12000000/256) ,当 TCCR1 累加到 65535 时,产生中断,然后进行中断操作,全局变量 SECONG 加 1 等。 调试过程: 单片机的 调试是枯燥而又艰辛的,其中既有硬件上又软件上的调试。对于硬件调试,我们一开始就打定主意用液晶屏来显示,但是买来的液晶屏屡试都还无反应,只用背光灯亮了,我们想了无数个办法都没有成功,在其中浪费了巨大的时间,后来发现竟然是因为电位器没有调好,调好后在改了一下代码的显示,总算是把 1602 调通了,实在是因为
5、一开始没有经验完全不知道电位器要调整。 我们遇上的第二个大麻烦就是 1302 竟然不能走钟,一开始还是从软件入手,测试了DS1302寄存器里的数据,改了很多小问题,最后变的可以读取和写入数据了,但是还是不能走,我 用万用表测了管脚,感觉是因为晶振没有起振,换了同学的晶振,还是不能走动,愈发悲剧,百度谷歌了很长时间,有说电容问题,甚至有说 DS1302 很多假冒的,后来某次突然二了,竟然有吹风筒去吹(看代码太久,神经错乱),更无语的是吹了一下后。竟然时钟竟然动了,十分囧,遂感觉是因为天气潮湿导致晶振管脚短接,至今未能验证是否。后来这两天天气凉下来都能正常起振了 最后是小键盘的调试,因为之前弄过,
6、所以硬件上是没有问题的,只是软件上问题多多,比如会显示乱码之类的,大多是时序和键盘抖动的问题,慢慢调还是调好了。 经验教训 : 最大的感慨是调试时一开始完全不知道是软件还是硬件的问题,只能慢慢猜测,不断尝试才能调好一块板子,而且同是 AVR 单片机不同的焊接电路使用方法是完全不同的,写代码时一定要多用宏定义才方便改,遇到问题慢慢看 DATASHEET。 附带 源码 【主程序】 #include“test.h“ #include“time.h“ #include“keycheck.h“ #include“delay.h“ #define TIMER_KEY 15 #define RTC_KEY
7、14 #define SETTIME_KEY 11 uchar settime7=0x20,0x04,0x12,0x26,0x09,0x06,0x10; void Writeweek(uchar day) switch (day) case 1: Write1602(1,M); Write1602(1,o); Write1602(1,n); break; case 2: Write1602(1,T); Write1602(1,u); Write1602(1,e); break; case 3: Write1602(1,W); Write1602(1,e); Write1602(1,d); br
8、eak; case 4: Write1602(1,T); Write1602(1,h); Write1602(1,r); break; case 5: Write1602(1,F); Write1602(1,r); Write1602(1,i); break; case 6: Write1602(1,S); Write1602(1,a); Write1602(1,t); break; case 7: Write1602(1,S); Write1602(1,u); Write1602(1,n); break; void display(uchar time) uchar *p; Gotoxy(1
9、,0); Write1602(1,2); Write1602(1,0); p=BCD2ACSII(time6); Write1602(1,p0); Write1602(1,p1); Write1602(1,-); p=BCD2ACSII(time4); Write1602(1,p0); Write1602(1,p1); Write1602(1,-); p=BCD2ACSII(time3); Write1602(1,p0); Write1602(1,p1); Gotoxy(12,0); Writeweek(time5); Gotoxy(2,1); p=BCD2ACSII(time2); Writ
10、e1602(1,p0); Write1602(1,p1); Write1602(1,:); p=BCD2ACSII(time1); Write1602(1,p0); Write1602(1,p1); Write1602(1,:); p=BCD2ACSII(time0); Write1602(1,p0); Write1602(1,p1); Gotoxy(0,0); void Write_time_input() uchar i; uchar table=“input new time:“; for(i=0;i=1; uchar DS1302_readB(void) uchar i,byte=0X
11、00; time_DDR time_Port for(i=0;i8;i+) SCLK_H; asm(“nop“); asm(“nop“); SCLK_L; asm(“nop“); asm(“nop“); if(time_PIN else byte time_DDR|=BIT(time_DATA); return byte; void DS1302_writeD(uchar addr,uchar data) RST_L; SCLK_L; asm(“nop“); asm(“nop“); RST_H; asm(“nop“); asm(“nop“); DS1302_writeB(addr); asm(
12、“nop“); asm(“nop“); SCLK_L; asm(“nop“); asm(“nop“); DS1302_writeB(data); SCLK_L; asm(“nop“); asm(“nop“); RST_L; uchar DS1302_readD(uchar addr) uchar data; RST_L; SCLK_L; asm(“nop“); asm(“nop“); RST_H; asm(“nop“); asm(“nop“); DS1302_writeB(addr); asm(“nop“); asm(“nop“); data=DS1302_readB(); asm(“nop“
13、); asm(“nop“); SCLK_L; RST_L; return data; void DS1302_setT(uchar ptTimeD) uchar i; uchar addr = 0x80; DS1302_writeD(C_WP|WR,UPROTECT); Delay_ms(5); for(i=0;i7;i+) DS1302_writeD(addr|WR,ptTimeDi); addr+=2; Delay_ms(1); DS1302_writeD(C_WP|WR,PROTECT); void DS1302_getT(uchar time) uchar i; uchar addr = 0x80; RST_H; for(i=0;i7;i+) timei=DS1302_readD(addr|RD); asm(“nop“); addr+=2; SCLK_L; RST_L; void DS1302_init(void) DS1302_writeD(C_WP|WR,UPROTECT); DS1302_writeD(C_SEC|WR,CLK_START); DS1302_writeD(C_WP|WR,PROTECT); uchar* BCD2ACSII(uchar i) uchar *p; p0=i/16; p1=i%16; p0+=0; p1+=0; return p;