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;
}
相关推荐
爱学习的颖颖27 分钟前
EXTI外部中断的执行逻辑|以对射式红外传感器计次为例
单片机·嵌入式硬件·exti中断
keer_zu1 小时前
STM32L051 RTC闹钟配置详解
stm32·嵌入式硬件
AI精钢2 小时前
H20芯片与中国的科技自立:一场隐形的博弈
人工智能·科技·stm32·单片机·物联网
etcix5 小时前
implement copy file content to clipboard on Windows
windows·stm32·单片机
谱写秋天5 小时前
在STM32F103上进行FreeRTOS移植和配置(STM32CubeIDE)
c语言·stm32·单片机·freertos
globbo8 小时前
【嵌入式STM32】I2C总结
单片机·嵌入式硬件
玖別ԅ(¯﹃¯ԅ)9 小时前
SysTick寄存器(嘀嗒定时器实现延时)
stm32·单片机·嵌入式硬件
limitless_peter9 小时前
集成运算放大器(反向比例,同相比例)
嵌入式硬件·硬件工程
Blossom.11810 小时前
把 AI 推理塞进「 8 位 MCU 」——0.5 KB RAM 跑通关键词唤醒的魔幻之旅
人工智能·笔记·单片机·嵌入式硬件·深度学习·机器学习·搜索引擎
桃源学社(接毕设)12 小时前
基于人工智能和物联网融合跌倒监控系统(LW+源码+讲解+部署)
人工智能·python·单片机·yolov8