本帖最后由 rui199009 于 2015-11-3 19:08 编辑
10天前发了两篇帖子,分别是机智云代码介绍和can总线的学习。今天就来学习下另一种通信方式:IIC通信(I2C)。IIC通信和can总线不同,can总线的两根通信线分别代表CANH和CANL,不需要时钟。耳IIC通信却需要时钟进行同步,因此IIC由数据线和时钟线构成。其中 IIC的时钟线和数据线的高低电平只要在通信协议的标准范围内都可以,但是要注意的是不同芯片的IIC电压范围不同,有的需要加电平转换芯片,防止芯片被烧毁。
IIC通信有两种实现方式,一种是硬件IIC,另一种是模拟IIC。硬件IIC较为快速,占用资源少,只需要配置相关寄存器就可以使用,较省电,但是用法复杂。模拟IIC更容易理解通信过程,便于移植到各种单片机平台,可以在任意IO引脚上使用。
首先先从硬件IIC开始,结合机智云的代码进行讲解。机智云IIC代码写的比较丰富(哈哈,太长了,虽然在配置时很方便,但是不是很容易理解其中的运行过程),粗略看下接近1000行,下面就仔细的一个部分一个部分的解读下(比较长,请耐心观看)。
首先,是一部分宏定义。主要是对于STM32F103的IIC通信中所用到的寄存器的对应位进行配置,最终达到使用IIC进行通信的功能。涉及到的寄存器有CR1、CR2、OAR1、CAR2、CCR等。 CR1_PE_Set:启用IIC模块。 CR1_PE_Reset:禁用IIC模块。 CR1_START_Set:主模式下,重复产生起始条件;从模式下,当总线空闲时,产生起始条件。 CR1_START_Reset:主模式下,无起始条件产生;从模式下,无起始条件产生。 CR1_STOP_Set:主模式下,在当前字节传输或在当前起始条件发出后产生停止条件;从模式下,在当前字节传输或释放SCL和SDA线。 CR1_STOP_Reset:主模式下,无停止条件产生;从模式下,无停止条件产生。 CR1_ACK_Set:在接收到一个字节后返回一个应答(匹配的地址或数据)。 CR1_ACK_Reset:无应答返回。 CR1_ENGC_Set:允许广播呼叫,以应答响应地址00h。 CR1_ENGC_Reset:禁止广播呼叫,以非应答响应地址00h。 CR1_SWRST_Set:IIC模块处于复位状态。 CR1_SWRST_Reset:IIC模块不处于复位状态。 CR1_PEC_Set:PEC传输(在发送或接受模式)。 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= 1或RxNE=1时,允许DMA请求。 CR2_DMAEN_Reset:禁止DMA请求。 CR2_LAST_Set:下一次DMA的EOT是最后的传输。 CR2_LAST_Reset:下一次DMA的EOT不是最后的传输。 CR2_FREQ_Reset:用于设置正确的输入时钟频率以产生正确的时序,允许的范围在2~36Hz之间。000000:禁用。000001:禁用。000010:2MHz。……..100100:36MHz。大于100100:禁用。
OAR1_ADD0_Set:10位地址模式时为地址第0位。 OAR1_ADD0_Reset:7位地址模式时不用关心。
OAR2_ENDUAL_Set:在7位地址模式下,OAR1和OAR2都被识别。 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),使能或禁止特定的IIC的DMA请求。
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),使能或禁止特定特定IIC的PEC传输。
void I2C_PECPositionConfig(I2C_TypeDef*I2Cx, uint16_t I2C_PECPosition),选择特定IIC的PEC 的位置。
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,感兴趣的同学可自行搜索哈。
|