一、首先是对于PCF8563芯片的介绍与使用说明:
PCF8563 是PHILIPS 公司推出的一款工业级内含I2C 总线接口功能的具有极低功耗的多功能时钟/日历芯片。PCF8563 的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。是一款性价比极高的时钟芯片,它已被广泛用于电表、水表、气表、电话、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。
多于的我并不想赘述了太多,我会将中英文手册和源码见后;由于PCF8563是IIC通讯的,又据说STM32芯片硬件IIC的问题(至于好不好用我还没试过,都是道听途说),所以采用模拟IIC完成本程序的通讯。
整个实现过程分成了两部分:
1.IIC底层驱动程序 IIC.c和 IIC.h ;
2.PCF8563.c 和 PCF8563.h;
下面开始我的代码表演(其实都是前辈们写烂了的代码,我又做了整理,思路符合自己更加清晰而已)!!!
二、IIC驱动程序
1.h头文件:
/******************************************************************************
* @ File name --> iic.h
* @ Brief --> MCU模拟IIC通讯函数
* @ --> 要改变传输频率,请修改延时函数中的数值即可
******************************************************************************/
#ifndef _iic_h_
#define _iic_h_
/******************************************************************************
外部函数头文件
******************************************************************************/
#include "system.h"
#include "Systick.h"
/******************************************************************************
外部引脚修改区
******************************************************************************/
/* IIC_SCL时钟端口、引脚定义 */
#define IIC_SCL_PORT GPIOB
#define IIC_SCL_PIN (GPIO_Pin_6)
#define IIC_SCL_PORT_RCC RCC_APB2Periph_GPIOB
/* IIC_SDA时钟端口、引脚定义 */
#define IIC_SDA_PORT GPIOB
#define IIC_SDA_PIN (GPIO_Pin_7)
#define IIC_SDA_PORT_RCC RCC_APB2Periph_GPIOB
/******************************************************************************
对于低速晶振的支持
是否使用延时函数进行调整通讯频率
******************************************************************************/
#define _USER_DELAY_CLK 1 //定义了则使用延时调整通讯频率
//0:不使用延时函数调整通讯频率,对于低速MCU时候用
//1:使用延时函数调整通讯频率,对于高速MCU时候用
/******************************************************************************
位带操作
******************************************************************************/
#define IIC_SCL PBout(6)
#define IIC_SDA PBout(7) //IIC发送数据用
#define IN_SDA PBin(7) //IIC读取数据用
/******************************************************************************
通讯频率延时函数
需要调整通讯频率的请修改此函数值即可
******************************************************************************/
#if _USER_DELAY_CLK==1 //定义了则使用
#define IIC_Delay() delay_us(2) //要改变请修改delay_us()中的数值即可
#endif
/******************************************************************************
外部功能函数
******************************************************************************/
void IIC_GPIO_Init(void); //GPIO初始化
void IIC_Start(void); //IIC启动
void IIC_Stop(void); //IIC停止
void IIC_Ack(u8 a); //主机向从机发送应答信号
u8 IIC_Write_Byte(u8 dat); //向IIC总线发送一个字节数据
u8 IIC_Read_Byte(void); //从IIC总线上读取一个字节数据
#endif /* end iic.h */
有一点需要注意的是,如果你想省事头里面包含的那两个头(一个是延时,一个是包含位带操作定义的103头文件),直接替换就好。
2.c文件
#include "iic.h"
/******************************************************************************
* Function Name --> IIC_GPIO_Init
* Description --> GPIO初始化
* Input --> none
* Output --> none
* Reaturn --> none
******************************************************************************/
void IIC_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(IIC_SCL_PORT_RCC|IIC_SDA_PORT_RCC,ENABLE);
GPIO_InitStructure.GPIO_Pin=IIC_SCL_PIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(IIC_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
IIC_SDA = 1; //置IIC总线空闲
IIC_SCL = 1;
}
/******************************************************************************
* Function Name --> SDA_OUT
* Description --> SDA输出配置
* Input --> none
* Output --> none
* Reaturn --> none
******************************************************************************/
void IIC_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
}
/******************************************************************************
* Function Name --> SDA_IN
* Description --> SDA输入配置
* Input --> none
* Output --> none
* Reaturn --> none
******************************************************************************/
void IIC_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
}
/******************************************************************************
* Function Name --> IIC启动
* Description --> SCL高电平期间,SDA由高电平突变到低电平时启动总线
* SCL: __________
* __________
* SDA: _____
* _______________
* Input --> none
* Output --> none
* Reaturn --> none
******************************************************************************/
void IIC_Start(void)
{
IIC_SDA_OUT(); //设置成输出
IIC_SDA = 1; //为SDA下降启动做准备
IIC_SCL = 1; //在SCL高电平时,SDA为下降沿时候总线启动
#if _USER_DELAY_CLK==1 /* 定义了则使用延时函数来改变通讯频率 */
IIC_Delay();
IIC_SDA = 0; //突变,总线启动
IIC_Delay();
IIC_SCL = 0;
IIC_Delay();
#else /* 否则不使用延时函数改变通讯频率 */
IIC_SDA = 0; //突变,总线启动
IIC_SCL = 0;
#endif /* end __USER_DELAY_CLK */
}
/******************************************************************************
* Function Name --> IIC停止
* Description --> SCL高电平期间,SDA由低电平突变到高电平时停止总线
* SCL: ____________________
* __________
* SDA: _________/
* Input --> none
* Output --> none
* Reaturn --> none
******************************************************************************/
void IIC_Stop(void)
{
IIC_SDA_OUT(); //设置成输出
IIC_SDA = 0; //为SDA上升做准备
#if _USER_DELAY_CLK==1 /* 定义了则使用延时函数来改变通讯频率 */
IIC_Delay();
IIC_SCL = 1; //在SCL高电平时,SDA为上升沿时候总线停止
IIC_Delay();
IIC_SDA = 1; //突变,总线停止
IIC_Delay();
#else /* 否则不使用延时函数改变通讯频率 */
IIC_SCL = 1; //在SCL高电平时,SDA为上升沿时候总线停止
IIC_SDA = 1; //突变,总线停止
#endif /* end __USER_DELAY_CLK */
}
/******************************************************************************
* Function Name --> 主机向从机发送应答信号
* Description --> none
* Input --> a:应答信号
* 0:应答信号
* 1:非应答信号
* Output --> none
* Reaturn --> none
******************************************************************************/
void IIC_Ack(u8 a)
{
IIC_SDA_OUT(); //设置成输出
if(a) IIC_SDA = 1; //放上应答信号电平
else IIC_SDA = 0;
#if _USER_DELAY_CLK==1 /* 定义了则使用延时函数来改变通讯频率 */
IIC_Delay();
IIC_SCL = 1; //为SCL下降做准备
IIC_Delay();
IIC_SCL = 0; //突变,将应答信号发送过去
IIC_Delay();
#else /* 否则不使用延时函数改变通讯频率 */
IIC_SCL = 1; //为SCL下降做准备
IIC_SCL = 0; //突变,将应答信号发送过去
#endif /* end __USER_DELAY_CLK */
}
/******************************************************************************
* Function Name --> 向IIC总线发送一个字节数据
* Description --> none
* Input --> dat:要发送的数据
* Output --> none
* Reaturn --> ack:返回应答信号
******************************************************************************/
u8 IIC_Write_Byte(u8 dat)
{
u8 i;
设计资源 培训 开发板 精华推荐
- LTC3245IDE 高效降压-升压型充电泵稳压 5V 输出的典型应用电路
- DC1397B-B,具有 1.25V 基准和 10ppm/摄氏度最大基准的 LTC2656BCUFD-H16 八路 SPI 16 位电压输出 DAC 的演示板
- STM32WB55xx 多协议无线 32 位 MCU 基于 ARM Cortex-M4 的典型应用,带 FPU、低功耗蓝牙和 802.15.4 无线电解决方案
- NCP300LSN30T1 3V LED条形图电压监视器的典型应用
- 【南京邮电校赛】三相逆变电路
- 使用 ROHM Semiconductor 的 BD48L35G-TL 的参考设计
- LTC3107 的典型应用 - 超低电压能量收集器和一次电池寿命延长器
- LT1942EUF 演示板,用于 TFT 电源和 LED 驱动器的四路转换器,Vin=3V-4.5V,Von=10V/2mA,Voff=-10V/2mA,AVdd=5V/40mA
- 使用 Analog Devices 的 LTC3851IUD-1 的参考设计
- LT1339、48VIN、5VOUT、50A 大功率降压转换器