18.3.2 程序设计
这里采用C51语言,在KeilµVision3集成开发环境中编写程序,来实现对DS1302的控制。本例的程序功能是首先初始化DS1302,然后通过输入不同的字符来分别执行初始化、时钟操作和RAM操作,分别介绍如下。
❑输入字符s或者S,设置日期和时间操作。此时可以再次输入字符来设置年、月、日、星期、时、分和秒信息。
❑输入字符i或者I,进入初始化操作。此时可以详细设置时间和日期等。
❑输入字符r或者R,进入RAM操作。此时可以选择单字节写RAM(输入字符b或者B)、多字节写RAM(输入字符w或者W)或者多字节读RAM(输入字符r或者R)。
❑输入字符d或者D,显示当前日期和时间。
❑输入字符e或者E,退出程序。
主程序的流程图,如图18.10所示。其中,省略了设置时间的下级选项。
图 18.10 主程序流程图
首先在KeilµVision3集成开发环境中建立项目,具体操作步骤如下。
(1)在KeilµVision3集成开发环境中,选择Project→New→µVision Project命令,新建一个工程,并保存。
(2)在弹出的选择器件对话框中选择Atmel公司的AT89S52,如图18.11所示。
(3)单击“确定”按钮,此时询问是否添加启动代码,如图18.12所示。
图 18.11 选择单片机AT89S52
(4)单击“是”按钮添加启动代码,完成工程的建立。
图 18.12 添加启动代码
(5)选择File→New命令,新建一个程序文件,并保存为*.C文件,可以在其中输入程序源代码,示例如下。
include<reg52.h>
//头文件
include<stdio.h>
define uchar unsigned char
//宏定义
sbit SCLK=P1^3;//声明接口引脚
sbit I_O=P1^4;
sbit RSTB=P1^5;
void ResetDS1302();//复位子函数
uchar ReadByteDS1302();//字节读取子函数
void WriteByteDS1302(uchar W_Byte);//字节写入子函数
void SetYear();//年设置子函数
void SetMonth();//月设置子函数
void SetDate();//日设置子函数
void SetDay();//星期设置子函数
void SetHour();//小时设置子函数
void SetMinute();//分钟设置子函数
void SetSecond();//秒设置子函数
void DisableWrite();//写保护子函数
void EnableWrite();//写允许子函数
void Charge();//充电控制子函数
void InitDS1302();//初始化子函数
void WriteRamByte();//RAM字节写入子函数
void Display(uchar loop);//时钟显示子函数
void BurstReadRAM();//多字节突发方式读取RAM子函数
void BurstWriteRAM();//多字节突发方式写入RAM子函数
void main(void)//主函数
{
uchar Key,Key1,Key2;
SCON=0x50;//设置串行口:方式1,8位UART,允许接收
TMOD|=0x20;//设置定时器T1,方式2,8位自动重装
PCON=0x80;//设置SMOD=1
TL1=0xF4;//波特率4800bit/s,初值
TH1=0xF4;
TR1=1;//开启定时器1
TI=1;
printf(“*AT89S52 CONTROL DS1302*\n\n”);
printf(“Initialize the DS1302.\n”);
InitDS1302();//初始化DS1302
while(1)
{
printf(“\nEnter DS1302 Menu Selection:\n”);
printf(“d or D:Display Clock Routine\n”);
printf(“s or S:Set DS1302\n”);
printf(“i or I:Run the Initialize Routine\n”);
printf(“r or R:Run the RAM Routine\n”);
printf(“e or E:Exit\n”);
Key=_getkey();//获取输入字符
switch(Key)
{
case‘d’://执行时钟操作
case‘D’:
printf(“\rRun the Display Clock Routine\n”);
Display(1);
break;
case‘s’://初始化DS1302
case‘S’:
printf(“\rRun Set DS1302\n”);
printf(“\nEnter DS1302 Time Set Menu Selection:”);
printf(“y or Y:Set year\n”);
printf(“M:Set Month\n”);
printf(“D:Set date\n”);
printf(“d:Set day\n”);
printf(“h or H:Set hour\n”);
printf(“m:Set minute\n”);
printf(“s or S:Set second\n”);
Key1=_getkey();//获取输入字符
switch(Key1)
{
case‘y’://设置年
case‘Y’:
SetYear();
break;
case‘M’://设置月
SetMonth();
break;
case‘D’://设置星期
SetDate();
break;
case‘d’://设置日
SetDay();
break
case‘h’://设置小时
case‘H’:
SetHour();
break;
case‘m’://设置分钟
SetMinute();
break;
case‘s’://设置秒
case‘S’:
SetSecond();
break;
default:
printf(“Please Input the Right Option”);
}
break;
case‘i’://初始化DS1302
case‘I’:
printf(“Run the Initialize Routine\n”);
InitDS1302();
break;
case‘r’://RAM操作
case‘R’:
printf(“\rRun the RAM Routine\n”);
printf(“\nEnter DS1302 RAM Menu Selection:”);
printf(“b or B:Write RAM Byte\n”);
printf(“r or R:Burst Read RAM\n”);
printf(“w or W:Burst Write RAM\n”);
Key2=_getkey();//获取输入字符
switch(Key2)
{
case‘b’://RAM字节写入
case‘B’:
WriteRamByte();
break;
case‘r’://多字节突发方式读取RAM
case‘R’:
BurstReadRAM();
break;
case‘w’://多字节突发方式写入RAM
case‘W’:
BurstWriteRAM();
break;
default:
printf(“Please Input the Right Option”);
}
break;
case‘e’://退出
case‘E’:
goto exit;
break;
default:
printf(“Please Input the Right Option”);
}
}
exit:printf(“Exit the program”);
}
在该程序中,首先定义了DS1302和AT89S52的接口引脚。在main主函数中,首先初始化串口为模式1,并设置定时器T1为8位自动重载方式,设置波特率为4800bit/s,随后启动定时器T1。接着,调用InitDS1302()函数初始化DS1302。在while主循环中,通过_getkey()函数获取输入字符,分别执行设置日期时间操作、RAM操作、复位DS1302以及退出等。
当程序编写完毕后,便可以编译仿真。如果编译通过,可以将程序写入AT89S52单片机中执行,通过串口来控制实时时钟芯片DS1302工作。