3回答

0收藏

机智云IIC代码介绍

机智云GoKit 机智云GoKit 4663 人阅读 | 3 人回复 | 2015-11-02

本帖最后由 rui199009 于 2015-11-3 19:08 编辑

10天前发了两篇帖子,分别是机智云代码介绍和can总线的学习。今天就来学习下另一种通信方式:IIC通信(I2C)。IIC通信和can总线不同,can总线的两根通信线分别代表CANHCANL,不需要时钟。耳IIC通信却需要时钟进行同步,因此IIC由数据线和时钟线构成。其中 IIC的时钟线和数据线的高低电平只要在通信协议的标准范围内都可以,但是要注意的是不同芯片的IIC电压范围不同,有的需要加电平转换芯片,防止芯片被烧毁。


IIC通信有两种实现方式,一种是硬件IIC,另一种是模拟IIC。硬件IIC较为快速,占用资源少,只需要配置相关寄存器就可以使用,较省电,但是用法复杂。模拟IIC更容易理解通信过程,便于移植到各种单片机平台,可以在任意IO引脚上使用。

首先先从硬件IIC开始,结合机智云的代码进行讲解。机智云IIC代码写的比较丰富(哈哈,太长了,虽然在配置时很方便,但是不是很容易理解其中的运行过程),粗略看下接近1000行,下面就仔细的一个部分一个部分的解读下(比较长,请耐心观看)。


首先,是一部分宏定义。主要是对于STM32F103IIC通信中所用到的寄存器的对应位进行配置,最终达到使用IIC进行通信的功能。涉及到的寄存器有CR1CR2OAR1CAR2CCR等。
CR1_PE_Set:启用IIC模块。
CR1_PE_Reset:禁用IIC模块。
CR1_START_Set:主模式下,重复产生起始条件;从模式下,当总线空闲时,产生起始条件。
CR1_START_Reset:主模式下,无起始条件产生;从模式下,无起始条件产生。
CR1_STOP_Set:主模式下,在当前字节传输或在当前起始条件发出后产生停止条件;从模式下,在当前字节传输或释放SCLSDA线。
CR1_STOP_Reset:主模式下,无停止条件产生;从模式下,无停止条件产生。
CR1_ACK_Set:在接收到一个字节后返回一个应答(匹配的地址或数据)。
CR1_ACK_Reset:无应答返回。
CR1_ENGC_Set:允许广播呼叫,以应答响应地址00h
CR1_ENGC_Reset:禁止广播呼叫,以非应答响应地址00h
CR1_SWRST_SetIIC模块处于复位状态。
CR1_SWRST_ResetIIC模块不处于复位状态。
CR1_PEC_SetPEC传输(在发送或接受模式)。
CR1_PEC_Reset:无PEC传输。
CR1_ENPEC_Set:开启PEC计算。
CR1_ENPEC_Reset:禁止PEC计算。
CR1_ENARP_Set:使能ARP
CR1_ENARP_Reset:禁止ARP
CR1_NOSTRETCH_Set:禁止时钟延长。
CR1_NOSTRETCH_Reset:允许时钟延长。
CR1_CLEAR_Mask:该位不是寄存器位,是用来初始化CR1寄存器的一个值。

CR2_DMAEN_Set:当TxE= 1RxNE=1时,允许DMA请求。
CR2_DMAEN_Reset:禁止DMA请求。
CR2_LAST_Set:下一次DMAEOT是最后的传输。
CR2_LAST_Reset:下一次DMAEOT不是最后的传输。
CR2_FREQ_Reset:用于设置正确的输入时钟频率以产生正确的时序,允许的范围在2~36Hz之间。000000:禁用。000001:禁用。0000102MHz……..100100:36MHz。大于100100:禁用。

OAR1_ADD0_Set10位地址模式时为地址第0位。
OAR1_ADD0_Reset7位地址模式时不用关心。

OAR2_ENDUAL_Set:在7位地址模式下,OAR1OAR2都被识别。
OAR2_ENDUAL_Reset:在7位地址模式下,只有OAR1被识别。
OAR2_ADD2_Reset:自身地址寄存器2初始化,0xFF01

CCR_FS_Set:快速模式的IIC
CCR_CCR_Set:快速/标准模式下的时钟控制分频系数(主模式)。初始值,0x0FFF

FLAG_Mask:标志初始值0x00FFFFFF
ITEN_Mask:中断使能标识0x07000000
以上所述的均是机智云IIC通信中所需要的寄存器及相关位。


以下是IIC通信的相关函数。
void I2C_DeInit(I2C_TypeDef* I2Cx),取消I2Cx外设寄存器默认值的初始化

