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

一、前言

        最近需要用到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),这里使用100000i2c_clock_config(I2C_PERIPH, I2C_SPEED, I2C_DTCY_2);// 配置 I2C 工作模式和地址:// I2C_ADDFORMAT_7BITS:使用 7 位地址模式// I2C_BUS_ADDRESS:SD2068器件代码0110010 = 0x32i2c_mode_addr_config(I2C_PERIPH, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_BUS_ADDRESS);// 启用 I2C 外设i2c_enable(I2C_PERIPH);// 使能 ACK 应答功能,确保在接收数据后自动发送 ACKi2c_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,准备发送STOPif (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,准备发送STOPi2c_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.pswp.cn/bicheng/82124.shtml

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

相关文章

React从基础入门到高级实战:React 基础入门 - 列表渲染与条件渲染

列表渲染与条件渲染 在 React 开发中&#xff0c;列表渲染 和 条件渲染 是处理动态数据和用户交互的基础技术。通过列表渲染&#xff0c;你可以根据数据动态生成 UI 元素&#xff1b;而条件渲染则让你根据特定条件展示不同的内容。这两个技能在实际项目中非常常见&#xff0c;…

在Java的list.forEach(即 Stream API 的 forEach 方法)中,无法直接使用 continue 或 break 语句的解决办法

说明 在 Java 的 list.forEach&#xff08;即 Stream API 的 forEach 方法&#xff09;中&#xff0c;无法直接使用 continue 或 break 语句&#xff0c;因为它是一个终结操作&#xff08;Terminal Operation&#xff09;&#xff0c;依赖于 Lambda 表达式或方法引用。 有些时…

(7)Spring 6.x 响应式编程模型

Spring 6.x 响应式编程模型 👉 点击展开题目 Spring 6.x中的响应式编程模型与传统的Servlet模型相比有哪些优势?如何实现两者的无缝迁移? 📌 Spring 6.x 响应式编程模型概述 Spring 6.x 中的响应式编程模型基于 Project Reactor 构建,采用非阻塞、事件驱动的架构,通过…

排序和排列——蓝桥杯备考

1.十大排序算法 本次用下面的例题详解这十种排序算法 题目描述 将读入的 N 个数从小到大排序后输出。 输入格式 第一行为一个正整数 N。 第二行包含 N 个空格隔开的正整数 ai​&#xff0c;为你需要进行排序的数。 输出格式 将给定的 N 个数从小到大输出&#xff0c;数之间空格…

C# 高效读取大文件

在 C# 中高效读取大文件时&#xff0c;需根据文件类型和场景选择不同的技术方案&#xff0c;以下为综合实践方法及注意事项&#xff1a; 一、文本文件读取方案 逐行读取 StreamReader.ReadLine‌&#xff1a;通过流式处理逐行加载文本&#xff0c;避免一次性加载整个文件到内…

深度学习模型可视化:Netron的安装和使用

文章目录 Netron简介Netron加载模型类型Netron使用方式Netron功能介绍完整案例总结 Netron简介 Netron是一个支持PyTorch的可视化工具&#xff0c;它的开发者是微软的Lutz Roeder&#xff0c;操作简单快捷&#xff0c;就像保存文件、打开文件一样&#xff0c;简单高效。Netron…

pytorch LSTM 结构详解

最近项目用到了LSTM &#xff0c;但是对LSTM 的输入输出不是很理解&#xff0c;对此&#xff0c;我详细查找了lstm 的资料 import torch.nn as nnclass LSTMModel(nn.Module):def __init__(self, input_size1, hidden_size50, num_layers2):super(LSTMModel, self).__init__()…

AUTOSAR AP 入门0:AUTOSAR_EXP_PlatformDesign.pdf

AUTOSAR AP官网&#xff1a;AUTOSAR Adaptive Platform设计AUTOSAR AP的目的&#xff0c;翻译版官方文档 AUTOSAR_EXP_PlatformDesign.pdf &#xff1a; https://mp.weixin.qq.com/s?__bizMzg2MzAyMDIzMQ&mid2247553050&idx2&sn786c3a1f153acf99b723bf4c9832acaf …

零碳办会新范式!第十届国际贸易发展论坛——生物能源和可持续发展专场,在京举办

