GD32 IIC(I2C)通信(使用示例为SD2068)

news2025/5/25 3:13:13

一、前言

        最近需要用到GD32的I2C通信,虽然是第一次做I2C通信,但是GD32完整的标准库有现存的I2C通信示例,虽然示例是EEPROM的通信,但是调用的函数应该是大差不差,所以上手比较简单,这里简单记录一下笔记,方便下次使用。

二、GD32与SD2068 的连接

  • SDA:GD32的I2C数据线(我选用的PB10)。

  • SCL:GD32的I2C时钟线(我选用的PB11)。

三、I2C初始化

宏定义和头文件:

#include "gd32e23x.h" //已经包含了gd32e23x_i2c.h

#define I2C_PERIPH             I2C1
#define I2C_SPEED              100000
#define I2C_BUS_ADDRESS        0x32
#define I2C_RCUX               RCU_I2C1
#define I2C_RCU_GPIOX          RCU_GPIOB
#define I2C_SCL_PIN            GPIO_PIN_10
#define I2C_SDA_PIN            GPIO_PIN_11

1、GPIO初始化

void i2c_gpio_config(void)
{
    /* 时钟初始化 */
    rcu_periph_clock_enable(I2C_RCU_GPIOX);

    /* I2C_SCL 引脚复用 */
    gpio_af_set(GPIOB, GPIO_AF_1, I2C_SCL_PIN);
    /* I2C_SDA 引脚复用 */
    gpio_af_set(GPIOB, GPIO_AF_1, I2C_SDA_PIN);
    /* 初始化GPIO复用功能模式 */
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SCL_PIN);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, I2C_SDA_PIN);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
}

 2、I2C功能初始化

void i2c_config(void)
{
    // 启用 I2C 外设的时钟
    rcu_periph_clock_enable(I2C_RCUX);

    // 配置 I2C 的时钟参数:
    // I2C_PERIPH:这里使用的I2C1
    // I2C_SPEED:通信速率(单位为 Hz,常用为 100000 或 400000),这里使用100000
    i2c_clock_config(I2C_PERIPH, I2C_SPEED, I2C_DTCY_2);

    // 配置 I2C 工作模式和地址:
    // I2C_ADDFORMAT_7BITS:使用 7 位地址模式
    // I2C_BUS_ADDRESS:SD2068器件代码0110010 = 0x32
    i2c_mode_addr_config(I2C_PERIPH, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_BUS_ADDRESS);

    // 启用 I2C 外设
    i2c_enable(I2C_PERIPH);

    // 使能 ACK 应答功能,确保在接收数据后自动发送 ACK
    i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
}

四、I2C写实现

        主要过程就是:空闲->发送START 信号->发送设备、寄存器地址和方向->发送数据。封装函数如下:

void i2c_write_multi(uint8_t reg_addr, uint8_t *data, uint8_t dataSize)
{
    // 等待 I2C 总线空闲,防止冲突
    while(i2c_flag_get(I2C_PERIPH, I2C_FLAG_I2CBSY));

    // 发送 START 信号,起始 I2C 通信
    i2c_start_on_bus(I2C_PERIPH);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND));
    
    // 发送设备地址和写入方向(最低位0)
    i2c_master_addressing(I2C_PERIPH, I2C_BUS_ADDRESS << 1, I2C_TRANSMITTER);
		//i2c_data_transmit(I2C_PERIPH, I2C_BUS_ADDRESS << 1);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND));

    // 清除地址发送标志位
    i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND);

    // 发送寄存器地址(子地址)
    i2c_data_transmit(I2C_PERIPH, reg_addr);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_TBE));

    // 开始循环写入多个数据字节
    while(dataSize--) {
				delay_1ms(5);
        i2c_data_transmit(I2C_PERIPH, *data++);
        while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_TBE));
    }

    // 发送 STOP 信号,结束通信
    i2c_stop_on_bus(I2C_PERIPH);
    while(I2C_CTL0(I2C_PERIPH) & I2C_CTL0_STOP);
}

五、I2C读实现

        通信过程与写类似,直接上实现代码:

