使用PCF8563实现硬件看门狗

在使用STM32的过程中,发现有需求使用到硬件看门狗,定时时长1小时,PCF8563 可以有从秒 分 时的倒计时的功能,倒计时结束后触发中断,复位STM32的电源,从而实现硬件看门狗的功能。

PCF8563库下载地址https://github.com/dong930623/PCF8563

具体使用方法 

PB6 连接 SCL

PB7 连接 SDA

使用时,先进行初始化

PCF8563_Init_Register();

后定时复位倒计时的时间

PCF8563_rest (void);

具体实现如下

PCF8563.c

  1 /***************************************************************************
  2 ** 版权所有:             
  3 ** 文件名称:  PCF8563.c
  4 ** 内容摘要:  PCF8563 读写函数
  5 ** 当前版本:  v1.0
  6 ** 作    者:  Donny
  7 ** 创建日期: 2017年10月12日
  8 ** 修改记录: 
  9 ** 修改日期: 
 10 ** 版本号  : 
 11 ** 修改人  : 
 12 ** 修改内容: 
 13 ***************************************************************************/
 14 
 15 #include "PCF8563.h"
 16 #include "delay.h" 
 17 
 18 void IIC_Init(void)
 19 {                         
 20     GPIO_InitTypeDef GPIO_InitStructure;
 21     //RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟 
 22     RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOC, ENABLE );    
 23                          
 24     //GPIOC->CRH&=0XFFF00FFF;//PC11/12 推挽输出
 25     //GPIOC->CRH|=0X00033000;       
 26     GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN;
 27     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
 28     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 29     GPIO_Init(IIC_SCL_PORT, &GPIO_InitStructure);
 30     GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
 31     GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure); 
 32     Set_IIC_SCL;
 33     Set_IIC_SDA;
 34 }
 35 //产生IIC起始信号
 36 void IIC_Start(void)
 37 {
 38     SDA_OUT();     //sda线输出
 39     Set_IIC_SDA;            
 40     Set_IIC_SCL;
 41     delay_us(4);
 42      Clr_IIC_SDA;//START:when CLK is high,DATA change form high to low 
 43     delay_us(4);
 44     Clr_IIC_SCL;//钳住I2C总线,准备发送或接收数据 
 45 }      
 46 //产生IIC停止信号
 47 void IIC_Stop(void)
 48 {
 49     SDA_OUT();//sda线输出
 50     Clr_IIC_SCL;
 51     Clr_IIC_SDA;//STOP:when CLK is high DATA change form low to high
 52      delay_us(4);
 53     Set_IIC_SCL; 
 54     Set_IIC_SDA;//发送I2C总线结束信号
 55     delay_us(4);                                   
 56 }
 57 //等待应答信号到来
 58 //返回值:1,接收应答失败
 59 //        0,接收应答成功
 60 u8 IIC_Wait_Ack(void)
 61 {
 62     u8 ucErrTime=0;
 63     SDA_IN();      //SDA设置为输入  
 64     Set_IIC_SDA;delay_us(1);       
 65     Set_IIC_SCL;delay_us(1);     
 66     while(READ_SDA)
 67     {
 68         ucErrTime++;
 69         if(ucErrTime>250)
 70         {
 71             IIC_Stop();
 72             return 1;
 73         }
 74     }
 75     Clr_IIC_SCL;//时钟输出0        
 76     return 0;  
 77 } 
 78 //产生ACK应答
 79 void IIC_Ack(void)
 80 {
 81     Clr_IIC_SCL;
 82     SDA_OUT();
 83     Clr_IIC_SDA;
 84     delay_us(2);
 85     Set_IIC_SCL;
 86     delay_us(2);
 87     Clr_IIC_SCL;
 88 }
 89 //不产生ACK应答            
 90 void IIC_NAck(void)
 91 {
 92     Clr_IIC_SCL;
 93     SDA_OUT();
 94     Set_IIC_SDA;
 95     delay_us(2);
 96     Set_IIC_SCL;
 97     delay_us(2);
 98     Clr_IIC_SCL;
 99 }                                          
