zoukankan      html  css  js  c++  java
  • GPIO软件模拟I2C

    GPIO软件模拟I2C

    ]


    http://blog.csdn.net/sergeycao/article/details/2933362


    字体变小 字体变大

    /*****************************************************************************
     *
     * Filename:
     * ---------
     *   soft_i2c.c
     *
     *
     * Description:
     * ------------
     *   Use GPIO simulate I2C interface.
     *
     * Author:
     * -------
     *   jimmy.li 
     ****************************************************************************/
    #define uint32  
    #define uint16  
    #define uint8  
    #define int32  
    #define int16  
    #define int8  


    /* GPIO setting */
    #define SDA_GPIO 
    #define SCL_GPIO 

    /* set GPIO function as general output/input */
    #define SET_SDA_FN_0  
    #define SET_SCL_FN_0  

    #define SET_SDA_OUTPUT  
    #define SET_SDA_INPUT  
    #define SET_SCL_OUTPUT  

    /* read SDA status */
    #define GET_SDA_VALUE  

    /* pull SDA/SCL high or low */
    #define SEND_SDA_VALUE(x) 
    #define PULL_SDA_LOW  
    #define PULL_SDA_HIGH  
    #define PULL_SCL_LOW  
    #define PULL_SCL_HIGH  

    /* delay */
    #define I2C_DUMMY_DELAY  /
    do{/
       uint16  i2c_dummy_cnt; /
       for (i2c_dummy_cnt = 5; i2c_dummy_cnt!=0; i2c_dummy_cnt--); /
    }while(0)

    /*************************************************************************
    * FUNCTION
    * I2C_Init
    *
    * DESCRIPTION
    * Prepare to control I2C bus, set SCL, SDA normal GPIO mode.
    *
    * PARAMETERS
    * None.
    *
    * RETURNS
    * None
    *
    *************************************************************************/
    void I2C_Init(void)
    {
         /* set SCL, SDA normal GPIO mode */
         SET_SDA_FN_0;
         SET_SCL_FN_0;
    }

    /*************************************************************************
    * FUNCTION
    *     I2C_Release
    *
    * DESCRIPTION
    *     Release I2C bus.
    *
    * PARAMETERS
    *     None.
    *
    * RETURNS
    *     None
    *
    *************************************************************************/
    void I2C_Release(void)
    {
         /* set SCL, SDA high */
         PULL_SCL_HIGH;
         PULL_SDA_HIGH;
    }

    /*************************************************************************
    * FUNCTION
    *     I2C_Start
    *
    * DESCRIPTION
    *     Initiate a START condition.
    *     A High to Low transition on the SDA line while SCL is High defines a START condition.
    *
    * SCL --- ---
    *            |___
    * SDA ---
    *        |___ ___
    *
    * PARAMETERS
    *     None.
    *
    * RETURNS
    *     None
    *
    *************************************************************************/
    void I2C_Start(void)
    {   
         SET_SCL_OUTPUT;
         SET_SDA_OUTPUT;
     
         PULL_SCL_HIGH;
         PULL_SDA_HIGH;
         I2C_DUMMY_DELAY;
     
         PULL_SDA_LOW;
         I2C_DUMMY_DELAY;
     
         PULL_SCL_LOW;
         I2C_DUMMY_DELAY;
    }

    /*************************************************************************
    * FUNCTION
    *     I2C_Stop
    *
    * DESCRIPTION
    *     Generate a Stop condition.
    *     A Low to High transition on the SDA line while SCL is High defines a START condition.
    *
    * SCL     --- ---
    *     ___|
    * SDA         ---
    *     ___ ___|
    *
    * PARAMETERS
    *     None.
    *
    * RETURNS
    *     None
    *
    *************************************************************************/
    void I2C_Stop(void)
    {
         SET_SCL_OUTPUT;
         SET_SDA_OUTPUT;
     
         PULL_SCL_LOW;
         PULL_SDA_LOW;
         I2C_DUMMY_DELAY;
     
         PULL_SCL_HIGH;
         I2C_DUMMY_DELAY;
     
         PULL_SDA_HIGH;
         I2C_DUMMY_DELAY;
    }

    /*************************************************************************
    * FUNCTION
    *     I2C_TxByte
    *
    * DESCRIPTION
    *     Send a byte to I2C bus.
    *
    * PARAMETERS
    *     @uint8 data  data to be send.
    *
    * RETURNS
    *     ack received from I2C slave device.
    *
    *************************************************************************/
    uint8 I2C_TxByte(uint8 data)
    {
         int8 i, ack;
         SET_SCL_OUTPUT;
         SET_SDA_OUTPUT;
     
         // send 8bits data, MSB first
         for(i=8; --i>=0; ){
              if((data>>i)& 0x01)
                   PULL_SDA_HIGH;
              else
                   PULL_SDA_LOW;
              I2C_DUMMY_DELAY;
              PULL_SCL_HIGH;
              I2C_DUMMY_DELAY;
              PULL_SCL_LOW;
              I2C_DUMMY_DELAY;
        }
     
         // receive ack
         SET_SDA_INPUT;
     
         PULL_SCL_HIGH;
         I2C_DUMMY_DELAY;
         ack = GET_SDA_VALUE; // read ack when HIGH period of the SCL
         PULL_SCL_LOW;
     
         SET_SDA_OUTPUT;
         return ack;
    }

    /*************************************************************************
    * FUNCTION
    *     I2C_RxByte
    *
    * DESCRIPTION
    *     Receive a byte from I2C bus.
    *
    * PARAMETERS
    *     @uint8 *data  store received data.
    *     @uint8 ack  ack send to I2C slave device after receive a byte.
    *                        ACK -- 0
    *                        NACK -- 1
    * RETURNS
    *     None.
    *
    *************************************************************************/
    void I2C_RxByte(uint8 *data, uint8 ack)
    {
         int16 i;
        uint32 dataCache;
        dataCache = 0;
        
        SET_SDA_INPUT;
        
        // receive 8bits data
        for(i=8; --i>=0; ){
            dataCache <<= 1;
            PULL_SCL_HIGH;
            I2C_DUMMY_DELAY;
            dataCache |= GET_SDA_VALUE;
            PULL_SCL_LOW;
           I2C_DUMMY_DELAY;
        }
        
         SET_SDA_OUTPUT;    
        // send ack
        if(ack)
             PULL_SDA_HIGH;
        else
             PULL_SDA_LOW;
        I2C_DUMMY_DELAY;
        PULL_SCL_HIGH;
        I2C_DUMMY_DELAY;
        PULL_SCL_LOW;
        
        *data = (uint8)dataCache;
    }

    I2C总线协议标准版本是v2.1,于2000年推出。I2C的主要特性如下:

    1,只需两根线:串行数据线(SDA), 串行时钟线(SCL)。
    2,   SDA 和SCL 都是双向线路都通过一个电流源或上拉电阻连接到正的电源电压, 当总线空闲时这两条线路都是高电平,连接到总线的器件输出级必须是漏极开路或集电极开路才能执行线与的功能。
    3,每一个连接到I2C总线上的设备都要求是可被软件寻址的,也就是在I2C总线上每一个设备都必须有一个独一无二的地址(7bits)。同一时刻,总线上只能存在一个主/从(Master/Slave)关系,而且只有主设备(Master)才能发起Read和Write。
    4,I2C总线是面向8位的串行双向传输总线,其标准模式(Standard-mode)下,速率可达100kbit/s,在其快速模式(Fast-mode)下,速率可达400kbit/s,而在高速模式(High-speed mode)下,速率可高达3.4Mbit/s。

    Transmitter
         I2C总线上发送数据的设备
    Receiver
         I2C总线上接收数据的设备
    Master
         发起传输、产生时钟信号,并且终止传输的设备
    Slave
         被master寻址的设备


    I2C数据的有效性:
             SDA线上的数据在时钟High阶段必须稳定,只有在时钟Low时SDA数据线上的数据才能发生高/低电平变化。

     查看更多精彩图片

    START
           当SCL在高电平时,SDA由高转变为低电平。(SCL=High, SDA : High ->Low)

    STOP
           当SCL在高电平时,SDA由低转变为高电平。    (SCL=High, SDA: Low -> High)

     查看更多精彩图片

    I2C总线上的数据传输
        SDA线上传输的每一个字节都必须是8-bits长,但每一次所传输的字节数不限,每传输完一个字节,必须跟随一个ack位(ack 方向与数据传输方向相反 ),I2C上传输的数据都是高位优先传输(MSB)的。


    I2C 的应答信号
    1, ACK (应答)        ---    是一个低电平信号
    2, NACK(应答非)    ---  是一个高电平信号
  • 相关阅读:
    Django登录逻辑,中间用到Cookie创建、读取、删除、等操作
    CBV和FBV用户认证装饰器
    Django Session配置
    Django基于Cookie装饰器实现用户认证
    回归博客
    Jenkins部署
    iostat命令详解
    被入侵和删除木马程序的经历
    centos7 centos-home 磁盘转移至centos-root下
    zabbix图形显示口口不显示汉字
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124345.html
Copyright © 2011-2022 走看看