2025年5月16日&#xff0c;第十届国际贸易发展论坛在北京国际饭店盛大启幕。本届论坛由北京绿林认证有限公司主办。作为汇聚行业智慧、引领发展方向的盛会&#xff0c;国际贸易发展论坛每两年一届&#xff0c;本次会议是第十届&#xff0c;至今已走过近20年光辉历程。多年来&am…

ECharts图表工厂,完整代码+思路逻辑

Echart工厂支持柱状图&#xff08;bar&#xff09;折线图&#xff08;line&#xff09;散点图&#xff08;scatter&#xff09;饼图&#xff08;pie&#xff09;雷达图&#xff08;radar&#xff09;极坐标柱状图&#xff08;polarBar&#xff09;和极坐标折线图&#xff08;po…

如何制作令人印象深刻的UI设计?

1. 规划用户旅程 规划用户旅程是创建高效且吸引人的UI设计的第一步。设计师需要深入了解目标用户群体的需求和行为模式&#xff0c;这通常涉及用户调研、创建用户角色&#xff08;Personas&#xff09;和绘制用户旅程图&#xff08;User Journey Maps&#xff09;。通过这种方…

k8s 离线安装 kube-prometheus-stack

配置共享存储 Prometheus 需要配置持久化存储&#xff0c;防止数据丢失 服务端 服务端安装 NFS 服务 sudo apt install nfs-kernel-server 创建共享目录&#xff0c;在服务器端创建 /nfs 目录。 mkdir /nfs chmod -R 777 /nfs # 设置文件权限 nfs目录下只给了默认权限&#xff…

ceph osd 磁盘分区对齐

分区对齐可以提高读写速度的原理是什么 分区对齐可以提高磁盘读写速度的原理主要在于 磁盘的物理扇区大小与操作系统发起的读写请求之间是否对齐。如果不对齐,每次读写操作可能会跨越多个物理扇区,造成额外的 I/O 操作,从而降低性能。 🔧 原理详解 1. 物理扇区(Physica…

Simon J.D. Prince《Understanding Deep Learning》

学习神经网络和深度学习推荐这本书&#xff0c;这本书站位非常高&#xff0c;且很多问题都深入剖析了&#xff0c;甩其他同类书籍几条街。 多数书&#xff0c;不深度分析、没有知识体系&#xff0c;知识点零散、章节之间孤立。还有一些人Tian所谓的权威&#xff0c;醒醒吧。 …

【泛微系统】后端开发Action常用方法

后端开发Action常用方法 代码实例经验分享:代码实例 经验分享: 本文分享了后端开发中处理工作流Action的常用方法,主要包含以下内容:1) 获取工作流基础信息,如流程ID、节点ID、表单ID等;2) 操作请求信息,包括请求紧急程度、操作类型、用户信息等;3) 表单数据处理,展示…

SSH的screen方法

创建一个screen窗口&#xff0c;&#xff08;在需要运行程序的文件夹内&#xff09;使用 screen -S name 命令&#xff0c;其中 name 是窗口的名字。 在窗口中执行需要的命令。 当需要临时离开时&#xff0c;使用快捷键 ctrlA D 回来时&#xff0c;使用 screen -r name 恢复…

无法访问org.springframework.boot.SpringApplication

无法访问org.springframework.boot.SpringApplication 检查springboot和jdk的版本是否适配检查jdk的设置是否统一 主要检查下面几处地方

洛谷 P1800 software(DP+二分)【提高+/省选−】

题目链接 https://www.luogu.com.cn/problem/P1800 思路 对于大于等于最优解的天数&#xff0c;一定能使公司交付软件。对于小于最优解的天数&#xff0c;一定无法使公司交付软件。所以考虑二分答案 x x x。 定义 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i个人做了 j j j…

C++性能测试工具——sysprof的使用

一、sysprof sysprof相对于前面的一些性能测试工具来说&#xff0c;要简单不少。特别是其图形界面的操作&#xff0c;非常容易上手&#xff0c;它还支持分析文件的保存和导入功能&#xff0c;这是一个非常不错的功能。做为一款系统性能测试工具&#xff0c;它支持多种硬件平台…

redis数据持久化和配置-15(备份和还原 Redis 数据)

备份和还原 Redis 数据 备份和恢复数据是管理任何数据库系统&#xff08;包括 Redis&#xff09;的关键方面。数据丢失可能是由于硬件故障、软件错误、意外删除甚至恶意攻击而发生的。因此&#xff0c;拥有强大的备份和恢复策略对于确保数据持久性和业务连续性至关重要。本课将…