登录/注册

stm32f103模拟i2c例程

更多

以下是一个基于STM32F103的模拟I2C(软件I2C)例程,使用GPIO引脚模拟I2C协议,代码基于标准外设库(Standard Peripheral Library)实现:

1. 硬件连接

2. GPIO初始化

#include "stm32f10x.h"

#define I2C_SCL_PIN    GPIO_Pin_6
#define I2C_SDA_PIN    GPIO_Pin_7
#define I2C_GPIO_PORT  GPIOB

void I2C_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    // SCL和SDA配置为开漏输出模式
    GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  // 开漏输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_GPIO_PORT, &GPIO_InitStructure);

    // 初始化为高电平
    GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN | I2C_SDA_PIN);
}

3. 基本时序函数

// 微秒级延时(需根据主频调整)
void I2C_Delay_us(uint32_t us) {
    us *= 72;  // 假设系统时钟72MHz
    while(us--) {
        __NOP();
    }
}

// 产生起始信号
void I2C_Start(void) {
    SDA_HIGH();
    SCL_HIGH();
    I2C_Delay_us(5);
    SDA_LOW();   // SCL高电平期间SDA下降沿
    I2C_Delay_us(5);
    SCL_LOW();    // 拉低SCL准备传输数据
}

// 产生停止信号
void I2C_Stop(void) {
    SDA_LOW();
    SCL_LOW();
    I2C_Delay_us(5);
    SCL_HIGH();   // SCL高电平期间SDA上升沿
    I2C_Delay_us(5);
    SDA_HIGH();
}

// 等待ACK应答
uint8_t I2C_Wait_Ack(void) {
    uint8_t ack = 0;
    SDA_INPUT();   // 切换SDA为输入模式
    SCL_HIGH();
    I2C_Delay_us(5);

    if (GPIO_ReadInputDataBit(I2C_GPIO_PORT, I2C_SDA_PIN) == 0) {
        ack = 1;   // 收到ACK
    }

    SCL_LOW();
    SDA_OUTPUT();  // 切换回输出模式
    return ack;
}

// 发送ACK信号
void I2C_Ack(void) {
    SDA_LOW();
    I2C_Delay_us(2);
    SCL_HIGH();
    I2C_Delay_us(5);
    SCL_LOW();
}

// 发送NACK信号
void I2C_NAck(void) {
    SDA_HIGH();
    I2C_Delay_us(2);
    SCL_HIGH();
    I2C_Delay_us(5);
    SCL_LOW();
}

4. 数据读写函数

// 发送一个字节
void I2C_SendByte(uint8_t data) {
    for (uint8_t i = 0; i < 8; i++) {
        SCL_LOW();
        if (data & 0x80) SDA_HIGH();
        else SDA_LOW();
        data <<= 1;
        I2C_Delay_us(2);
        SCL_HIGH();  // 上升沿发送数据
        I2C_Delay_us(5);
    }
    SCL_LOW();
}

// 接收一个字节
uint8_t I2C_ReadByte(void) {
    uint8_t data = 0;
    SDA_INPUT();     // SDA设为输入

    for (uint8_t i = 0; i < 8; i++) {
        SCL_LOW();
        I2C_Delay_us(2);
        SCL_HIGH();  // 上升沿读取数据
        data <<= 1;
        if (GPIO_ReadInputDataBit(I2C_GPIO_PORT, I2C_SDA_PIN)) {
            data |= 0x01;
        }
        I2C_Delay_us(5);
    }

    SCL_LOW();
    SDA_OUTPUT();    // 切回输出模式
    return data;
}

5. 使用示例(以AT24C02 EEPROM为例)

// 向EEPROM写入一个字节
void EEPROM_WriteByte(uint8_t addr, uint8_t data) {
    I2C_Start();
    I2C_SendByte(0xA0);       // 器件地址 + 写操作
    I2C_Wait_Ack();
    I2C_SendByte(addr);       // 写入地址
    I2C_Wait_Ack();
    I2C_SendByte(data);       // 发送数据
    I2C_Wait_Ack();
    I2C_Stop();
    Delay_ms(10);             // 等待EEPROM写入完成
}

// 从EEPROM读取一个字节
uint8_t EEPROM_ReadByte(uint8_t addr) {
    uint8_t data;
    I2C_Start();
    I2C_SendByte(0xA0);       // 器件地址 + 写操作
    I2C_Wait_Ack();
    I2C_SendByte(addr);       // 发送要读取的地址
    I2C_Wait_Ack();

    I2C_Start();              // 重复起始条件
    I2C_SendByte(0xA1);       // 器件地址 + 读操作
    I2C_Wait_Ack();
    data = I2C_ReadByte();    // 读取数据
    I2C_NAck();               // 发送NACK结束读取
    I2C_Stop();
    return data;
}

注意事项:

  1. 时序调整:延时函数I2C_Delay_us()需根据实际主频调整,可用示波器校准。
  2. 错误处理:建议在实际应用中增加超时判断,避免死循环。
  3. 多设备支持:通过修改器件地址(0xA0/0xA1)适配不同从机。
  4. 中断处理:若在中断中使用,需考虑延时函数的准确性。

可根据具体需求调整GPIO引脚和时序参数,适用于大多数I2C从设备通信场景。

STM32F103普通IO模拟通信协议如I2C,SPI,串口,怎么精准的控制通讯的速率?

用STM32F103普通IO模拟通信协议如I2C,SPI,串口等。 怎么精准的控制通讯的速率,我看到STLINK也是用的

2024-03-28 08:24:07

请问STM32F103 I2C通信和SPI通信哪种方式更稳定?

STM32F103这颗料I2C通信和SPI通信哪种方式更稳定?

2024-03-22 06:24:49

STM32F103系列做PMBus的主机和I2C再配置上有什么区别吗?

有没有人用STM32F103系列做过PMBus的主机呀?和I2C再配置上有什么区别吗?

2024-03-13 07:41:56

STM32f103系列i2c读写文件at24c02

STM32f103系列i2c读写文件at24c02免费下载。

资料下载 heianqishi1118 2022-03-04 09:43:47

STM32F103硬件I2C Slave

MCU:STM32F103IDE:STM32CubeIDEHAL库硬件I2C当作Slave,

资料下载 goodmbby 2021-12-20 19:38:54

STM32F103 硬件I2C主从机通信

STM32F103 硬件I2C主从机通信

资料下载 名士流 2021-12-07 12:06:10

STM32作为I2C从机中断接收和从模式中断应答数据总结

主设备发送读信号时中断发送回应的功能。在网上找了很多资料,都说STM32F103的i2c硬件有瑕疵,具体有啥瑕疵我也不太清楚,只是大部分例程都是

资料下载 远不及你 2021-12-02 19:21:32

STM32F103 模拟IIC时序

STM32F103 模拟IIC时序

资料下载 overheat 2021-11-25 09:51:10

stm32f103 flash模拟eeprom

,STM32F103的Flash存储器可以模拟EEPROM的功能,在本文中我们将详细介绍如何使用STM32F103的Flash存储器来实现EEP

2024-01-09 11:21:36

STM32使用教程 基于STM32F103RBT6的例程 STM32控制OLED例程

,请按实际引脚连接 OLED STM32 VCC 3.3V GND GND DIN SPI:PA7 / I2C:PB9 / I2C_SOFT:P

2022-05-05 19:44:07

STM32F103硬件I2C Slave的相关资料分享

MCU:STM32F103IDE:STM32CubeIDEHAL库硬件I2C当作Slave,

2022-02-17 06:59:50

STM32F103I2C软件模拟实验

例程:STM32F103系列 I2C软件模拟实验(mini板)问题:下面

2022-01-18 08:14:34

STM32F103 Slave I2C配置过程是怎样的?

STM32F103 Slave I2C配置过程是怎样的?

2021-12-14 06:57:59

STM32F103 硬件I2C主从机通信 精选资料分享

肝了这么多天,查了很多资料,逛了不少论坛终于把stm32f103的硬件I2C写出来了,就先做个记录。开发板是自己画的兼容原子精英两块板子,型号是f103

2021-08-11 06:04:15

STM32F10x_ 模拟I2C读写EEPROM

STM32F10x_模拟I2C读写EEPROM

2020-03-25 11:13:37

7天热门专题 换一换
相关标签