基于单片机的万年历制作文档格式.docx
《基于单片机的万年历制作文档格式.docx》由会员分享,可在线阅读,更多相关《基于单片机的万年历制作文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
二、DS1302简介
1、总体概述
图一:
DS1302外部引脚
DS1302是一种高性能、低功耗的实时时钟芯片,附加有31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可以采用突发方式,一次传送多个字节的时钟信号或RAM数据。
实时时钟可以提供秒、分、时、日、星期、月和年,一个月小于31日时可以自动调整,包括闰年,有效值2100年。
可以采用12h或24h方式计时,采用双电源供电,可设置备用电源充电方式,同时提供了对后备电源进行涓流充电的能力。
7个附加字节的暂存储器,包括移位寄存器、控制逻辑、振荡器、实时时钟和RAM。
芯片为8引脚小型DIP封装,引脚排列如图一所示,引脚功能见表一。
引脚号
名称
功能
1
Vcc1
备份电源输入
2
X1
32.768Hz晶振输入
3
X2
32.768Hz晶振输出
4
GND
地
5
RST
控制移位寄存器/复位
6
I/O
数据输入/输出
7
SCLK
串行时钟
8
Vcc2
主电源输入
表一:
DS1302引脚功能说明
2、DS1302的控制字和读写时序说明
在变成过程中要注意DS1302的读写时序。
DS1302是SPI总线驱动方式。
它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。
要想与DS1302通信,首先要了解DS1302的控制字。
DS1302的控制字见表二:
BIT7
BIT6
BIT5
BIT4
BIT3
BIT2
BIT1
BIT0
RAM
A4
A3
A2
A1
A0
RD
CK’
WR’
表二:
DS1302的控制字
控制字的作用是设定DS1302的工作方式、传输字节等。
每次数据的传输都是由控制字开始。
控制字各位的含义和作用如下:
1、BIT7:
控制字的最高位有效,必须是逻辑1,如果它为0,则不能把数据写入到DS1302中;
2、BIT6:
如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;
3、BIT5至BIT1(A4~A0):
用A4~A0表示,定义片内寄存器和RAM地址。
定义如下:
当BIT6位=0时,定义时钟和其他寄存器的地址。
A4~A0=0~6,顺序为妙、分、时、日、月、星期、年的寄存器。
当A4~A0=7,为芯片写保护寄存器地址。
当A4~A0=8.为慢速充电参数选择寄存器。
当A4~A0=31,为时钟多字节方式选择寄存器。
当BIT6=1时,定义RAM的地址,A4!
A0=0~30,对应各子地址的RAM,地址31对应的是RAM多字节方式选择寄存器。
4、BIT0(最低有效位):
如果为0,表示要进行写操作,为1表示进行读操作。
控制字总是从最低位开始输出。
在控制字指令输入后的下一个SCLK时钟上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。
同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。
图二:
DS1302数据读写时序
三、DS1302在单片机系统中应用的实现
DS1302与单片机的链接仅需要3条线,即SCLK、I/O、RST。
VCC2在单电源与电池供电的系统中提供地电源并能提供低功率的电池备份。
VCC2在双电源系统中提供电源,在这种运行方式下VCC1连接到备份电源,以便在没有主电源的情况下能保存时间信息以及数据。
DS1302由两者中的较大者供电。
当VCC2大于VCC1+0.2V时,VC2给DS1302供电。
当VCC2小于在单片机系统中使用VCC1的时候,DS1302由VCC1供电。
在本系统中,以ATmega为主器件,DS1302为从器件,RST接在主器件的PC4/TD0上,此引脚为高位的时候,选中该芯片,对其进行操作。
串行数据线I/O与串行时钟线SCLK分别接在PC3/TMS和PC2/TCK上,所有的单片机地址、命令、及数据均通过这两条线传输。
在系统中,主器件在总线上产生时钟脉冲,寻址信号,数据信号,而从器件则相应接收数据,送出数据。
对DS1302的每一次读写都需要16个时钟脉冲,前8个脉冲输入操作地址和读写命令。
1、硬件设计
此系统中的主要器件为单片机ATmega16和DS1302,系统的逻辑图如下:
图三:
系统的逻辑框图
其接口电路如图四所示。
图四:
接口电路
2、程序设计
单片机控制DS1302时钟芯片的程序,主要包括两个方面的关键内容,一个是单片机对DS1302寄存器的地址定义和控制字的写入,二是数据的读取。
单片机控制的DS1320时钟实时时间控制楼成图如下:
为了节约成本,使用了实验室的开发板进行连接,只是外接了一个1602小液晶。
电路图在整体框架图中可以看见。
四、总结
串行时钟芯片DS1302连线简单、体积小、价格低,再为控制其系统中应用有着突出的优点。
DS1302可以用于数据记录,特别是对某些具有特殊意义的数据点的记录,能实现数据与出现该数据的时间同时记录。
这种记录对长时间的连续测控系统结果分析及对异常数据出现的原因的查找具有重要意义。
附录一:
主程序
#include<
mega16.h>
delay.h>
stdio.h>
//*******************************
//DS1302RealTimeClockfunctions
#asm
.equ__ds1302_port=0x15;
PORTC
.equ__ds1302_io=3
.equ__ds1302_sclk=2
.equ__ds1302_rst=4
#endasm
ds1302.h>
.equ__lcd_port=0x18;
PORTb数据寄存器地址
/*液晶与单片机的端口连接
1GND-9GND
2+5V-10VCC
3VLC-LCDHEADERVo
4RS-1PB0(M16)
5RD-2PB1(M16)
6EN-3PB2(M16)
11D4-5PB4(M16)
12D5-6PB5(M16)
13D6-7PB6(M16)
14D7-8PB7(M16)*/
lcd.h>
unsignedcharh,m,s,r,y,n;
unsignedchartime[10];
charlcd_buffer[50];
bitrunnian=0;
intn_temp;
unsignedcharkey_stime_counter,time_counter;
bittime_1s_ok;
//时间计数单元,
bittime_display;
bitkey_stime_ok,baoshi=0;
unsignedcharchange=0;
intadd=2000;
//Timer0比较匹配中断服务,2ms定时AS
interrupt[TIM0_COMP]voidtimer0_comp_isr(void)
{
//LED扫描显示
if(++key_stime_counter>
=5)
{
key_stime_counter=0;
key_stime_ok=1;
//10ms到
if(++time_counter>
=30)
{
time_counter=0;
time_1s_ok=~time_1s_ok;
//0.1s到
}
}
}
#definekey_inputPINA.3//按键输入口
#definekey_state_00
#definekey_state_11
#definekey_state_22
unsignedcharread_keyb3(void)
staticunsignedcharkey_state=0;
unsignedcharkey_press,key_return=0;
key_press=key_input;
//读按键I/O电平
switch(key_state)
casekey_state_0:
//按键初始态
if(!
key_press)key_state=key_state_1;
//键被按下,状态转换到键确认态
break;
casekey_state_1:
//按键确认态
key_press)
{
key_return=1;
//按键仍按下,按键确认输出为"
1"
(1)
key_state=key_state_2;
//状态转换到键释放态
}
else
key_state=key_state_0;
//按键已抬起,转换到按键初始态
casekey_state_2:
if(key_press)key_state=key_state_0;
//按键已释放,转换到按键初始态
}
returnkey_return;
}
#definekeyb1_inputPINA.1//按键输入口
unsignedcharread_keyb1(void)
key_press=keyb1_input;
#definekeyb2_inputPINA.2//按键输入口
unsignedcharread_keyb2(void)
key_press=keyb2_input;
#definekeyb4_inputPINA.4//按键输入口
unsignedcharread_keyb4(void)
key_press=keyb4_input;
voidmain(void)
PORTA=0xFF;
//显示控制I/O端口初始化
DDRA=0x00;
PORTD=0x00;
DDRD=0xff;
PORTB=0x00;
DDRB=0xFF;
PORTC=0x10;
DDRC=0x1c;
//T/C0初始化
TCCR0=0x0B;
//内部时钟,64分频(4M/64=62.5KHz),CTC模式
TCNT0=0x00;
OCR0=0x7C;
//OCR0=0x7C(124),(124+1)/62.5=2ms
TIMSK=0x02;
//允许T/C0比较匹配中断//OCR0=0x7C(124),(124+1)/62.5=2ms
rtc_init(0,0,0);
//ds1302初始化
rtc_set_date(31,12,9);
rtc_set_time(23,59,55);
lcd_init(16);
//initializetheLCDfor2lines&
16columns
lcd_clear();
//cleretheLCD
#asm("
sei"
)//开放全局中断
while
(1)
if(!
time_display)//0.1秒到
rtc_get_date(&
time[3],&
time[4],&
time[5]);
r=time[3];
y=time[4];
n=time[5];
rtc_get_time(&
time[0],&
time[1],&
time[2]);
h=time[0];
m=time[1];
s=time[2];
if(time[1]==0&
&
time[2]==0)baoshi=1;
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"
%4d/%2d/%2d"
n+add,y,r);
//%X以16进制输出
lcd_puts(lcd_buffer);
//如果不是以16进制,则showASC-IIon1602
}
else
%2d:
%2d"
h,m,s);
if(baoshi)
{
//蜂鸣器响
baoshi=0;
TCCR1A=0x40;
TCCR1B=0x09;
OCR1A=500;
delay_ms(100);
OCR1A=0;
delay_ms(10);
if(change&
!
time_display)
switch(change)
case1:
lcd_gotoxy(0,0);
/%2d/%2d"
y,r);
//如果不是以16进制,则showASC-IIon1602
while(time_1s_ok);
break;
case2:
lcd_gotoxy(0,0);
%4d//%2d"
n+add,r);
case3:
%4d/%2d/"
n+add,y);
if(change&
time_display)
{switch(change)
case1:
:
m,s);
case2:
h,s);
lcd_puts(l