制作出来的实物图如下:
- /*********************************************************************
- 模块名称:DS1302
- 模块功能: RTC
- 硬件接线:无。
- 注意事项:(1) DS1302的SPI接口用到了P3.4、P3.5、P3.6,若程序运行有问题查
- 硬件问题时可以从这三个引脚复用部分查起
- (2) DS1302的初始化时间是随便给的,之所以给23.59.50,是为了在10
- 秒后即可看到24.59.59到00.00.00的跳变。
- (3) DS1302寄存器读写的函数编写时要注意时序和LSB这2个要点。
- **********************************************************************/
- /*
- **********************************************************************
- * 头文件包含
- **********************************************************************
- */
- #include "ds1302.h"
- /*
- **********************************************************************
- * 本地全局变量
- **********************************************************************
- */
- // 以下为DS1302相关定义
- sbit DSIO = P1^0; // DS1302的SPI接口IO线,输入输出都走这里
- sbit CE = P1^1; // chip enable,读写ds1302前要使能,读写完要禁止
- sbit SCLK = P1^2; // serial clock,串行时钟线
- extern u8 gTime[7]; // 定义在mian.c中,用来存储DS1302中7个时间的BCD码值
- extern u8 gDigValue[8]; // 定义在main.c中,用LCD2864上显示的8个数值
- extern u8 YTD[];
- extern u8 week[];
- // DS1302内部时间寄存器地址常量定义,这些地址值可查DS1302数据手册获取
- u8 code DS1302_READ_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; //读地址
- u8 code DS1302_WRITE_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //写地址
- /*
- **********************************************************************
- * 内部函数原型声明
- **********************************************************************
- */
- static void Ds1302WriteReg(u8 addr, u8 dat);
- static u8 Ds1302ReadReg(u8 addr);
- static void Ds1302WriteTime(void);
- /*********************************************************************
- * 函 数 名 : Ds1302WriteReg
- * 函数功能 : 向DS1302中地址为addr的寄存器写入数值dat
- * 参数列表 : addr - 待写入数值的寄存器地址
- dat - 待写入addr寄存器的数值
- * 函数输出 : 无
- *********************************************************************/
- static void Ds1302WriteReg(u8 addr, u8 dat)
- {
- u8 i = 0;
- CE = 0;
- _nop_(); // 空指令,延时
- SCLK = 0; // 先将SCLK置低电平
- _nop_();
- CE = 1; // CE拉高以使能对DS1302的读写权限
- _nop_();
- for (i=0; i<8; i++) // 循环逐位发送addr的8个bit,注意低位在前
- {
- DSIO = addr & 0x01; // 数据从LSB低位开始传送
- addr >>= 1; // 发完后addr右移一位原来的次低位变成新的低位
- SCLK = 1; // 拉高SCLK制造一个上升沿,通知DS1302读取数据
- _nop_(); // 延时等待DS1302读取DSIO线上的1位数据
- SCLK = 0; // 读完后,拉低SCLK为下一个位的传输做准备
- _nop_();
- }
- // 循环结束后1字节的寄存器地址传给DS1302
- for (i=0; i<8; i++) // 循环写入8位数据,注意低位在前
- {
- DSIO = dat & 0x01;
- dat >>= 1;
- SCLK = 1; //制造上升沿通知DS1302读取数据
- _nop_();
- SCLK = 0;
- _nop_();
- } // 循环结束后1字节值成功传给DS1302
-
- CE = 0; // 写入完毕拉低CE以禁止对DS1302的读写,防止意外改写事故
- _nop_();
- }
- /*********************************************************************
- * 函 数 名 : Ds1302ReadReg
- * 函数功能 : 向DS1302中地址为addr的寄存器写入数值dat
- * 参数列表 : addr - 待读出的寄存器的地址
- * 函数输出 : 读出的寄存器addr的数值
- *********************************************************************/
- static u8 Ds1302ReadReg(u8 addr)
- {
- u8 i = 0, dat = 0, dat1 = 0;
- CE = 0; // CE设置为初始状态
- _nop_();
- SCLK = 0; // SCLK设置为初始状态
- _nop_();
- CE = 1; // 拉高CE使能对DS1302的寄存器读写权限
- _nop_();
- for (i=0; i<8; i++) // 循环发送8bit寄存器地址值
- {
- DSIO = addr & 0x01; // DS1302的SPI接口从LSB开始发送
- addr >>= 1;
- SCLK = 1; // 制造上升沿,DS1302在上升沿完成读取动作
- _nop_();
- SCLK = 0; // 拉低SCLK为下个bit发送做准备
- _nop_();
- }
-
- for (i=0; i<8; i++) // 循环读取8bit寄存器值数据
- {
- dat1 = DSIO;//从最低位开始接收
- dat = (dat>>1) | (dat1<<7);
- SCLK = 1;
- _nop_();
- SCLK = 0;//DS1302下降沿时,放置数据
- _nop_();
- }
- CE = 0;
- _nop_(); //以下为DS1302复位的稳定时间,必须的。
- SCLK = 1;
- _nop_();
- DSIO = 0;
- _nop_();
- DSIO = 1;
- _nop_();
- return dat;
- }
- /*********************************************************************
- * 函 数 名 : Ds1302WriteTime
- * 函数功能 : 将全局变量gTime中的时间写入DS1302中以重置DS1302时间
- * 参数列表 : 无
- * 函数输出 : 无
- *********************************************************************/
- static void Ds1302WriteTime(void)
- {
- u8 i = 0;
- Ds1302WriteReg(0x8E,0x00); // 禁用WP以获取写时间寄存器的权限
- for (i=0; i<7; i++) // 依次写入7个时间,顺序依次:秒分时日月周年
- {
- Ds1302WriteReg(DS1302_WRITE_ADDR[i],gTime[i]);
- }
- Ds1302WriteReg(0x8E,0x80); // 使能WP以禁止对时间寄存器的读写,防止意外改写事故
- }
- /*********************************************************************
- * 函 数 名 : Ds1302InitTime
- * 函数功能 : 以给定的初始时间来重置DS1302时间值
- * 参数列表 : 无
- * 函数输出 : 无
- *********************************************************************/
- void Ds1302InitTime(void)
- {
- // 先给个初始化时间
- gTime[0] = 0x50; // 初始化时间,秒,注意是BCD码不是10进制也不是16进制
- gTime[1] = 0x59; // 初始化时间,分,注意是BCD码不是10进制也不是16进制
- gTime[2] = 0x23; // 初始化时间,时,注意是BCD码不是10进制也不是16进制
- gTime[3] = 0x31; // 初始化时间,日,注意是BCD码不是10进制也不是16进制
- gTime[4] = 0x12; // 初始化时间,月,注意是BCD码不是10进制也不是16进制
- gTime[5] = 0x07; // 初始化时间,周,注意是BCD码不是10进制也不是16进制
- gTime[6] = 0x18; // 初始化时间,年,注意是BCD码不是10进制也不是16进制,以2000为基数
- // 将给定时间写入DS1302内部时间寄存器以完成初始化
- Ds1302WriteTime();
- }
- /*********************************************************************
- * 函 数 名 : Ds1302ReadTime
- * 函数功能 : 读出DS1302内部时间放入全局变量gTime中
- * 参数列表 : 无
- * 函数输出 : 无
- *********************************************************************/
- void Ds1302ReadTime(void)
- {
- u8 i = 0;
- for (i=0; i<7; i++)//读取7个字节的时钟信号:秒分时日月周年
- {
- gTime[i] = Ds1302ReadReg(DS1302_READ_ADDR[i]);
- }
- }
- /*********************************************************************
- * 函 数 名 : UpdateDigValue
- * 函数功能 : 显示时间
- * 参数列表 : 无
- * 函数输出 : 无
- *********************************************************************/
- void UpdateDigValue(void)
- {
- Ds1302ReadTime(); // 从DS1302读取时间存入gTime中
- gDigValue[0] = ((gTime[2] >> 4) & 0x0f)+48; // Hour的高4位
- gDigValue[1] = ((gTime[2] >> 0) & 0x0f)+48; // Hour的低4位
- gDigValue[2] = ':'; // 分隔符
-
- gDigValue[3] = ((gTime[1] >> 4) & 0x0f)+48; // Minute的高4位
- gDigValue[4] = ((gTime[1] >> 0) & 0x0f)+48; // Minute的低4位
- gDigValue[5] = ':'; // 分隔符
- gDigValue[6] = ((gTime[0] >> 4) & 0x0f)+48; // Second的高4位
- gDigValue[7] = ((gTime[0] >> 0) & 0x0f)+48; // Second的低4位
-
- }
- /*********************************************************************
- * 函 数 名 : DisplayDay
- * 函数功能 : 显示年月日
- * 参数列表 : 无
- * 函数输出 : 无
- *********************************************************************/
- void DisplayDay(void)
- {
- Ds1302ReadTime(); // 从DS1302读取时间存入gTime中
- YTD[2] = ((gTime[6] >> 4) & 0x0f)+48; // Hour的高4位
- YTD[3] = ((gTime[6] >> 0) & 0x0f)+48; // Hour的低4位
- YTD[6] = ((gTime[4] >> 4) & 0x0f)+48; // Minute的高4位
- YTD[7] = ((gTime[4] >> 0) & 0x0f)+48; // Minute的低4位
- YTD[10] = ((gTime[3] >> 4) & 0x0f)+48; // Second的高4位
- YTD[11] = ((gTime[3] >> 0) & 0x0f)+48; // Second的低4位
- }
复制代码 全部资料51hei下载地址:
代码.zip
(53.48 KB, 下载次数: 5)
|