void I2C_Init(I2C_TypeDef* I2Cx,I2C_InitTypeDef* I2C_InitStruct),根据I2C_InitStruct结构体中的特定参数初始化I2C外设。

void I2C_StructInit(I2C_InitTypeDef*I2C_InitStruct),用默认值填充I2C_InitStruct结构体中的成员变量。

void I2C_Cmd(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止特定的IIC外设。

void I2C_DMACmd(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止特定的IICDMA请求。

void I2C_DMALastTransferCmd(I2C_TypeDef*I2Cx, FunctionalState NewState),指定下一个DMA传输是最后一个。

void I2C_GenerateSTART(I2C_TypeDef* I2Cx,FunctionalState NewState),产生IIC传输启动条件。

void I2C_GenerateSTOP(I2C_TypeDef* I2Cx,FunctionalState NewState),产生IIC传输停止条件。

void I2C_AcknowledgeConfig(I2C_TypeDef*I2Cx, FunctionalState NewState),使能或禁止指定IIC的响应特征。

void I2C_OwnAddress2Config(I2C_TypeDef*I2Cx, uint8_t Address),配置特定I2C自己的地址。

void I2C_DualAddressCmd(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止特定I2C对的地址模式。

void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止特定I2C普通的呼叫特征。

void I2C_ITConfig(I2C_TypeDef* I2Cx,uint16_t I2C_IT, FunctionalState NewState),使能或禁止特定的IIC中断。

void I2C_SendData(I2C_TypeDef* I2Cx,uint8_t Data),通过IIC外设发送一个字节的数据。

uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx),返回通过IIC外设接收到的最后一个字节数据。

void I2C_Send7bitAddress(I2C_TypeDef* I2Cx,uint8_t Address, uint8_t I2C_Direction),发送地址字节来选择从设备。

uint16_t I2C_ReadRegister(I2C_TypeDef*I2Cx, uint8_t I2C_Register),读取特定IIC寄存器并返回其值。

void I2C_SoftwareResetCmd(I2C_TypeDef*I2Cx, FunctionalState NewState),使能或禁止特定IIC的软件复位。

void I2C_SMBusAlertConfig(I2C_TypeDef*I2Cx, uint16_t I2C_SMBusAlert),对于特定的IIC驱动SMBusAlert引脚为高或者低。

void I2C_TransmitPEC(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止特定特定IICPEC传输。

void I2C_PECPositionConfig(I2C_TypeDef*I2Cx, uint16_t I2C_PECPosition),选择特定IICPEC 的位置。

void I2C_CalculatePEC(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止传输中PEC值统计的字节数。

uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx),对于特定的IIC返回PEC的值。

void I2C_ARPCmd(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止ARP

void I2C_StretchClockCmd(I2C_TypeDef* I2Cx,FunctionalState NewState),使能或禁止特定IIC时钟的延长。

voidI2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle),选择特定IIC快速模式的占空比。

uint32_t I2C_GetLastEvent(I2C_TypeDef*I2Cx),返回最后一个IIC事件。

ErrorStatus I2C_CheckEvent(I2C_TypeDef*I2Cx, uint32_t I2C_EVENT),检查最后一个IIC事件是否和传递的参数一致。

FlagStatus I2C_GetFlagStatus(I2C_TypeDef*I2Cx, uint32_t I2C_FLAG),检查特定的IIC标志是否被置位。

void I2C_ClearFlag(I2C_TypeDef* I2Cx,uint32_t I2C_FLAG),清楚IIC的保留标志。

ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx,uint32_t I2C_IT),检查是否有特定的IIC中断发生。

void I2C_ClearITPendingBit(I2C_TypeDef*I2Cx, uint32_t I2C_IT),清楚IIC中断保留位。


可以看到所用函数库的配置比较多,有较多的参数调用,单单在使用中,可以较为快速的实现代码的开发,但对于IIC通信的过程不便理解。希望网友能够百度模拟IIC的通信过程,并自己用开发板实现这个简单的通信过程。附上一个链接,http://blog.csdn.net/sdwuyulunbi/article/details/6654469,感兴趣的同学可自行搜索哈。

分享到:
回复

使用道具 举报

回答|共 3 个

倒序浏览

沙发

无力回天

发表于 2015-11-2 16:27:00 | 只看该作者

简单东西做这么复杂,不是好事
板凳

#define

发表于 2015-11-2 19:26:39 | 只看该作者

个人觉得   排版用点心的话    效果会更好              
地板

rui199009

发表于 2015-11-3 19:04:19 | 只看该作者

#define 发表于 2015-11-2 19:26
个人觉得   排版用点心的话    效果会更好

谢谢提醒,我会尝试着改下。
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条