zoukankan      html  css  js  c++  java
  • 单片机驱动-软件模拟I2C

    一、数据格式

      1、读数据:

      2、写数据:

    二、I2C时序图

      1、读写时序图:

     

    三、软件实现

      1、开始

      在SCL处于高电平的状态时,SDA产生一个下降沿信号;

    /*
     *@brief i2c Start
     *@author Mr.W
     *@date 2020-8-3
     */
    static void i2c_start(void)
    {
        I2C_SDA_SET;
        i2c_delay(5);
        I2C_SCL_SET;
        i2c_delay(5);
        I2C_SDA_CLR;
        i2c_delay(5);
        I2C_SCL_CLR;
        i2c_delay(5);
    }

      2、停止

      在SCL处于高电平的状态时,SDA产生一个上升沿信号;

    /*
     *@brief i2c Stop
     *@author Mr.W
     *@date 2020-8-3
     */
    static void i2c_stop(void)
    {
        I2C_SCL_CLR;
        i2c_delay(5);
        I2C_SDA_CLR;
        i2c_delay(5);
        I2C_SCL_SET;
        i2c_delay(5);
        I2C_SDA_SET;
        i2c_delay(5);
    }

      3、等待响应信号

      如果等到响应信号SDA电平信号由高电平变成低电平,否则未等到响应信号;

    /*
     *@brief i2c Wait Acknowledge
     *@author Mr.W
     *@date 2020-8-3
     */
    static uint8_t i2c_wait_ack(void)
    {
        I2C_SDA_SET;
        i2c_delay(5);
        I2C_SCL_SET;
        i2c_delay(5);
        if(I2C_PIN_SDA)
        {
            i2c_stop();
            return 0;
        }
        I2C_SCL_CLR;
        return  1; 
    }

      4、发送响应

    /*
     *@brief i2c Send Acknowledge
     *@author Mr.W
     *@date 2020-8-3
     */
    static void i2c_send_ack(void)
    {
        I2C_SDA_CLR;
        i2c_delay(5);
        I2C_SCL_SET;
        i2c_delay(5);
        I2C_SCL_CLR;    
    }

      5、发送未响应

    /*
     *@brief i2c Send No Acknowledge
     *@author Mr.W
     *@date 2020-8-3
     */
    static void i2c_send_noack(void)
    {
        I2C_SDA_SET;
        i2c_delay(5);
        I2C_SCL_SET;
        i2c_delay(5);
        I2C_SCL_CLR;    
    }

      6、发送数据

      发送一个字节数据;

    /*
     *@brief i2c Send Data
     *@author Mr.W
     *@date 2020-8-3
     */
    static void i2c_send_data(uint8_t data)
    {
        uint8_t i = 8;
        
        while(i--)
        {
            I2C_SCL_CLR;
            i2c_delay(10);
            if(data & 0x80)
            {
                I2C_SDA_SET;
            }         
            else
            {
                I2C_SDA_CLR;
            }
            
            i2c_delay(5);
            data <<= 1;
            I2C_SCL_SET;
            i2c_delay(5);
            I2C_SCL_CLR;
            i2c_delay(5);
        }    
    }

      7、接收数据

      接收一个字节数据;

    /*
     *@brief i2c Receive Data
     *@author Mr.W
     *@date 2020-8-3
     */
    static uint8_t i2c_receive_data(void)
    {
        uint8_t i = 8;
        uint8_t data = 0;
        
        I2C_SDA_SET;
        while(i--)
        {
            data <<= 1;
            I2C_SCL_CLR;
            i2c_delay(5);
            I2C_SCL_SET;
            i2c_delay(5);
            if(I2C_PIN_SDA) 
                data |= 0x01;
        }
        I2C_SCL_CLR;
        
        return data;    
    }

      8、读多个数据

    /*
     *@brief Read Data
     *@author Mr.W
     *@date 2020-8-3
     */
    uint8_t ReadNByte(uint8_t sla, uint16_t suba, uint8_t *pdata, uint16_t num)
    {
        uint8_t i;
        
        i2c_start();
        i2c_send_data(sla);
        if(i2c_wait_ack() == 0)
        {
            i2c_stop();
            return 0;
        }
        i2c_send_data(suba);
        if(i2c_wait_ack() == 0)
        {
            i2c_stop();
            return 0;
        }
        
        i2c_start();
        i2c_send_data(sla|0x01);
        if(i2c_wait_ack() == 0)
        {
            i2c_stop();
            return 0;
        }
        for(i = 0; i < num; i++)
        {
            *pdata++ = i2c_receive_data();
            if(i < (num - 1))
                i2c_send_ack();
        }
        i2c_send_noack();
        i2c_stop();
        
        return 1;    
    }

      9、写多个数据

    /*
     *@brief Write Data
     *@author Mr.W
     *@date 2020-8-3
     */
    uint8_t WriteNByte(uint8_t sla, uint16_t suba, uint8_t *pdata, uint16_t num)
    {
        uint8_t i;
        
        i2c_start();
        i2c_send_data(sla);
        if(i2c_wait_ack() == 0)
        {
            i2c_stop();
            return 0;
        }
        i2c_send_data(suba);
        if(i2c_wait_ack() == 0)
        {
            i2c_stop();
            return 0;
        }
    
        for(i = 0; i < num; i++)
        {
            i2c_send_data(*pdata++);
            if(i2c_wait_ack() == 0)
            {
                i2c_stop();
                return 0;
            }
        }
        i2c_stop();
        
        return 1;
    }

    #end

  • 相关阅读:
    疫情控制
    严格次小生成树
    图论之最短路
    A Simple Framework for Contrastive Learning of Visual Representations 阅读笔记
    CenterNet文献调研记录
    朴素贝叶斯分类器基本代码 && n折交叉优化 2
    朴素贝叶斯分类器基本代码 && n折交叉优化
    蓝桥杯刷题 -- 第八届蓝桥杯
    蓝桥杯刷题 -- 第七届蓝桥杯
    蓝桥杯刷题 -- 第六届蓝桥杯
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/13434533.html
Copyright © 2011-2022 走看看