查看: 3582|回复: 3

机智云IIC代码介绍

[复制链接]
  • TA的每日心情
    奋斗
    2015-10-21 16:47
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2015-11-2 14:50:42 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 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,感兴趣的同学可自行搜索哈。

    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-12-15 11:51
  • 签到天数: 24 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2015-11-2 16:27:00 | 显示全部楼层
    简单东西做这么复杂,不是好事
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2018-3-28 17:24
  • 签到天数: 276 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2015-11-2 19:26:39 | 显示全部楼层
    个人觉得   排版用点心的话    效果会更好              
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-10-21 16:47
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

     楼主| 发表于 2015-11-3 19:04:19 | 显示全部楼层
    #define 发表于 2015-11-2 19:26
    个人觉得   排版用点心的话    效果会更好

    谢谢提醒,我会尝试着改下。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2024-11-15 08:55 , Processed in 0.141859 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.