void i2c_read_multi(uint8_t reg_addr, uint8_t *data, uint8_t dataSize)
{
    // 等待 I2C 总线空闲
    while(i2c_flag_get(I2C_PERIPH, I2C_FLAG_I2CBSY));

    // 发送起始信号
    i2c_start_on_bus(I2C_PERIPH);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND));

    // 发送设备地址
    i2c_master_addressing(I2C_PERIPH, I2C_BUS_ADDRESS << 1, I2C_TRANSMITTER);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND));

    //清地址标志
    i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND);

    // 写入要读取的寄存器地址(子地址)
    i2c_data_transmit(I2C_PERIPH, reg_addr);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_TBE));
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_BTC));

    // 第二次起始信号,重新启动为“读模式”
    i2c_start_on_bus(I2C_PERIPH);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND));

    // 发送设备地址,读方向(1)
    i2c_master_addressing(I2C_PERIPH, I2C_BUS_ADDRESS << 1, I2C_RECEIVER);
    while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND));
    i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND);

    // 如果只读取1个字节,提前关闭ACK,准备发送STOP
    if (dataSize == 1) {
        i2c_ack_config(I2C_PERIPH, I2C_ACK_DISABLE);
        i2c_stop_on_bus(I2C_PERIPH);
    }
    // 读取多个字节循环
    for (uint8_t i = 0; i < dataSize; i++) {
				delay_1ms(5);
        if (i == dataSize - 2) {// 读取即将完成,关闭ACK,准备发送STOP
            i2c_ack_config(I2C_PERIPH, I2C_ACK_DISABLE);
            i2c_stop_on_bus(I2C_PERIPH);
        }

        while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_RBNE));
        data[i] = i2c_data_receive(I2C_PERIPH);
    }

    // 等待 STOP 传输完毕
    while(I2C_CTL0(I2C_PERIPH) & I2C_CTL0_STOP);

    // 恢复 ACK 设置(便于下次通信)
    i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
    i2c_ackpos_config(I2C_PERIPH, I2C_ACKPOS_CURRENT);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2385055.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sanitizers

一、简介 sanitizers 是谷歌提供的一套开源工具&#xff0c;能够发现堆栈读写溢出、内存泄漏、线程数据竞争和死锁等问题。包括&#xff1a; AddressSanitizers (Asan):检测地址相关问题&#xff0c;如use-after-free,heap-buffer-overflow, stack_buffer_overflow,use_after_…

pip代理出现问题 ProxyError

