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;
}
相关推荐
嵌入式小白牙42 分钟前
ARM-DMA
arm开发·stm32·单片机
青牛科技-Allen3 小时前
GC8871刷式直流电机驱动器深度解析:3.6A驱动与内置电流检测技术
单片机·嵌入式硬件·音视频·音响·电动工具·散热风扇·电脑散热风扇
月阳羊7 小时前
【硬件-笔试面试题】硬件/电子工程师,笔试面试题-26,(知识点:硬件电路的调试方法:信号追踪,替换,分段调试)
笔记·嵌入式硬件·面试·职场和发展
金色光环10 小时前
【阅读整理】野火ADC_AD7192模块资料
单片机·嵌入式硬件
jllllyuz10 小时前
基于AD7147电容触摸芯片与STC12C5A60S2单片机方案
单片机·嵌入式硬件
范纹杉想快点毕业14 小时前
ZYNQ芯片,SPI驱动开发自学全解析个人笔记【FPGA】【赛灵思
stm32·单片机·嵌入式硬件·mcu·架构·51单片机·proteus
景彡先生14 小时前
STM32 GPIO(通用输入输出)详解:从模式原理到实战应用
stm32·单片机·嵌入式硬件
苏州向日葵15 小时前
篇五 网络通信硬件之PHY,MAC, RJ45
网络·嵌入式硬件
GalaxySinCos15 小时前
07 51单片机之定时器
单片机·嵌入式硬件·51单片机