`

i2c协议笔记

阅读更多

最近因为要用rx8025,所以仔细看了一下i2c的协议文件,之前用过i2c的器件,不过是直接用的网上的例程,没仔细看协议的具体实现。仔细看了之后把延时时间给优化了一下。

开始停止都很简单,主要是中间的传输

 

中间传输出现的 (重新)开始信号 和开始传输的 开始信号 都是一样的,只要在SCL时钟线高电平期间,SDA数据线来一个下降沿就行。

 

i2c传输的要点就是: 传输一个字节 后面必然紧跟一个 响应 信号,这个响应信号可能来自主机,或者是从机,具体是谁,就要看传输方向。

传输方向分两种情况:

 1.主机->从机,主机对从机发一个字节之后,主机要读取从机的响应信号(主机读SDA线)

                    A) 主机读SDA为高电平,说明从机无应答,主机在此之后可以选择发送 停止信号

                         或者 (重新)开始信号。(重新)开始信号之后主机可以选择重新发送刚才的字节。

                    B) 主机读SDA为低电平,说明从机有应答,主机可以选择 直接发送下一字节 或者 停止信号

                         或者 (重新)开始信号 。(重新)开始信号之后主机也可以继续发送下一字节。

2.从机->主机, 主机读取从机一个字节之后,主机要向从机发送一个响应信号(主机写SDA线)

                    A)  主机写SDA为高电平,从机收到主机的无应答信号之后,从机停止传输,

                         等待主机的停止信号。

                    B)  主机写SDA为低电平,从机收到主机的应答信号之后,从机继续输出下一字节。

 

多说无益,直接上示例。

其实下面的代码实用价值并不是很大,仅为最简演示用,因为没有对总线的各种状态做判断,出现意外情况很容易死机,卡总线。

关于对总线的判断(程序中没有的部分):开始传输前主机要读一次总线确保都是高电平,传输过程中还要根据响应信号决定重发、等待、停止。停止之后还要读总线确保总线被释放,即数据线与时钟线都是高电平。

 

头文件

#ifndef _I2C_H_
#define _I2C_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32f10x_gpio.h"

/*******************************************************************************
 * 注意: RX8025的Tbuf为1300ns 但在通信中发生计时数据的进位时 
 *       需要61000ns(Tsp)的总线空闲时间更新寄存器
 ******************************************************************************/
/****** I2C时序        参数说明                  标准模式  高速模式 RX8025 ****/
#define Thd_sta 46  // (重复)起始条件的保持时间  4000ns    600ns    600ns
#define Tlow    95  // SCL时钟的低电平周期       4700ns    1300ns   1300ns
#define Thigh   46  // SCL时钟的高电平周期       4000ns    600ns    600ns
#define Tsu_sta 46  // 重复起始条件的建立时间    4700ns    600ns    600ns
#define Thd_dat 0   // SDA数据保持时间           0         0        0
#define Tsu_dat 15  // SDA数据建立时间           250ns     100ns    200ns
#define Tsu_sto 46  // 停止条件的建立时间        4000ns    600ns    600ns
#define Tbuf    4500// 停止和启动之间的总线空闲  1300ns    1300ns   61000ns(Tsp)
#define ACK     0   // 应答   (SDA低电平)
#define NACK    1   // 无应答 (SDA高电平)

/******************** SCL PA0 ************* SDA PA1 ***************************/
#define I2C_SCL_W(X)  X?(GPIOA->BSRR = 0x00000001):(GPIOA->BSRR = 0x00010000);
#define I2C_SDA_W(X)  X?(GPIOA->BSRR = 0x00000002):(GPIOA->BSRR = 0x00020000);
#define I2C_SCL_R()   ((GPIOA->IDR & 0x00000001)>>0)    // PA0
#define I2C_SDA_R()   ((GPIOA->IDR & 0x00000002)>>1)    // PA1

void    I2C_Delay(uint32_t t);
void    I2C_Start(void);
void    I2C_Stop(void);
uint8_t I2C_SendByte(uint8_t dat);
uint8_t I2C_ReadByte(uint8_t ack);

#ifdef __cplusplus
}
#endif

#endif

 函数文件

#include "i2c.h"

/**
  * @brief  delay func.
  * @param  delay time = t * 14ns
  * @retval none
  */

void I2C_Delay(uint32_t t)
{
    SysTick->LOAD = tick;
    SysTick->CTRL = 0x00000005;
    while(!(SysTick->CTRL & 0x00010000));
    SysTick->CTRL = 0x00000000;
}

/**
  * @brief  i2c start func.
  * @param  none
  * @retval none
  */

void I2C_Start(void)
{
    I2C_SDA_W(1);
    I2C_Delay(Tsu_dat);     // Tsu;dat  S > 250ns, F > 100ns
    I2C_SCL_W(1);
    I2C_Delay(Thigh);       // Thigh    S > 4.0us, F > 0.6us

    I2C_SCL_W(1);
    I2C_Delay(Tsu_sta);     // Tsu;sta  S > 4.7us, F > 0.6us
    I2C_SDA_W(0);
    I2C_Delay(Thd_sta);     // Thd;sta  S > 4.0us, F > 0.6us
    I2C_SCL_W(0);
    I2C_Delay(Tlow);        // Tlow     S > 4.7us, F > 1.3us
}

/**
  * @brief  i2c stop func.
  * @param  none
  * @retval none
  */

void I2C_Stop(void)
{
    I2C_SCL_W(0);
    I2C_Delay(Tlow);        // Tlow     S > 4.7us, F > 1.3us
    I2C_SDA_W(0);
    I2C_Delay(Tsu_dat);     // Tsu;dat  S > 250ns, F > 100ns
    I2C_SCL_W(1);
    I2C_Delay(Tsu_sto);     // Tsu;sto  S > 4.0us, F > 0.6us
    I2C_SDA_W(1);
    I2C_Delay(Tbuf);        // Tbuf(Tsp)S > 4.7us, F > 1.3us, for RX8025 > 61us
}

/**
  * @brief  i2c send data func.
  * @param  1 byte data
  * @retval slave response signal: ACK(0) or NACK(1)
  */

uint8_t I2C_SendByte(uint8_t dat)
{
    uint8_t i;
    for(i = 0; i < 8; i ++)
    {
        if((dat >> 7) & 1)  // MSB first
        {
            I2C_SDA_W(1);
        }
        else
        {
            I2C_SDA_W(0);
        }

        dat <<= 1;
        I2C_Delay(Tsu_dat); // Tsu;dat  S > 250ns, F > 100ns, for rx8025 > 200ns
        I2C_SCL_W(1);
        I2C_Delay(Thigh);   // Thigh    S > 4.0us, F > 0.6us
        I2C_SCL_W(0);
        I2C_Delay(Tlow);    // Tlow     S > 4.7us, F > 1.3us
    }

    I2C_SDA_W(1);
    I2C_Delay(Tsu_dat);     // Tsu;dat  S > 250ns, F > 100ns, for rx8025 > 200ns
    I2C_SCL_W(1);
    I2C_Delay(Thigh);       // Thigh    S > 4.0us, F > 0.6us

    i = 0;
    if( I2C_SDA_R() )
    {
        i = 1;
    }
    I2C_SCL_W(0);
    I2C_Delay(Tlow);        // Tlow     S > 4.7us, F > 1.3us

    return i;               // ACK == 0, NACK == 1
}

/**
  * @brief  i2c read data func.
  * @param  master response signal: ACK(0) or NACK(1)
  * @retval 1 byte data
  */

uint8_t I2C_ReadByte(uint8_t ack)
{
    uint8_t   a;
    uint8_t   dat = 0;
    I2C_SDA_W(1);           // master release sda and go high
    I2C_Delay(Tsu_dat);     // Tsu;dat  S > 250ns, F > 100ns, for rx8025 > 200ns
    for(a = 0; a < 8; a ++)
    {
        I2C_SCL_W(1);
        I2C_Delay(Thigh);
        dat <<= 1;
        if( I2C_SDA_R() )
            dat |= 1;
        I2C_SCL_W(0);
        I2C_Delay(Tlow);
    }

    if(ack)                 // master response signal
    {
        I2C_SDA_W(1);       // master nack
    }
    else
    {
        I2C_SDA_W(0);       // master ack
    }

    I2C_Delay(Tsu_dat);     // Tsu;dat  S > 250ns, F > 100ns, for rx8025 > 200ns
    I2C_SCL_W(1);
    I2C_Delay(Thigh);       // Thigh    S > 4.0us, F > 0.6us
    I2C_SCL_W(0);
    I2C_Delay(Tlow);        // Tlow     S > 4.7us, F > 1.3us

    return dat;
}

 

分享到:
评论

相关推荐

    i2c协议笔记1

    i2c协议笔记1

    MSP430单片机I2C应用笔记

    I2C协议就不用在这里赘述了,EEPROM选用Microchip的24LC02B,MFRC522接成I2C接口形式,MSP430G2553的I2C口配置在USCI_B0(UCB0SCL和UCB0SDA)上,接线示意图如下,图中只画出I2C接口相关接线,其他接线略去,MFRC...

    STM32应用笔记-SPI自举程序中使用的I2C协议

    STM32应用笔记-SPI自举程序中使用的I2C协议

    I2C协议规范与应用自学笔记-水印版

    I2C是名副其实的世界级的标准总线,并且衍生出了其他很多总线

    UART、I2C、SPI协议和应用

    UART协议(中文版)、I2C协议(中文版)、SPI协议(中文版和英文版)、SPI总线协议_SD卡应用、SPI总线_TLC1549-带串行控制的10 位模数转换器的应用、SPI接口学习笔记_ADuC812 与nRF2401的应用

    Atecc608_hal_I2C_Driver.zip

    ATECC508A芯片开发笔记(十一):NXP 平台移植ATECCx08 CryptoAuthLib库(I2C)

    STM32-I2C 协议.pdf

    本应用笔记说明了 STM32 微控制器自举程序中使用的 I2C 协议。它详细说明了每个支持的 指令。 若需器件自举程序 I2C 硬件资源和要求的更多信息,请参考应用笔记 AN2606 “STM32 微控 制器系统存储器自举模式 ”。

    翻译理解I2C总线 I2C总线是一种非常流行且功能强大的总线,用于单个主设备或多个主设备与单个或多个从设备之间的通信

    本应用笔记旨在帮助用户了解I2C总线的工作原理。 图1显示了嵌入式系统的典型I2C总线,其中使用了多个从器件。 微控制器代表I2C主控制器,并控制IO扩展器,各种 传感器,EEPROM,ADC/DAC等等。 所有这些都只由主机的2...

    用于 Atmels ATtiny微控制器的复合主从 I2C 库_C++_代码_相关文件_下载

    用于 Atmels ATTiny 微控制器的复合主从 I2C 库 用于 ATtiny 上用于 I2C 通信的新组合 TinyWire 库的类 完整的库基于 TinyWireM 和 TinyWireS 库,最初由 BroHogan 发布,然后由 jkl 修改。我重新编写了他们的代码以...

    SMBUS协议规范与应用自学笔记-水印版.pdf

    SMBus源于I2C,但是在协议层做了更多的定义

    华为工程师linux的笔记-第2章 .pdf

    Linux性能优化、大数据量备份、Shell企业实战基础、Shell实战高级编程、自动化运维趋势、Puppet自动化运维实战、Ansible自动化运维实战、...企业级高并发网站集群、Docker、K8S、Hadoop、Ceph、CI/CD、MQ、ZK、ETCD等...

    STM32-IIC-学习笔记总结.pdf

    stm32的i2c驱动总结,对寄存器配置,协议实现,控制逻辑等做了详细说明,是初学者快速上手的好手册。

    应用笔记LAT1171+STM32F745+USART1+Bootloader+失败原因分析与解决

    STM32 的 Bootloader 可以支持多种协议的,比如 USART,I2C,DFU 等等,USART Bootloader 是客户使用 STM32 的时候常常会用到的协议。客户在使用 STM32F745 进行 产品开发的时候,出现了使用 STM32CubeProgramer ...

    c#学习笔记.txt

    C#学习笔记(2)【大 中 小】【打印】【加入收藏】【关闭】 【收藏到新浪ViVi】【收藏到365KEY】 浏览字号:日期:2004-07-11 人气:8092 出处: write by cash(天下第七) 2002.01.20 版权所有,翻录不究 cashcao@...

    应用笔记AN2606-STM32单片机系统内存启动方式

    其主要任务是通过一种可用的串行外设(如USART、CAN、USB、I2C)将应用程序下载到内部Flash中。每种串行接口都定义了相应的通信协议,其中包含兼容的命令集和序列。本文档适用于表1中列出的产品,这些产品在文档中统...

    硬件工程师炼成之路笔记

    通信协议:了解和掌握常见的通信协议,如SPI、I2C、UART等,可以用来实现设备之间的通信和数据传输。 PCB设计:掌握PCB设计软件和技能,能够设计、绘制和制造电路板。 硬件故障排除:掌握硬件故障排除技能,能够定位...

    net学习笔记及其他代码应用

    else if(i &gt; 0 && i &lt;= 2) return 1; else return Foo(i -1) + Foo(i - 2); } } 4.C#中的委托是什么?事件是不是一种委托? 答 : 委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数...

    比较完整的一个EEPROM手册,加入自己笔记

    比较完整的一个EEPROM手册,加入自己笔记 这个是ST的,主要是加入了一些自己的理解,配合IIC规范(周立功)的理解IIC协议 https://download.csdn.net/download/qq2012953313493/10941228

    html入门到放弃笔记

    1、协议名 http 2、域名(主机名,IP地址) www.codeboy.com 3、目录路径 img/header 4、文件名 logo.png http://www.codeboy.com/img/header/logo.png img/header/logo.png 2、相对路径(重点) 场合:...

    Windows 网络编程

    在Wi n 3 2环境中,Wi n s o c k接口最终成为一个真正的“与协议无关”接口,尤其是在Winsock 2发布之后。 本书的最后这一部分讨论了一种重要的服务,名为“远程访问服务”(Remote Access Service, RAS),它允许...

Global site tag (gtag.js) - Google Analytics