“多功能电子钟”设计说明
1 工程文件下载:
2 程序设计框架说明
本案例程序设计主要分为:DS1302、ADC、按键扫描三个模块。
2.1宏定义
#define uchar unsignedchar //宏定义
#define uint unsigned int
#defineADC_CHS1_7 0X07
/***********时分秒写寄存器**************/
#define DS1302_SECOND_WRITE 0x80
#define DS1302_MINUTE_WRITE 0x82
#define DS1302_HOUR_WRITE 0x84
#define DS1302_WEEK_WRITE 0x8A
#define DS1302_DAY_WRITE 0x86
#define DS1302_MONTH_WRITE 0x88
#define DS1302_YEAR_WRITE 0x8C
#define ADC_POWER 0X80
#define ADC_FLAG 0X10 //当A/D转换完成后,ADC_FLAG要软件清零
#define ADC_START 0X08
#define ADC_SPEED_90 0X60
/***********时分秒读寄存器**************/
#define DS1302_SECOND_READ 0x81
#define DS1302_MINUTE_READ 0x83
#define DS1302_HOUR_READ 0x85
#define DS1302_WEEK_READ 0x8B
#define DS1302_DAY_READ 0x87
#define DS1302_MONTH_READ 0x89
#define DS1302_YEAR_READ 0x8D
#define P1_7_ADC 0x80
2.2引脚定义
/********DS1302*******/
sbitRtc_sclk = P1^5; //时钟线引脚,控制数据的输入与输出
sbitRtc_rst = P1^6; //CE线引脚,读、写数据时必须置为高电平
sbitRtc_io = P5^4; //实时时钟的数据线引脚
/********数码管显示******/
sbit Led_sel = P2^3; //流水灯和数码管选通引脚
sbit Sel0 = P2^0; //Sel0、Sel1、Sel2三位二进制进行数码管位选0-7 sbit Sel1 = P2^1;
sbit Sel2 = P2^2;
sbit KEY1=P3^2; //Key1对应触发外部中断0
sbit KEY2=P3^3; //Key2对应触发外部中断1
sbitKEY3=P1^7; //Key3
2.3变量定义
时间结构体
typedef struct __SYSTEMTIME__
{
uchar Second;
uchar Minute;
uchar Hour;
uchar Week;
uchar Day;
uchar Month;
uchar Year;
}SYSTEMTIME; //定义的时间类型
SYSTEMTIME t;
Fun_Key.c模块
/*年、月、日标志*/
bit set_Y_flag;
bit set_M_flag;
bit set_D_flag;
/*时、分、秒标志*/
bit set_H_flag;
bit set_Ms_flag;
bit set_S_flag;
/*年、月、日值*/
uint set_Y_val;
uint set_M_val;
uint set_D_val;
/*时、分、秒值*/
uint set_H_val;
uint set_Ms_val;
uint set_S_val;
bit set_YMD_done; //年月日设置完
bit set_HMS_done; //时分秒设置完
bit show_set_YMD; //显示年月日
bit show_set_HMS; //显示时分秒
bit show_YMD; //显示年月日
bit show_HMS; //显示时分秒
bit show_YMDW;
bit show_key_val;
unsigned char key_val;
bit ring_flag;/*标志闹钟*/
unsigned int ring_H;
unsigned int ring_Ms;
unsigned int ring_S;
CALENDAR模块
bit c_moon;
unsigned int year_moon;
unsigned int month_moon;
unsigned int day_moon;
unsigned int week;
DS1302模块
bit set_YMD_flag; //设置年月日标记
bit set_HMS_flag; //设置时分秒标记
SYSTEMTIME t;
SYSTEMTIME set_t;
3 程序函数说明
延时程序
void Delayms(char i);
DS1302读写函数
void Ds1302_write(uchar temp);
uchar Ds1302_read();
void WriteDS1302(uchar Addr, uchar Data);
uchar ReadDS1302(uchar cmd)
SYSTEMTIME DS1302_GetTime();
系统初始化
void Init();
void Init_key();
ADC转换
unsigned char GetADC();
检测导航键
unsigned char Fun_Keycheck();
监听按键3
void Fun_key3();
监听功能键,完成时分秒相关值的设置
void Fun_Key_task_HMS();
监听按键2,完成时分秒设置
void Fun_key2();
监听按键1,完成相关功能的操作
void Key_OFFON();
初始化DS1302
void Initial_DS1302(void);
中断显示程序
void timer0() interrupt 1
初始化ADC
void Init_ADC();
4 程序设计框架及关键技巧说明
4.1 程序总框图设计流程
4.2 I/O引脚及相关寄存器配置
4.2.1 I/O引脚:
(1)数码管位选引脚
整个设置P2口的值;
(2)数码管使能引脚
sbit led_sel = P2^3 ;
(3)DS1302引脚
sbit rtc_sclk=P1^5; //时钟线引脚
sbit rtc_rst=P1^6; // CE线引脚
sbit rtc_io=P5^4; //实时时钟的数据线引脚
(4)按键引脚
sbit KEY1 = P3^2 ; //控制时间校准时设置的值
sbit KEY2 = P3^3 ; //设置时间
sbit KEY3 = P1^7; //设置年月日
4.2.2寄存器:
(1)DS1302相关寄存器

其中:
①控制字寄存器:写地址0x8E,读地址0x8F
位7:必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。
位6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;此程序中没有涉及RAM存取数据,所以位6置为0.
位5~位1(A4~A0) :指示操作单元的地址;
位0 :为0写操作,为1读操作。

②秒寄存器:
位7:时间暂停位,为1时钟振荡器停止工作,为0时,时钟振荡器启动;
初始化时,要启动时钟振荡器,在禁止写保护的情况下通过如下语句实现:
temp=ReadDS1302(DS1302_SECOND_READ)&0x7f;
WriteDS1302(0x80,temp);//晶振开始工作
③小时寄存器:
位7:12或24小时工作模式选择位,为1时12小时工作模式,此时位5为AM/PM位,低电平对应 AM,高电平对应PM;在 24 小时模式下,位5为第二个10小时位表示(20~23 时);
④写保护寄存器:
位7: WP 是写保护位,工作时除WP 外的其他位都置为0, 写操作之前WP必须为0,当WP 为1时不能进行写操作。
WriteDS1302(0x8E,0x00); //禁止写保护位
WriteDS1302(0x8E,0x80); //写保护位置1
(2) 定时器相关寄存器
其中
①TMOD寄存器:

初始化时,设置定时器0,工作模式1即16位不可重装载模式,TMOD= 0x01 ;
②IE寄存器:

初始化时,设置EA=1,打开总的中断,设置ET0=1开启定时器0的中断;
③TH0、TL0寄存器:
同时还要设置TH0、TL0的初始值;
④TCON寄存器:

初始化时,设置TR0=1启动定时器0
(3) A/D相关寄存器
①P1ASF寄存器:

初始化时,设置P1ASF=P1_7_ADC(0x80),即P1.7口为模拟功能A/D使用;
②ADC_RES寄存器:

初始化时,设置ADC_RES=0x00;
③ADC_CONTR寄存器:

初始化时,设置ADC_CONTR = ADC_POWER| ADC_FLAG | ADC_START | ADC_SPEED_90 | ADC_CHS1_7,即对应位都值1,其中ADC_SPEED_90对应SPEED1、SPEED0均为1;ADC_CHS1_7对应CHS2、CHS1、CHS0均为1;

