硬件:PCF8563、STC15W4K32S4
PCF8563
有
16
个8位寄存器:一个可自动增量的地址寄存器,一个内置
32.768KHz
的
振荡器(带有一个内部集成的电容),一个分频器(用于给实时时钟
RTC
提供源时钟),一
个可编程时钟输出,一个定时器,一个报警器,一个掉电检测器和一个
400KHz
I
2
C
总线接口。
所有
16
个寄存器设计成可寻址的
8
位并行寄存器,但不是所有位都有用。前两个寄存
器(内存地址
00H
,
01H
)用于控制寄存器和状态寄存器,内存地址
02H
~
08H
用于时钟计
数器(秒
~
年计数器),地址
09H
~
0CH
用于报警寄存器(定义报警条件),地址
0DH
控制
CLKOUT
管脚的输出频率,地址
0EH
和
0FH
分别用于定时器控制寄存器和定时器寄存器。
秒、分钟、小时、日、月、年、分钟报警、小时报警、日报警寄存器,编码格式为
BCD
,
星期和星期报警寄存器不以
BCD
格式编码。
报警功能模式
一个或多个报警寄存器
MSB
(
AE=Alarm Enable
报警使能位)清0时,相应的报警条
件有效,这样,一个报警将在每分钟至每星期范围内产生一次。设置报警标志位
AF
(控制 /状态寄存器2的位3)用于产生中断,AF
只可以用软件清除。
![](https://img-blog.csdnimg.cn/direct/40ff6b7e17144fcb8b6d23f006017a72.png)
![](https://img-blog.csdnimg.cn/direct/b6b1b46a341f4a848f769fc93079eb1f.png)
![](https://img-blog.csdnimg.cn/direct/37a20d599f06498b9e55081a7ccb6043.png)
根据上述来来自数据手册的信息可知,分钟报警器的地址为09H,标志位为AF,即控制 /状态寄存器2(01H)的位3(Bit3)用于产生中断,且AF 只可以用软件清除;TF为定时器标志位。AIE为报警使能位,TIE为定时器使能位。
通过IIC向PCF8563写入数据,即iic_send_add_byte函数
//起始信号
void IIC_Start (void)
{
SDA =1;
SCL = 1;
Delay1us();
SDA = 0;
}
//I2C发送1个字节数据
void IIC_SendByte(unsigned char dite)
{
unsigned char i;
SDA = 0;
SCL =0;
Delay1us();
for(i=0;i<8;i++)
{
if(dite &0x80) SDA = 1;
else SDA =0;
Delay1us();
dite <<=1;
SCL = 1;
Delay1us();
SCL = 0;
Delay1us();
}
}
//等待应答
bit IIC_WaitAck(void)
{
bit i;
SCL = 1;
Delay1us();
i = SDA;
SCL = 0;
return i;
}
//终止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
Delay1us();
SDA = 1;
Delay1us();
}
void iic_send_add_byte(unsigned char add,unsigned char bat) //向某个地址发送某数据
{
IIC_Start();
IIC_SendByte(0xa2);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(bat);
IIC_WaitAck();
IIC_Stop();
}
使能AIE:iic_send_add_byte(0x01,0x02);
设置报警分钟时间:iic_send_add_byte(0x09,0x30);//每隔30分钟报警一次
清除标志位:iic_send_add_byte(0x01,0x02);
或者
unsigned char value;
unsigned char c_buf[8];
// 读取PCF8563寄存器中的值
c_buf[2] = PCF8563_ReadOneByte(0x01);
// 将BCD格式转换为二进制格式
value = ((c_buf[2] >> 4) & 0x0F) * 10 + (c_buf[2] & 0x0F);
// 清零第四位的数值(AF清零)
c_buf[2] &= 0xF7;
c_buf[2]=binaryToDecimal(c_buf[2]);
c_buf[2]=dec_bcd(c_buf[2]);
// 将二进制格式转换回BCD格式
//c_buf[2] = ((value / 10) << 4) | (value % 10);
iic_send_add_byte(0x01,c_buf[2]); //清零AF标志位
//读函数编写流程:start->发送设备地址->等待ACK->发送需要被读的内存地址->等待ACK->发送读指令(设备地址)->等待ACK-->读内存数据->等待no ACK->STOP
unsigned char PCF8563_ReadOneByte(unsigned char Adddrsend)
{
unsigned char Rec;
IIC_Start();
IIC_SendByte(0xA2);//通过I2C总线发送数据(芯片指令)写操作
IIC_WaitAck();
IIC_SendByte(Adddrsend);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xA3);
IIC_WaitAck();
Rec=IIC_RecByte();
IIC_Stop();
return Rec;
}
代码可以运行但感觉有更好的方法
新手,求大佬教教😍