通信协议与传感器1
摘要:DS1302是一款实时时钟芯片,具有精准计时、掉电保持和31字节RAM存储功能。其核心功能通过CH位控制时钟启停、WP位实现写保护,采用BCD编码和特定时序通信。硬件需配置32.768kHz晶振和后备电池。驱动程序包含写入/读取时间函数,通过解除/恢复写保护确保数据安全,使用时需注意BCD码转换和地址计算(如时寄存器地址0x84)。典型应用包括设置初始时间并循环读取显示,适用于需要精确计时的
·
通信协议与传感器1 |SPI协议-DS1302
一、模块功能
DS1302 是一款实时时钟(RTC)芯片,广泛应用于嵌入式系统中,核心功能如下:
- 精准计时:可记录年、月、日、时、分、秒,支持闰年自动修正,兼容 12/24 小时制切换
- 掉电保持:内置后备电池供电电路,主电源断电后仍能持续计时,时间数据不丢失
- 涓流充电:支持对备用电池进行涓流充电,延长断电续航时间
- 数据存储:内置 31 字节静态 RAM,可存储少量用户自定义数据
- 简化通信:采用三线制串行接口(CE、SCLK、IO),与 SPI 时序兼容,减少硬件引脚占用
二、工作原理
- 核心实现原理


1. 核心控制位
- CH 位(时钟启停位)
- 位置:秒寄存器(80H/81H)第 7 位
- 功能:
CH=1晶振停止(时间冻结),CH=0晶振启动(开始计时),上电默认CH=1 - 关键:初始化后必须置 0,否则芯片不计时
- WP 位(写保护位)
- 位置:写保护寄存器(8EH/8FH)第 7 位
- 功能:
WP=1禁止写入(防误改),WP=0允许写入 - 关键:写入前必须解除保护,写入后必须恢复保护
2. 编码与时序规则
- BCD 编码:用 4 位二进制表示 1 位十进制数(如 25 → 0x25),读写时需完成十进制 ↔ BCD 转换,不可直接写入十进制数。
- 通信时序:RST 拉高激活芯片,SCLK 上升沿发送数据、下降沿接收数据,通信结束后 RST 拉低,时序不匹配会导致通信失败。
- 小时模式:支持 12/24 小时制,第 7 位 = 1 为 12 小时制(带 AM/PM),第 7 位 = 0 为 24 小时制,初始化时需明确选择。
3. 硬件要求
- 晶振必须为 32.768kHz,焊接可靠;后备电池电压需充足,否则断电后时间丢失。
- 寄存器未使用的高位必须写 0,否则可能引发功能异常。
1.初始化时间
- 解除写保护:向 8EH 寄存器写入
0x00,将 WP 位置 0。 - 写入时间数据:将十进制时间转换为 BCD 码,依次写入秒(80H)、分(82H)、时(84H)、日(86H)、月(88H)、周(8AH)、年(8CH)寄存器,写入秒寄存器时将 CH 位置 0。
- 开启写保护:向 8EH 寄存器写入
0x80,将 WP 位置 1。
2. 读取时间
- (可选)临时解除写保护:向 8EH 写入
0x00。 - 依次读取秒(81H)、分(83H)、时(85H)等寄存器。
- 将寄存器中的 BCD 码转换为十进制(如 0x25 → 25),用于显示或计算。
- 恢复写保护:向 8EH 写入
0x80。
三、硬件配置
- 晶振:32.768kHz 晶振连接 X1、X2 引脚,搭配电容后接地。
- 电源:VCC2 接单片机 3.3V/5V 主电源,VCC1 接 3V 纽扣电池。
- 通信:RST(P13)、SCLK(P17)、I/O(P23)分别连接单片机 GPIO。
四、完整代码实现
- 可直接运行的示例代码
/*
程序说明: DS1302驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include <reg52.h>
#include <intrins.h>
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
void Write_Ds1302(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )
{
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
Write_Ds1302(dat);
RST=0;
}
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0; _nop_();
SCK=0; _nop_();
RST=1; _nop_();
Write_Ds1302(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0; _nop_();
SCK=0; _nop_();
SCK=1; _nop_();
SDA=0; _nop_();
SDA=1; _nop_();
return (temp);
}
时间设置函数:Set_Rtc
void Set_Rtc(unsigned char* ucRtc)
{
unsigned char i;
Write_Ds1302_Byte(0x8e, 0x00); // 向8EH(写保护寄存器)写0x00,解除写保护(WP=0)
for (i=0; i<3; i++) // 循环写入时、分、秒(共3个时间字段)
{
// 0x84-2*i:地址计算逻辑
// i=0 → 0x84(时寄存器写地址),i=1 → 0x82(分),i=2 → 0x80(秒)
Write_Ds1302_Byte(0x84-2*i, ucRtc[i]);
}
Write_Ds1302_Byte(0x8e, 0x80); // 向8EH写0x80,开启写保护(WP=1)
}
- 参数说明:
ucRtc是字符数组指针,数组顺序为[时, 分, 秒](均为 BCD 码)。 - 地址计算:利用
0x84-2*i实现地址递减(84H→82H→80H),对应时、分、秒的写地址。 - 保护机制:先解除写保护,写入完成后立即恢复,防止数据误改。
5. 时间读取函数:Read_Rtc
void Read_Rtc(unsigned char* ucRtc)
{
unsigned char i;
for (i=0; i<3; i++)
{
// 0x85-2*i:地址计算逻辑
// i=0 → 0x85(时寄存器读地址),i=1 → 0x83(分),i=2 → 0x81(秒)
ucRtc[i] = Read_Ds1302_Byte (0x85-2*i);
}
}
- 参数说明:
ucRtc是输出数组指针,读取后数组存储[时, 分, 秒]的 BCD 码数据。 - 地址计算:读地址 = 写地址 + 1(如时写地址 84H→读地址 85H),因此用
0x85-2*i对应。 - 无需解除保护:读取操作不受 WP 位限制,直接读取即可。
使用示例
// 主函数示例:设置时间并读取显示
void main()
{
unsigned char rtc_data[3];
// 初始化时间:12时30分00秒(BCD码:12→0x12,30→0x30,00→0x00)
rtc_data[0] = 0x12; // 时
rtc_data[1] = 0x30; // 分
rtc_data[2] = 0x00; // 秒(CH位=0,启动计时)
Set_Rtc(rtc_data); // 设置时间
while(1)
{
Read_Rtc(rtc_data); // 循环读取时间
// 此处可添加数码管显示代码,将rtc_data中的BCD码转为十进制显示
}
}
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)