STM32模拟IIC读取PCF8563

发布者:大泉人家最新更新时间:2019-08-10 来源: eefocus关键字:STM32  模拟IIC  读取PCF8563 手机看文章 扫描二维码
随时随地手机看文章

一、首先是对于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;

[1] [2] [3] [4] [5] [6]
关键字:STM32  模拟IIC  读取PCF8563 引用地址:STM32模拟IIC读取PCF8563

上一篇:STM32使用模拟IIC实现24C02读取
下一篇:STM32模拟IIC驱动OLED屏 原理+源码

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved