ARM-I2C软实现

开发流程

  1. 引脚初始化
  2. 引脚功能定义
  3. 实现读操作
  4. 实现写操作

GD32F4软件I2C初始化

复制代码
void SoftI2C_init() {
    // 时钟配置
    rcu_periph_clock_enable(SCL_RCU);
    // 设置输出模式
    gpio_mode_set(SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCL_PIN);
    gpio_output_options_set(SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, SCL_PIN);

    // 时钟配置
    rcu_periph_clock_enable(SDA_RCU);
    // 设置输出模式
    gpio_mode_set(SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SDA_PIN);
    gpio_output_options_set(SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, SDA_PIN);
}
  • I2C引脚高低电平

GD32F4软件I2C引脚功能

复制代码
#define SCL_RCU		RCU_GPIOB
#define SCL_PORT	GPIOB
#define SCL_PIN		GPIO_PIN_6
#define SCL_AF		GPIO_AF_4

#define SDA_RCU		RCU_GPIOB
#define SDA_PORT	GPIOB
#define SDA_PIN		GPIO_PIN_7
#define SDA_AF		GPIO_AF_4

/************** io ***************/
#define SCL(BIT) 		gpio_bit_write(SCL_PORT, SCL_PIN, BIT?SET:RESET)
#define SDA(BIT) 		gpio_bit_write(SDA_PORT, SDA_PIN, BIT?SET:RESET)
#define SDA_STATE() 	gpio_input_bit_get(SDA_PORT, SDA_PIN)

#define SDA_IN()  	gpio_mode_set(SDA_PORT, GPIO_MODE_INPUT,  GPIO_PUPD_NONE, SDA_PIN)
#define SDA_OUT() 	gpio_mode_set(SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SDA_PIN)
  • IO引脚定义
  • 引脚输出模式高低电平输出:SCL高和低,SDA高和低
  • SDA模式配置:SDA输出模式,SDA输入模式
  • SDA输入模式状态读取。

写操作

复制代码
uint8_t SoftI2C_write(uint8_t addr, uint8_t reg, uint8_t* data, uint32_t len) {
    start();

    send(addr << 1);			//发送设备写地址
    if(wait_ack()) return 1;	//等待响应

    send(reg);					//发送寄存器地址
    if(wait_ack()) return 2;	//等待响应

    do {
        send(*data++);
        if(wait_ack()) return 3;
    } while(--len);

    stop();
    return 0;
}

读操作

复制代码
uint8_t SoftI2C_read(uint8_t addr, uint8_t reg, uint8_t* data, uint32_t len) {
    start();

    send(addr << 1);				//发送设备写地址
    if(wait_ack()) return 1;		//等待响应

    send(reg);						//发送寄存器地址
    if(wait_ack()) return 2;		//等待响应

    start();
    send((addr << 1) | 0x01);		//发送设备读地址
    if(wait_ack()) return 3;		//等待响应

    do {
        *data = recv();
        data++;
        if(len != 1) send_ack();	// 发送 ACK
    } while(--len);
    send_nack();					// 发送 NACK
    stop();

    return 0;
}
相关推荐
AoDeLuo16 小时前
EthercCAT软件主站方案对比
stm32·单片机·嵌入式硬件
平凡灵感码头16 小时前
半导体三大主流制程详解:Bipolar、CMOS 与 BCD
单片机·嵌入式硬件
国科安芯17 小时前
基于AS32S601ZIT2型抗辐照MCU的商业航天卫星姿态确定与控制系统研究
单片机·嵌入式硬件·安全·fpga开发·架构·risc-v
三品吉他手会点灯17 小时前
STM32F103 学习笔记-24-I2C-读写EEPROM(第2节)-I2C协议层介绍
笔记·stm32·学习
项目題供诗18 小时前
STM32-DMA数据转运+AD多通道(二十一)
stm32·单片机·嵌入式硬件
FPC_小西18 小时前
LDO 低压差线性稳压器 拆解电源稳压核心原理
人工智能·单片机·嵌入式硬件·集成学习·pcb工艺·hdi高密度互联
三品吉他手会点灯18 小时前
STM32F103 学习笔记-24-I2C-读写EEPROM(第3节)-STM32的I2C框图详解
笔记·stm32·学习
踏着七彩祥云的小丑18 小时前
嵌入式测试学习第 36 天:串口日志分析、通过日志定位简单问题
单片机·嵌入式硬件·学习
caimouse18 小时前
Reactos 第 9 章 设备驱动 — 9.9 磁盘的设备驱动堆叠
windows·嵌入式硬件
三品吉他手会点灯18 小时前
STM32F103 学习笔记-24-I2C-读写EEPROM(第4节)-STM32的I2C通讯过程
笔记·stm32·学习