# 8 DS1302实时时钟
[toc]
注:笔记主要参考B站江科大自化协教学视频“[51单片机入门教程-2020版 程序全程纯手打 从零开始入门](https://www.bilibili.com/video/BV1Mb411e7re?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click)”。
注:工程及代码文件放在了本人的[Github仓库](https://github.com/jjejdhhd/Learn_STC89C52)。
***
## 8.1 芯片介绍:DS1302
RTC(Real Time Clock)实时时钟,是一种集成电路,通常称为时钟芯片。常见的时钟芯片有DS1302,是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能。**本节的关键在于DS1302的时序。**
<div align=center>
<img src="https://raw.githubusercontent.com/jjejdhhd/Git_img2023/main/8051chip/DS1302%E5%AE%9E%E7%89%A9%E5%9B%BE.png" width=80%>
</div><div align=center>
图8-1 DS1302实物图
</div>
那为什么不使用单片机上的定时器来驱动实时时钟呢?
> 1. CPU内的定时器精度不高。
> 2. 使用定时器会占用CPU的内部资源。
> 3. 单片机定时器掉电不能继续工作。
>
<div align=center>
<img src="https://raw.githubusercontent.com/jjejdhhd/Git_img2023/main/8051chip/DS1302%E5%8E%9F%E7%90%86%E5%9B%BE.png" width=40%>
</div><div align=center>
图8-2 DS1302原理图
</div>
> 芯片引脚说明:
> CE:输入,芯片使能引脚。
> SCLK:输入,串行接口时钟。
> I/O:双向,输入输出的串行数据,SCLK上升沿触发。
基本逻辑是利用下面的寄存器地址说明(图8-4),写入的时候按需更改相应的秒数,读出的时候则依次进行读出。前八位是读写的选择和读写的地址,后八位才是具体要进行读写的数据,且**先传输低位**。前八位也被称为<u>命令字,最高位写保护,控制能否串行写入(1/0),但一直可以读;R/C选择是RAM数据/时钟数据(1/0);A4~A0则为5位寄存器地址;R/W位则控制读写(1/0)。</u>下面则给出了DS1602的读/写传输时序、寄存器操作地址:
<div align=center>
<img src="https://raw.githubusercontent.com/jjejdhhd/Git_img2023/main/8051chip/DS1602%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E6%97%B6%E5%BA%8F.png" width=60%>
</div><div align=center>
图8-3 DS1302数据传输时序
</div>
<div align=center>
<img src="https://raw.githubusercontent.com/jjejdhhd/Git_img2023/main/8051chip/DS1602%E5%AF%84%E5%AD%98%E5%99%A8%E5%9C%B0%E5%9D%80.png" width=70%>
</div><div align=center>
图8-4 RTC相关寄存器
注:左侧的八位是直接给出了**命令字**。
</div>
值得注意的是,上面寄存器所显示的数据,都采用BCD码(Binary Coded Decimal)进行编码:
> - 用4位二进制数来表示1位十进制数
> 例:0001 0011表示13,1000 0101表示85,0001 1010不合法
> 在十六进制中的体现:0x13表示13,0x85表示85,0x1A不合法
> - BCD码转十进制:DEC=BCD/16\*10+BCD%16; (2位BCD)
> 十进制转BCD码:BCD=DEC/10\*16+DEC%10; (2位BCD)
> - CH位:时停控制位,写入此位为高电平,则时钟暂停。
> - 12/24位:设置12小时/24小时模式位。12小时模式,BIT5表示AM/PM,BIT4表示十位;24小时模式,[BIT5,BIT4]表示十位。
> - 关于星期:注意这个星期不是实际的星期,而是“处理日”,所以需要用户指定初始的星期偏置。
## 8.2 实验:DS1302时钟显示
需求:在LCD显示屏第一行显示日期“年-月-日”,第二行显示时间“时-分-秒”,24小时制。
<div align=center>
<img src="https://raw.githubusercontent.com/jjejdhhd/Git_img2023/main/8051chip/%E4%BB%A3%E7%A0%81%E8%B0%83%E7%94%A8%E5%85%B3%E7%B3%BB-%E5%AE%9E%E6%97%B6%E6%97%B6%E9%92%9F.png" width=20%>
</div><div align=center>
图8-5 “实时时钟”代码调用关系
</div>
代码展示:
**- main.c**
```c
#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"
unsigned char DS1302_info[7];
void main(){
unsigned char i=0;
// 初始化LCD显示屏
LCD_Init();
LCD_ShowString(1,1,"2023-01-01");
LCD_ShowString(2,1,"00:00:00");
DS1302_Init();//初始化DS1302
while(1){
DS1302_ReadAll(&DS1302_info);
LCD_ShowNum(1,3,DS1302_info[0],2);
LCD_ShowNum(1,6,DS1302_info[1],2);
LCD_ShowNum(1,9,DS1302_info[2],2);
LCD_ShowDay(1,14,DS1302_info[3]);
LCD_ShowNum(2,1,DS1302_info[4],2);
LCD_ShowNum(2,4,DS1302_info[5],2);
LCD_ShowNum(2,7,DS1302_info[6],2);
}
}
```
**- DS1302.h**
```c
#ifndef __DS1302_H__
#define __DS1302_H__
void DS1302_Init(void);//初始化DS1302
unsigned char DS1302_ReadByte(unsigned char read_comd);//从DS1302中读出数据
void DS1302_WriteByte(unsigned char wri_comd,wri_byte);//向DS1302中写入数据
void DS1302_ReadAll(unsigned char *info);//读出所有信息
#endif
```
**- DS1302.c**
```c
#include <REGX52.H>
// 将端口重新定义
sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_CE = P3^5;
#define DS1302_RSEC 0x81
#define DS1302_RMIN 0x83
#define DS1302_RHOU 0x85
#define DS1302_RDAT 0x87
#define DS1302_RMON 0x89
#define DS1302_RDAY 0x8B
#define DS1302_RYEA 0x8D
#define DS1302_RWP 0x8F
#define DS1302_WSEC 0x80
#define DS1302_WMIN 0x82
#define DS1302_WHOU 0x84
#define DS1302_WDAT 0x86
#define DS1302_WMON 0x88
#define DS1302_WDAY 0x8A
#define DS1302_WYEA 0x8C
#define DS1302_WWP 0x8E
/**
* @brief :从DS1302中读出数据
* @param :需要操作的命令字read_comd。
* @retval :读出的数据read_byte。
*/
unsigned char DS1302_ReadByte(unsigned char read_comd){
unsigned char read_byte = 0x00;
unsigned char i;
DS1302_CE = 1;
// 写入命令字
for(i=0;i<8;i++){
DS1302_IO = read_comd&(0x01<<i);
DS1302_SCLK = 0;
DS1302_SCLK = 1; // 经过测试,不需延时
}
// 读出数据
for(i=0;i<8;i++){
DS1302_SCLK = 1;
DS1302_SCLK = 0;
read_byte = DS1302_IO ? (read_byte|(0x01<<i)) : read_byte;
}
DS1302_IO = 0; //注意最后一定要将数据线清零
DS1302_CE = 0;
return read_byte;
}
/**
* @brief :向DS1302中写入数据
* @param :需要操作的命令字wri_comd,需要写入的数据wri_byte。
* @retval :无。
*/
void DS1302_WriteByte(unsigned char wri_comd,wri_byte){
unsigned char i;
DS1302_CE = 1;
// 写入命令字
for(i=0;i<8;i++){
DS1302_IO = wri_comd&(0x01<<i);
DS1302_SCLK = 0;
DS1302_SCLK = 1; // 经过测试,不需延时
}
// 写入8位数据
for(i=0;i<8;i++){
DS1302_IO = wri_byte&(0x01<<i);
DS1302_SCLK = 0;
DS1302_SCLK = 1; // 经过测试,不需延时
}
DS1302_SCLK = 0;
DS1302_CE = 0;
}
/**
* @brief :初始化控制DS1302的引脚。
* @param :无。
* @retval :无。
*/
void DS1302_Init(void){
DS1302_SCLK = 0;
DS1302_IO = 0;
DS1302_CE = 0;
DS1302_WriteByte(DS1302_WWP,0x00);//解除写保护
DS1302_WriteByte(DS1302_WSEC,0x00);//解除时钟暂停
// 默认为24小时模式
}
/**
* @brief :从单片机中读出年/月/日/星期/时/分/秒
* @param :数组指针,存储年/月/日/星期/时/分/秒。
* @retval :无。程序中通过指针解引用更改信息。
*/
void DS1302_ReadAll(unsigned char *info){
unsigned char temp;
// 年
temp = DS1302_ReadByte(DS1302_RYEA);
*info = (temp>>4)*10 + (temp&0x0f);
// 月
temp = DS1302_ReadByte(DS1302_RMON);
*(info+1) = (temp>>4)*10 + (temp&0x0f);
// 日
temp = DS1302_ReadByte(DS1302_RDAT);
*(info+2) = (temp>>4)*10 + (temp&0x0f);
// 星期
*(info+3) = DS1302_ReadByte(DS1302_RDAY);
// 时
temp = DS1302_ReadByte(DS1302_RHOU);
if(!(temp&0x80)){*(info+4) = (temp>>4)*10 + (temp&0x0f);}
else {*(info+4) = ((temp&0x10)>>4)*10 + (temp&0x0f);}
// 分
temp = DS1302_ReadByte(DS1302_RMIN);
*(info+5) = ((temp&0x70)>>4)*10 + (temp&0x0f);
// 秒
temp = DS1302_ReadByte(DS1302_RSEC);
*(info+6) = ((temp&0x70)>>4)*10 + (temp&0x0f);
}
```
**- LCD1602.h*
没有合适的资源?快使用搜索试试~ 我知道了~
和B站UP江科大自化协学习51单片机.zip
共169个文件
h:70个
c:60个
zip:23个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 77 浏览量
2023-08-01
18:03:21
上传
评论
收藏 1.03MB ZIP 举报
温馨提示
关于51单片机的相关资料,资料真实可靠,需要的朋友自行下载即可。
资源推荐
资源详情
资源评论
收起资源包目录
和B站UP江科大自化协学习51单片机.zip (169个子文件)
LCD1602.c 9KB
LCD1602.c 9KB
LCD1602.c 9KB
LCD1602.c 9KB
LCD1602.c 9KB
LCD1602.c 9KB
main.c 6KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
LCD1602.c 5KB
DS1302.c 4KB
DS1302.c 4KB
AT24C02.c 3KB
AT24C02.c 3KB
AT24C02.c 3KB
HS0038.c 3KB
main.c 3KB
HS0038.c 3KB
Timer0.c 2KB
Timer0.c 2KB
main.c 2KB
Matrix_LED.c 2KB
main.c 2KB
_1Wire.c 2KB
_1Wire.c 2KB
main.c 2KB
Matrix_LED.c 2KB
NixieTube.c 1KB
main.c 1KB
DC_Motor.c 1KB
main.c 1KB
DS18B20.c 1KB
UART.c 1KB
main.c 1KB
DS18B20.c 1KB
UART.c 993B
main.c 983B
main.c 942B
main.c 913B
main.c 858B
main.c 830B
main.c 788B
main.c 707B
Buzzer.c 694B
Buzzer.c 694B
main.c 680B
main.c 620B
main.c 601B
main.c 596B
main.c 560B
main.c 373B
main.c 297B
main.c 295B
main.c 277B
MatrixKey.h 2KB
MatrixKey.h 2KB
Timer0.h 1KB
Timer0.h 1KB
Timer0.h 1KB
Timer0.h 1KB
Timer0.h 1KB
Timer0.h 1KB
NixieTube.h 1KB
LCD1602.h 1KB
LCD1602.h 1KB
LCD1602.h 1KB
LCD1602.h 1KB
LCD1602.h 1KB
LCD1602.h 1KB
PushKey.h 1KB
PushKey.h 1KB
PushKey.h 1KB
PushKey.h 1KB
PushKey.h 1KB
Timer0.h 1KB
Timer0.h 1KB
HS0038.h 964B
HS0038.h 964B
Timer1.h 958B
PushKey.h 786B
PushKey.h 786B
PushKey.h 786B
LCD1602.h 732B
LCD1602.h 732B
LCD1602.h 732B
LCD1602.h 732B
LCD1602.h 732B
LCD1602.h 655B
LCD1602.h 655B
LCD1602.h 655B
LCD1602.h 655B
NixieTube.h 546B
NixieTube.h 546B
PushKey.h 524B
共 169 条
- 1
- 2
资源评论
c++服务器开发
- 粉丝: 3047
- 资源: 4462
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功