一、首先是对于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;
上一篇:STM32使用模拟IIC实现24C02读取
下一篇:STM32模拟IIC驱动OLED屏 原理+源码
- 热门资源推荐
- 热门放大器推荐
设计资源 培训 开发板 精华推荐
- EVAL-ADXL354BZ,用于评估 ADXL354 低噪声、低漂移、低功耗、3 轴 MEMS 加速度计的评估板
- 一款用于手机的 LED 大功率 LED 驱动器
- 基于BlueNRG IC的Bluetooth®Smart USB dongle
- Super Dial 电机旋钮屏—esp32s3—v2
- MIKROE-2659,eINK CLICK 适配器板,用于通过 24 针带状电缆连接 eINK 显示器
- 用于 MCU 系统负载感应的 NCP300LSN185T1 1.85V 电压检测器的典型应用
- VL53L0X Nucleo Pack-包括VL53L0X扩展板和STM32F401RE Nucleo
- STM32F103C8T6
- 带丢失脉冲检测器或频率检测器的 NCP302LSN30T1 3V 电压检测器的典型应用
- VAR-DVK-OM37_CE7,基于安装了 Windows Embedded Compact 7 的 VAR-SOM-OM37 SOM 处理器的开发套件
- 首都医科大学王长明:针对癫痫的数字疗法已进入使用阶段
- 非常见问题解答第223期:如何在没有软启动方程的情况下测量和确定软启动时序?
- 兆易创新GD25/55全系列车规级SPI NOR Flash荣获ISO 26262 ASIL D功能安全认证证书
- 新型IsoVu™ 隔离电流探头:为电流测量带来全新维度
- 英飞凌推出简化电机控制开发的ModusToolbox™电机套件
- 意法半导体IO-Link执行器电路板为工业监控和设备厂商带来一站式参考设计
- Melexis采用无磁芯技术缩小电流感测装置尺寸
- 千丘智能侍淳博:用数字疗法,点亮“孤独症”儿童的光
- 数药智能冯尚:ADHD数字疗法正为儿童“多动症”提供更有效便捷服务
- Vicor高性能电源模块助力低空航空电子设备和 EVTOL的发展