`

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协议的一些基本特征、数据传输方式以及一些关键的通信细节。 首先,I2C协议支持双线半双工同步通信,这意味着数据在同一时刻只能沿一个方向传输,但两条线路(SDA和SCL)都可以作为数据的输入和...

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

    【I2C协议规范与应用自学笔记】 I2C(Inter-Integrated Circuit)协议是由Philips(现NXP)公司创建的一种同步半双工串行总线标准,它以其高效和简洁的特性,在全球范围内广泛应用,并衍生出多种总线协议,如SMBus...

    i2c-SPI笔记

    I2C(Inter-Integrated Circuit)是一种两线式串行总线协议,它允许多个设备在两个双向线上进行通信:数据线SDA(Serial Data Line)和时钟线SCL(Serial Clock Line)。I2C 总线系统通常用于连接微控制器、传感器、...

    MSP430单片机I2C应用笔记

    总结来说,这篇文章提供了使用MSP430G2553单片机进行I2C通信的实际案例,涉及了硬件配置、协议理解、程序设计以及调试技巧,对于那些希望在嵌入式系统中使用I2C协议的人来说,是一份宝贵的参考资料。

    i2c学习笔记和个人理解

    ### i2c学习笔记和个人理解 #### I2C总线简介 I2C(Inter-Integrated Circuit)是一种广泛应用于电子设备中的串行通信协议,它主要用于微控制器与各种外围设备之间的简单、双向通信。该协议是由飞利浦公司在1982年...

    STM32通过I2C在线升级(En)1

    11. I2C协议的特点:I2C协议是一种半双工串行通信协议,具有高速、低功耗和可靠性等特点。 本应用笔记提供了使用STM32F10x微控制器的I2C外设进行在线升级的指导。该方法可以广泛应用于各种需要在线升级的系统中。

    C8051F ,I2C接口存储器读取驱动程序

    该部分实现了I2C协议的读取和写入操作,包括slave地址的设置、数据的发送和接收、ACK机制的实现等。 在I2C通信协议实现部分,我们使用了C8051F微控制器的SMBus接口来实现I2C通信协议。SMBus接口是一个双线串行总线...

    i2c bootloader

    【标签】中的“lpc17xx”和“lpc11xx”是NXP半导体公司的微控制器系列,它们都支持I2C协议,并且广泛应用于各种嵌入式系统中。LPC17xx系列是基于ARM Cortex-M3内核的,而LPC11xx系列则是基于ARM Cortex-M0+内核的,...

    ti-i2c通讯协议手册

    这份"ti-i2c通讯协议手册"包含了一系列与I2C协议相关的文档,旨在帮助开发者理解并实施I2C通信。 首先,I2C_V2.1.pdf可能是TI发布的I2C协议规范的最新版本,详细描述了协议的基础,包括起始和停止条件、数据传输...

    总线协议简介讲解I2C总线协议

    - **专利背景**:I2C最初是一项受专利保护的技术,这意味着任何想要在其产品中使用I2C协议的企业都需要得到飞利浦(后来的NXP Semiconductors)的授权。这导致了许多法律纠纷,尤其是针对那些未经授权使用I2C协议的...

    I2C.rar_LPC23 i2c_i2c_i2c lpc23_lpc2368_lpc2368 i2c

    I2C协议允许多个设备共享两根线(SCL时钟线和SDA数据线)进行通信,极大地简化了硬件设计并降低了成本。 在I2C通信中,有主设备和从设备的概念。主设备通常是由微控制器扮演的角色,它控制通信时序,发出启动和停止...

    430I2c实例

    标题 "430I2c实例" 涉及的是使用TI公司的MSP430微控制器进行I2C通信的实践案例,特别是在与24128存储器交互时的编程实现...通过学习这个实例,开发者可以深化对I2C协议的理解,并能应用于其他类似的传感器或存储设备。

    国民MCU AN_N32G45x_FR系列芯片_硬件I2C应用笔记 V1.0

    本文将深入探讨国民微电子(Nation32)推出的AN_N32G45x_FR系列微控制器(MCU)在硬件I2C通信协议的应用。I2C(Inter-Integrated Circuit)是一种在嵌入式系统中广泛使用的多主控器串行总线,它允许不同设备之间进行高效...

    Linux Arm嵌入式利用I2C总线方式和I2C设备驱动方式配置从设备寄存器(并有相关的微博详细笔记)

    首先,理解I2C总线协议是关键。I2C总线由两条线构成:SDA(数据线)和SCL(时钟线)。主设备(如Linux系统中的CPU)控制时钟线,而数据线上的数据传输则由主设备和从设备共同完成。通信过程中,主设备发起读写请求,...

    I2C_Master0.zip_i2c master_i2c_master_it

    标题"I2C_Master0.zip_i2c master_i2c_master_it"表明这是一个关于I2C总线主控程序的资源包,专为MCS51系列单片机设计。...对于熟悉8051和I2C协议的嵌入式系统开发者来说,这是一个非常有价值的参考资料。

    I2C扩展IO芯片-PCA9535 datasheet

    在进行PCA9535芯片应用开发时,除了要参考数据手册外,还需要对I2C通信协议有所了解。I2C是一种串行通信协议,支持多主机和多从机配置,可以实现多个设备之间的数据传输。 PCA9535是一款非常实用的I2C扩展芯片,...

    I2C 逻辑选型指南

    - **软件定义的系统**:I2C总线采用统一的寻址方式和数据传输协议,整个系统可以通过软件来定义,提高了灵活性。 - **可重用性**:支持在不同的应用场景中使用同一类型的IC,缩短了产品的开发周期。 - **易于调试**...

    ARMlpc2300技术笔记例程I2C读写24C02.zip

    2. **I2C协议**:解释了I2C协议的基本原理,包括起始和停止信号、数据传输规则、ACK/NACK响应以及错误处理。 3. **24C02的地址和命令**:24C02的7位I2C地址,以及读写命令格式,如何选择从设备地址和指定存储地址。...

    UART、I2C、SPI协议和应用

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

Global site tag (gtag.js) - Google Analytics