• STM32-软件模拟I2C


    一、SCL和SDA引脚说明

      I2C的两个引脚(SCL引脚和SDA引脚)需要既能输出又能输入,为了避免复杂的配置操作需要把该引脚配置为开漏输出模式,该模式的说明如下图所示:

       当单片机的SDA引脚配置为低电平时,SDA线被拉低;当单片机的SDA引脚配置为高电平时,引脚端口为高阻态,SDA线通过上拉电阻被VCC拉高。因此一定要注意在进行I2C通讯时确保SDA线和SCL线外接上拉电阻。

    三、代码实现

      1、I2C软件延时

    /**
     * @brief 模拟I2C延时
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    static void analog_i2c_delay(void)
    {
        volatile uint8_t i;
    
        for (i = 0; i < 10; i++);
    }

      2、I2C引脚初始化

    /**
     * @brief 软件模拟I2C初始化
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    void bsp_analog_i2c_init(void)
    {
        GPIO_InitTypeDef GPIO_InitStruct = {0};
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
    
        /*Configure GPIO pins : PB6 PB7 */
        GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
        bsp_analog_i2c_stop();
    }

      3、I2C开始

    /**
     * @brief I2C 开始,SCL为高电平的时候SDA产生一个下降沿信号
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    void bsp_analog_i2c_start(void)
    {
        /*    _____
         *SDA      \_____________
         *    __________
         *SCL           \________
         */
        i2c_sda_high();
        i2c_scl_high();
        analog_i2c_delay();
        i2c_sda_low();
        analog_i2c_delay();
        i2c_scl_low();
        analog_i2c_delay();
    }

      4、I2C停止

    /**
     * @brief I2C 停止,SCL为高电平的时候SDA产生一个上升沿信号
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    void bsp_analog_i2c_stop(void)
    {
        /*               _______
         *SDA __________/
         *          ____________
         *SCL _____/
         */
        i2c_sda_low();
        i2c_scl_high();
        analog_i2c_delay();
        i2c_sda_high();
        analog_i2c_delay();
    }

      5、I2C等待响应

    /**
     * @brief I2C 等待响应
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    uint8_t bsp_analog_i2c_wait_ack(void)
    {
        uint32_t timeout = 0;
    
        i2c_sda_high();
        analog_i2c_delay();
        i2c_scl_high();
        analog_i2c_delay();
        while(i2c_read_sda())
        {
            timeout++;
            if(timeout > 2000)
            {
                return 0;
            }
        }
        i2c_scl_low();
        analog_i2c_delay();
        return 1;
    }

      6、I2C响应

    /**
     * @brief I2C 响应
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    void bsp_analog_i2c_ack(void)
    {
        /*           ____
         *SCL ______/    \______
         *    ____         _____
         *SDA     \_______/
         */
        i2c_sda_low();
        analog_i2c_delay();
        i2c_scl_high();
        analog_i2c_delay();
        i2c_scl_low();
        analog_i2c_delay();
        i2c_sda_high();
    }

      7、I2C不响应

    /**
     * @brief I2C 不响应
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    void bsp_analog_i2c_nack(void)
    {
        /*           ____
         *SCL ______/    \______
         *    __________________
         *SDA
         */
        i2c_sda_high();
        analog_i2c_delay();
        i2c_scl_high();
        analog_i2c_delay();
        i2c_scl_low();
        analog_i2c_delay();
    }

      8、I2C发送一个字节数据

    /**
     * @brief I2C 发送一个字节数据
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    void bsp_analog_i2c_send_byte(uint8_t data)
    {
        uint8_t i;
    
        for(i = 0; i < 8; i++)
        {
            if(data & 0x80)
            {
               i2c_sda_high();
            }
            else
            {
                i2c_sda_low();
            }
    
            analog_i2c_delay();
            i2c_scl_high();
            analog_i2c_delay();
            i2c_scl_low();
            if(i == 7)
            {
                i2c_sda_high();
            }
            data <<= 1;
            analog_i2c_delay();
        }
    }

      9、I2C接收一个字节数据

    /**
     * @brief I2C 读一个字节数据
     * @retval none
     * @author Mr.W
     * @date 2020-10-12
     */
    uint8_t bsp_analog_i2c_read_byte(void)
    {
        uint8_t i, data = 0;
    
        for(i = 0; i < 8; i++ )
        {
            data <<= 1;
            i2c_scl_high();
            analog_i2c_delay();
            if(i2c_read_sda())
            {
                data++;
            }
            i2c_scl_low();
            analog_i2c_delay();
        }
    
        return data;
    }

    #endif

  • 相关阅读:
    js解析json数据
    json.stringify
    [Eclipse的Maven项目搭建,仅为测试Maven功能]如何在Eclipse下搭建Maven项目
    在 Windows 中配置Maven:
    jsp引入文件时候经常遇到的${ctx}
    <%%> <%! %> <%=%> <%-- --%> jsp中jstl一些运用
    Spring MVC之@RequestBody, @ResponseBody 详解
    Spring MVC之@RequestMapping 详解
    Spring MVC之@RequestParam @RequestBody @RequestHeader 等详
    @RequiresPermissions 解释
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/14151229.html
Copyright © 2020-2023  润新知