WARNING: Retrying (Retry(total4, connectNone, readNone, redirectNone, statusNone)) after connection broken by ‘ProxyError(‘Cannot connect to proxy.’, NewConnectionError(’<pip._vendor.urllib3.connection.HTTPSConnection object at 0x7f8347ad5ae0>: F…

vue+threeJS 创建镂空球体(SphereGeometry)

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“vuethreeJS 创建镂空球体&#xff08;SphereGeometry&#xff09;”。 上次看到一个做镂空球体的项目&#xff0c;自己也准备尝试着做一做。今天终于做完了&#xff0c;并对这个项目进行梳理。 镂空球体示例效果…

[ Qt ] | 常见控件(一)

目录 Widget enable geometry 标题中的&#xff1a;有一不一定有二&#xff0c;但是有一说明还没结束。 Widget 控件(Widget)&#xff0c;是界面上各种元素&#xff0c;各种部分的统称。 Qt中的控件都是继承自QWidget这个类&#xff0c;是Qt控件体系中&#xff0c;通用的…

【八股战神篇】Java虚拟机(JVM)高频面试题

目录 专栏简介 一 请解释Java虚拟机(JVM)及其主要功能 延伸 1. JVM的基本概念 2. JVM的主要功能 二 对象创建的过程了解吗 延伸 1.Java 创建对象的四种常见方式 三 什么是双亲委派模型 延伸 1.双亲委派机制的作用: 2.双亲委派模型的核心思想: 3.双亲委派模型的…

NDVI谐波拟合(基于GEE实现)

在遥感影像中&#xff0c;我们常用 NDVI&#xff08;归一化植被指数&#xff09;来衡量地表植被的绿度。它简单直观&#xff0c;是生态监测、农情分析的基础工具。但你是否注意到&#xff1a; NDVI 虽然“绿”&#xff0c;却常常“乱”。 因为云层、观测频率、天气干扰&#xf…

南京邮电大学《智能控制技术》期末抢救(上)

一、智能控制的提出 传统控制方法包括经典控制和现代控制——基于被控对象精确模型的控制方式&#xff0c;缺乏灵活性和应变能力&#xff0c;适于解决线性、时不变性等相对简单的控制问题。传统控制方法在实际应用中遇到很多难解决的问题&#xff0c;主要表现以下几点&#xff…

TPDS-2014《Efficient $k$-means++ Approximation with MapReduce》

推荐深蓝学院的《深度神经网络加速&#xff1a;cuDNN 与 TensorRT》&#xff0c;课程面向就业&#xff0c;细致讲解CUDA运算的理论支撑与实践&#xff0c;学完可以系统化掌握CUDA基础编程知识以及TensorRT实战&#xff0c;并且能够利用GPU开发高性能、高并发的软件系统&#xf…

地理特征类可视化图像

目录 一、蜂窝热力地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.python代码实现 (1)代码 (2)实现结果 二、变形地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.python代码实现 (1)代码 (2)实现结果 三、关联地图 1. 特点 (1)优点 (2)缺点 2. 应用场景 3.pyth…

【Java高阶面经:微服务篇】8.高可用全链路治理:第三方接口不稳定的全场景解决方案

一、第三方接口治理的核心挑战与架构设计 1.1 不稳定接口的典型特征 维度表现影响范围响应时间P99超过2秒,波动幅度大(如100ms~5s)导致前端超时,用户体验恶化错误率随机返回5xx/429,日均故障3次以上核心业务流程中断,交易失败率上升协议不一致多版本API共存,字段定义不…

DataGridView中拖放带有图片的Excel,实现数据批量导入

1、带有DataGridView的窗体&#xff0c;界面如下 2、编写DataGridView支持拖放的代码 Private Sub DataGridView1_DragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles DataGridView1.DragEnterIf e.Data.GetDataPresent(DataFormats.FileDrop) ThenDim file…

跨域_Cross-origin resource sharing

同源是指"协议域名端口"三者相同&#xff0c;即便两个不同的域名指向同一个ip,也非同源 1.什么是CORS? CORS是一个W3C标准&#xff0c;全称是"跨域资源共享"&#xff08;Cross-origin resource sharing&#xff09;。它允许浏览器向跨源服务器&#xff…

Opencv常见学习链接(待分类补充)

文章目录 1.常见学习链接 1.常见学习链接 1.Opencv中文官方文档 2.Opencv C图像处理&#xff1a;矩阵Mat 随机数RNG 计算耗时 鼠标事件 3.Opencv C图像处理&#xff1a;亮度对比度饱和度高光暖色调阴影漫画效果白平衡浮雕羽化锐化颗粒感 4.OpenCV —— 频率域滤波&#xff…

大疆制图跑飞马D2000的正射与三维模型

1 问题描述 大疆制图在跑大疆无人机飞的影像的时候&#xff0c;能够自动识别相机参数并且影像自带pos信息&#xff0c;但是用飞马无人机获取的影像pos信息与影像是分开的&#xff08;飞马无人机数据处理有讲&#xff09;&#xff0c;所以在用大疆制图时需要对相机参数进行设置…

ConceptAttention:Diffusion Transformers learn highly interpretable features

ConceptAttention: Diffusion Transformers Learn Highly Interpretable Featureshttps://arxiv.org/html/2502.04320?_immersive_translate_auto_translate=1用flux的attention来做图文的显著性分析。 1.i

物联网低功耗保活协同优化方案:软硬件与WiFi网关动态联动

目录 一、总体方案概述 二、架构组成 2.1 系统拓扑 2.2 硬件端(MCU + WiFi 模组) 2.3 WiFi 网关 2.4 云端服务器 三、低功耗保活技术设计模式 3.1 模式一:定时唤醒 + MQTT 保活 3.1.1 设备端 3.1.2 优势 3.2 模式二:网关保活代理 + 本地网络唤醒 3.2.1 网关功能…

LW-CTrans:一种用于三维医学图像分割的轻量级CNN与Transformer混合网络|文献速递-深度学习医疗AI最新文献

Title 题目 LW-CTrans: A lightweight hybrid network of CNN and Transformer for 3Dmedical image segmentation LW-CTrans&#xff1a;一种用于三维医学图像分割的轻量级CNN与Transformer混合网络 01 文献速递介绍 三维医学图像分割旨在从计算机断层扫描&#xff08;CT…

光谱相机在地质勘测中的应用

一、‌矿物识别与蚀变带分析‌ ‌光谱特征捕捉‌ 通过可见光至近红外&#xff08;400-1000nm&#xff09;的高光谱分辨率&#xff08;可达3.5nm&#xff09;&#xff0c;精确识别矿物的“光谱指纹”。例如&#xff1a; ‌铜矿‌&#xff1a;在400-500nm波段反射率显著低于围…

Autodl训练Faster-RCNN网络(自己的数据集)

参考文章&#xff1a; Autodl服务器中Faster-rcnn(jwyang)复现(一)_autodl faster rcnn-CSDN博客 Autodl服务器中Faster-rcnn(jwyang)训练自己数据集(二)_faster rcnn autodl-CSDN博客 环境配置 我到下载torch这一步老是即将结束的时候自动结束进程&#xff0c;所以还是自己…

NFS服务小实验

实验1 建立NFS服务器&#xff0c;使的客户端顺序共享数据 第一步&#xff1a;服务端及客户端的准备工作 # 恢复快照 [rootserver ~]# setenforce 0 ​ [rootserver ~]# systemctl stop firewalld ​ [rootserver ~]# yum install nfs-utils -y # 服务端及客户端都安装 …