100 //IIC发送一个字节
101 //返回从机有无应答
102 //1,有应答
103 //0,无应答              
104 void IIC_Send_Byte(u8 txd)
105 {                        
106     u8 t;   
107       SDA_OUT();         
108     Clr_IIC_SCL;//拉低时钟开始数据传输
109     for(t=0;t<8;t++)
110     {              
111         //IIC_SDA=(txd&0x80)>>7;
112         if ((txd&0x80)>>7)     Set_IIC_SDA
113         else Clr_IIC_SDA;
114     txd<<=1;       
115         delay_us(2);   //对TEA5767这三个延时都是必须的
116         Set_IIC_SCL;
117         delay_us(2); 
118         Clr_IIC_SCL;    
119         delay_us(2);
120     }     
121 }         
122 //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
123 u8 IIC_Read_Byte(unsigned char ack)
124 {
125     unsigned char i,receive=0;
126     SDA_IN();//SDA设置为输入
127   for(i=0;i<8;i++ )
128     {
129         Clr_IIC_SCL; 
130         delay_us(2);
131         Set_IIC_SCL;
132         receive<<=1;
133         if(READ_SDA)receive++;   
134         delay_us(1); 
135     }                     
136     if (!ack)
137         IIC_NAck();//发送nACK
138     else
139         IIC_Ack(); //发送ACK   
140     return receive;
141 }
142 //在PCF5368指定地址读出一个数据
143 //ReadAddr:开始读数的地址  
144 //返回值  :读到的数据
145 u8 PCF5368_ReadOneByte(u8 ReadAddr)
146 {                  
147     u8 temp=0;                                                                                   
148     IIC_Start();   
149     IIC_Send_Byte(0XA2);       //发送写命令
150     IIC_Wait_Ack();   
151   IIC_Send_Byte(ReadAddr);   //发送低地址
152     IIC_Wait_Ack();        
153     IIC_Start();              
154     IIC_Send_Byte(0XA3);           //进入接收模式               
155     IIC_Wait_Ack();     
156   temp=IIC_Read_Byte(0);           
157   IIC_Stop();//产生一个停止条件        
158     return temp;
159 }
160 //在PCF5368指定地址写入一个数据
161 //WriteAddr  :写入数据的目的地址    
162 //DataToWrite:要写入的数据
163 void PCF5368_WriteOneByte(u8 WriteAddr,u8 DataToWrite)
164 {                                                                                                  
165   IIC_Start();   
166     IIC_Send_Byte(0XA2);        //发送写命令
167     IIC_Wait_Ack();
168     IIC_Send_Byte(WriteAddr);//发送高地址
169     IIC_Wait_Ack();                                                                
170     IIC_Send_Byte(DataToWrite);     //发送字节                               
171     IIC_Wait_Ack();                     
172     IIC_Stop();//产生一个停止条件 
173     delay_ms(10);     
174 } 
175 /***************************************************************************//**
176  * @brief
177  *  看门狗传感器初始化
178  *
179  ******************************************************************************/
180 void PCF8563_Init_Register (void)
181 {
182     IIC_Init();     
183     //停止定时器计数  
184     PCF5368_WriteOneByte (0x00, 0x20); 
185     //定时器产生脉冲中断
186     PCF5368_WriteOneByte (0x01, 0x11); 
187     //倒数定时器 60分钟
188     PCF5368_WriteOneByte ( 0x0E, 0x83); 
189     PCF5368_WriteOneByte ( 0x0F, 60); 
190     PCF5368_WriteOneByte ( 0x00, 0x00);      
191 }
192 /***************************************************************************//**
193  * @brief
194  *    获取倒计时的时间
195  *
196  ******************************************************************************/
197 int PCF8563_Gettime (void)
198 {    
199     return PCF5368_ReadOneByte(0x0F) & 0xff;         
200 }
201 /***************************************************************************//**
202  * @brief
203  *    复位倒计时的时间
204  *
205  ******************************************************************************/
206 void PCF8563_rest (void)
207 {   
208     //停止定时器计数  
209     PCF5368_WriteOneByte (0x00, 0x20); 
210     //定时器产生脉冲中断
211     PCF5368_WriteOneByte (0x01, 0x11); 
212     //倒数定时器 60分钟
213     PCF5368_WriteOneByte (0x0E, 0x83); 
214     PCF5368_WriteOneByte (0x0F, 60); 
215     PCF5368_WriteOneByte (0x00, 0x00);          
216 }

PCF8563.h

#ifndef __PCF8563_H
#define    __PCF8563_H

#include "stm32f10x.h"
//Mini STM32开发板
//IIC 驱动函数
//正点原子@ALIENTEK
//2010/6/10 

#define IIC_SCL_PORT              GPIOB
#define IIC_SCL_CLK               RCC_APB2Periph_GPIOB 
#define IIC_SCL_PIN               GPIO_Pin_6

#define IIC_SDA_PORT              GPIOB
#define IIC_SDA_CLK               RCC_APB2Periph_GPIOB  
#define IIC_SDA_PIN               GPIO_Pin_7

extern GPIO_InitTypeDef  GPIO_InitStructure;                     
//IO方向设置
#define SDA_IN()  {                                           
                                     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;  
                                     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
                   GPIO_Init(GPIOB, &GPIO_InitStructure);    
                                    }
#define SDA_OUT() {                                          
                                     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; 
                                     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          
                                     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
                   GPIO_Init(GPIOB, &GPIO_InitStructure);    
                                    }


//IO操作函数     
//#define IIC_SCL    PCout(12) //SCL
#define Set_IIC_SCL  {GPIO_SetBits(IIC_SCL_PORT,IIC_SCL_PIN);}
#define Clr_IIC_SCL  {GPIO_ResetBits(IIC_SCL_PORT,IIC_SCL_PIN);} 
//#define IIC_SDA    PCout(11) //SDA
#define Set_IIC_SDA  {GPIO_SetBits(IIC_SDA_PORT,IIC_SDA_PIN);}
#define Clr_IIC_SDA  {GPIO_ResetBits(IIC_SDA_PORT,IIC_SDA_PIN);} 
//#define READ_SDA   PCin(11)  //输入SDA 
#define READ_SDA    (GPIO_ReadInputDataBit(IIC_SDA_PORT, IIC_SDA_PIN))

     


//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口                 
void IIC_Start(void);                //发送IIC开始信号
void IIC_Stop(void);                  //发送IIC停止信号
void IIC_Send_Byte(u8 txd);            //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void);                 //IIC等待ACK信号
void IIC_Ack(void);                    //IIC发送ACK信号
void IIC_NAck(void);                //IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);     
void PCF8563_Init_Register (void);
void PCF8563_rest (void);
int PCF8563_Gettime (void);

#endif
原文地址:https://www.cnblogs.com/-Donny/p/7657742.html