基于RT-Thread的STM32F4开发第五讲——软件模拟I2C

文章目录

  • 前言
  • 一、RT-Thread工程创建
  • 二、AT24C02
  • 三、函数编写
    • 1.I2C_soft.c
    • 2.I2C_soft.h
    • 3.main.h
  • 四、效果展示
  • 五、资源分享
  • 总结


前言


本章是基于RT-Thread studio实现软件模拟I2C,开发板是正点原子的STM32F4探索者,使用的RT-Thread驱动是5.1.0,使用的I2C通讯芯片是存储芯片AT24C02,本章和前面文章不同在于I2C是软件模拟,与设备无关,所以驱动文件不会有问题,但是对于代码开发官方文档有些重要内容没有提到,本文将进行补充。

一、RT-Thread工程创建

这里只需要按前文得到一个不报错的基础工程,因为是软件模拟I2C,所以不需要去cubemx进行硬件配置。
然后去board.h找到I2C的定义区间,使能一个I2C型号,将SCL和SDA按你的使用的开发板引脚定义。我这里使能了I2C1,SCL接入的引脚是PB8,SDA接入的引脚是PB9,如下。
在这里插入图片描述
然后去设置中打开软件模拟I2C开关,Use GPIO to soft simulate I2C感觉重复了,开不开对工程没有影响,对于debug message开启的话可以看到I2C通讯的工作流程。
在这里插入图片描述
到此,I2C工程配置完成

二、AT24C02

AT24C02是接下来用到的I2C通讯芯片,我简单说明一下。
AT24C02 是一款由 低功耗串行电可擦除只读存储器(EEPROM),通过 I²C 总线进行通信。支持标准模式(100kHz)和快速模式(400kHz)。
2K 位(256 字节)存储空间,分为 32 页,每页 8 字节。地址范围:0x00~0xFF(地址低3位为页内地址,高5位为页面地址)。一个页面
只能写入8字节,超过的数据将写入下一个页面。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、函数编写

1.I2C_soft.c

先看代码,再看讲解

#include "I2C_soft.h"
#define DBG_TAG "I2C_soft"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>#define     I2C1_NAME   "i2c1"
#define     SLAVE_ADDR  0xa0>>1//data[0]为数据地址,后面开始是写入数据
int write_i2c1reg(rt_uint8_t *data,rt_uint8_t data_byte)
{rt_uint8_t i2c1_flag = 0;struct rt_i2c_bus_device *i2c1_bus;i2c1_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C1_NAME);if(i2c1_bus == RT_NULL){LOG_D("failed to i2c1 bus find");return -1;}i2c1_flag = (rt_uint8_t)rt_i2c_master_send(i2c1_bus, SLAVE_ADDR, RT_NULL, data, data_byte);if(i2c1_flag != data_byte){LOG_D("failed to i2c1 send");return -1;}return 0;
}
//data_add为读数据地址
int read_i2c1reg(rt_uint8_t data_add,rt_uint8_t *data,rt_uint8_t data_byte)
{rt_uint8_t i2c1_flag = 0;struct rt_i2c_bus_device *i2c1_bus;i2c1_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C1_NAME);if(i2c1_bus == RT_NULL){LOG_D("failed to i2c1 bus find");return -1;}rt_i2c_master_send(i2c1_bus, SLAVE_ADDR, RT_NULL, &data_add, 1);i2c1_flag = (rt_uint8_t)rt_i2c_master_recv(i2c1_bus, SLAVE_ADDR, RT_NULL, data, data_byte);if(i2c1_flag != data_byte){LOG_D("failed to i2c1 recv");return -1;}return 0;
}

按照图1,器件地址应该是0xa0(W)或0xa1®,最后一位为读写位,但是官方手册明确说明了不包含读写位。如下
在这里插入图片描述
所以,后面的函数默认传入的地址是不带最后一位的7位地址,然后根据flags标志形成8位地址作为器件地址,具体操作是将输入的地址左移1位,然后或上读写位成为最终地址,那么为了保证最终地址不出错,所以我们传入的地址就要先右移一位。
我这里使用rt_i2c_master_sendrt_i2c_master_recv写入和读出数据,代码上更简介,这两个函数就是把rt_i2c_transfer和传输的消息数组指针封装了一下。
在这里插入图片描述
另外对于rt_i2c_transfer函数第三个参数我觉得官网解释有误,num只能是1,否则就会出错。要符合官方文档的定义,你每次用rt_i2c_transfer只能写入一个字节,那就效率太低了。所以最好不要用这个函数,用上面两个函数,如果实在要用,那就记住num只能是1,和你数组元素个数无关。
在这里插入图片描述
当我们使用rt_i2c_master_send传输数据时,如果标志位flag不写入RT_I2C_NO_START /* 无开始条件 */,那么自动一开始发送一个起始位和一个器件地址字节和应答,后面就是一个数据字节一个应答,达到发送的数据个数后一个停止位,刚好符合图2中AT24C02的写入格式,所以我的写入函数没有问题。就是注意数组第一位是数据字节地址,后面才是写入的数据内容。

提示
如果分开操作,把数据地址独立出来应该如下操作。

//data_add为数据地址,data为写入数据数组
rt_i2c_master_send(i2c1_bus, SLAVE_ADDR, RT_I2C_NO_STOP, &data_add, 1);
rt_i2c_master_send(i2c1_bus, SLAVE_ADDR, RT_I2C_NO_START, data, data_byte);

可见RT_I2C_NO_STOP会去除停止位,RT_I2C_NO_START会去除起始位和器件地址字节

对于接收函数,按照图3的数据格式,先采用rt_i2c_master_send(i2c1_bus, SLAVE_ADDR, RT_NULL, &data_add, 1);发送一个读数据地址,然后使用rt_i2c_master_recv(i2c1_bus, SLAVE_ADDR, RT_NULL, data, data_byte);将读到的数据存入数组data中,data_byte是读取数据字节数,rt_i2c_master_recv的flag同理。

弄清了以上这些,遇见了其他的I2C通讯芯片,只要按照它的读写格式,就能利用rt_i2c_master_sendrt_i2c_master_recv配置出需要的格式。

2.I2C_soft.h

#ifndef APP_I2C_SOFT_H_
#define APP_I2C_SOFT_H_#include <board.h>
//data[0]为数据地址,后面开始是写入数据
int write_i2c1reg(rt_uint8_t *data,rt_uint8_t data_byte);
int read_i2c1reg(rt_uint8_t data_add,rt_uint8_t *data,rt_uint8_t data_byte);#endif /* APP_I2C_SOFT_H_ */

3.main.h

#include <rtthread.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "I2C_soft.h"int main(void)
{rt_uint8_t i2c1_wd[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10};rt_uint8_t i2c1_rd[8] = {0};write_i2c1reg(i2c1_wd, 10);rt_thread_mdelay(100);read_i2c1reg(0x00,i2c1_rd, 9);rt_thread_mdelay(100);for(int i = 0;i<9;i++){rt_kprintf("i2c1 read data id 0x%x\n",i2c1_rd[i]);}read_i2c1reg(0x08,i2c1_rd, 9);rt_thread_mdelay(100);for(int i = 0;i<9;i++){rt_kprintf("i2c1 read data id 0x%x\n",i2c1_rd[i]);}while (1){rt_thread_mdelay(1000);}return RT_EOK;
}

四、效果展示

在这里插入图片描述
为什么是这样效果我就不解释了,如果你看懂了这篇文章你就知道为什么是这样了(AT24C02默认无数据写入空间值为0xff)

五、资源分享

通过网盘分享的文件:I2C_soft.zip
链接: https://pan.baidu.com/s/1k1P0mUaXDR7jJ6dwgJJ7QQ?pwd=iims 提取码: iims


总结

对于软件模拟的I2C好处是兼容性好,移植容易,对硬件设计要求不高,缺点就是传输速率很低,效率不高,占用系统资源过大。我看了一下,好像RT-Thread并没有设计硬件I2C驱动。另外RT-Thread可以安装AT24C02的软件包,可以尝试使用一下。

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

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

相关文章

49、c# 能⽤foreach 遍历访问的对象需满足什么条件?

在 C# 中&#xff0c;要使用 foreach 循环遍历一个对象&#xff0c;该对象必须满足以下条件之一&#xff1a; 1. 实现 IEnumerable 或 IEnumerable 接口 非泛型版本&#xff1a;System.Collections.IEnumerable public class MyCollection : IEnumerable {private int[] _da…

推客小程序系统开发:全栈式技术解决方案与行业赋能实践​

​ 在数字化营销深度渗透各行业的当下&#xff0c;传统推广模式已难以满足企业精细化运营与高效获客的需求。专业的推客小程序系统凭借其强大的裂变传播能力与灵活的推广机制&#xff0c;成为企业构建私域流量池、提升推广效能的核心工具。我们基于多年技术沉淀与行业洞察&…

WPF布局系统详解:掌握界面设计的核心艺术

掌握界面设计的核心艺术 1. WPF布局系统概述2. Grid布局详解2.1 基本行列定义2.2 单元格定位与跨行跨列 3. StackPanel布局4. DockPanel布局5. WrapPanel与Canvas5.1 WrapPanel自动换行布局 5. Canvas绝对定位6. 布局嵌套与综合应用7. 布局性能优化8. 响应式布局技巧9. 实战&am…

labview实现LED流水灯的第一种方法

目的&#xff1a;写一个跑马灯程序&#xff0c;7个灯从左到右不停的轮流点亮&#xff0c;闪烁间隔由滑动条调节。 一、方法1&#xff1a;使用顺序结构 使用顺序结构&#xff0c;平铺式顺序结构与创建局部变量实现LED流水灯 具体步骤如下&#xff1a; 第一步&#xff0c;选择…

uniapp如何设置uni.request可变请求ip地址

文章目录 简介方法一&#xff1a;直接在请求URL中嵌入变量方法二&#xff1a;使用全局变量方法三&#xff1a;使用环境变量方法四&#xff1a;服务端配置方法五&#xff1a;使用配置文件&#xff08;如config.js&#xff09;:总结 简介 在uni-app中&#xff0c;uni.request 用…

深度学习篇---LSTMADF轨迹预测

文章目录 前言LSTM 轨迹预测原理应用在行人轨迹预测方面在自动驾驶车辆的轨迹预测中优点缺点APF 轨迹预测原理应用在船舶运动规划在无人驾驶车辆避障轨迹跟踪优点缺点示例代码前言 本文简单介绍LSTM(长短期记忆网络)和ADF(人工势场法)这两种不同的轨迹预测方法。 LSTM 轨迹…

python实现Web请求与响应

目录 一&#xff1a;什么是Web请求与响应&#xff1f; 1&#xff1a;Web请求 2&#xff1a;Web响应 3&#xff1a;HTTP协议概述 4&#xff1a;常见的HTTP状态码包括&#xff1a; 二&#xff1a;python的requests库 1&#xff1a;安装requests库 2&#xff1a;发送GET请…

Unity使用sherpa-onnx实现说话人识别

网友软绵绵的面包人推荐&#xff0c;模型3dspeaker_speech_eres2net_base_200k_sv_zh-cn_16k-common.onnx的效果比3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx要好 具体代码 using System; using System.Collections.Generic; using System.IO; using Sherpa…

ElasticSearch-集群

本篇文章依据ElasticSearch权威指南进行实操和记录 1&#xff0c;空集群 即不包含任何节点的集群 集群大多数分为两类&#xff0c;主节点和数据节点 主节点 职责&#xff1a;主节点负责管理集群的状态&#xff0c;例如分配分片、添加和删除节点、监控节点故障等。它们不直接…

LG P9844 [ICPC 2021 Nanjing R] Paimon Segment Tree Solution

Description 给定序列 a ( a 1 , a 2 , ⋯ , a n ) a(a_1,a_2,\cdots,a_n) a(a1​,a2​,⋯,an​)&#xff0c;有 m m m 次修改 ( l , r , v ) (l,r,v) (l,r,v)&#xff1a; 对每个 i ∈ [ l , r ] i\in[l,r] i∈[l,r]&#xff0c;令 a i ← a i v a_i\gets a_iv ai​←…

Google Prompt Tuning:文本嵌入优化揭秘

Google Research Prompt Tunin :from_embedded_string 在 Google Research 的 Prompt Tuning 项目代码库 中,from_embedded_string 函数主要用于基于字符串文本初始化提示词的嵌入向量,其调用场景通常与提示词优化或任务适配相关。 1. 核心代码位置 from_embedded_string …

网页 H5 微应用接入钉钉自动登录

ℹ️关于云审批 云审批&#xff08;cloud approve&#xff09; &#xff0c;一款专为小微企业打造&#xff0c;支持多租户的在线审批神器。它简化了申请和审批流程&#xff0c;让您随时随地通过手机或电脑完成请款操作。员工一键提交申请&#xff0c;审批者即时响应&#xff0c…

idea无法识别Maven项目

把.mvn相关都删除了 导致Idea无法识别maven项目 或者 添加导入各个模块 最后把父模块也要导入

飞桨paddle import fluid报错【已解决】

跟着飞桨的安装指南安装了paddle之后 pip install paddlepaddle有一个验证&#xff1a; import paddle.fluid as fluid fluid.install check.run check()报错情况如下&#xff0c;但是我在pip list中&#xff0c;确实看到了paddle安装上了 我import paddle别的包&#xff0c…

现代化SQLite的构建之旅——解析开源项目Limbo

现代化SQLite的构建之旅——解析开源项目Limbo 在当今飞速发展的技术世界中,轻量级且功能强大的数据库已成为开发者的得力助手。当我们谈论轻量级数据库时,SQLite无疑是一个举足轻重的名字。然而,随着技术的进步,我们对数据库的需求也变得更加多样化。这正是Limbo项目诞生…

MinIO:从入门到精通,解锁云原生存储的奥秘

一、引言&#xff1a;为什么 MinIO 正在重塑存储世界&#xff1f; 在云计算和大数据时代&#xff0c;传统存储系统面临扩展性差、成本高、兼容性不足等挑战。MinIO 凭借其 S3 兼容性、分布式架构、高性能存储 等特性&#xff0c;成为企业构建现代化存储基础设施的首选。 本文…

vscode怎么关闭自动定位文件

关闭自动定位文件功能 方式1 在设置中搜索: explorer.autoReveal 方式2 直接在settings.json中增加"explorer.autoReveal": false 添加类似jetbrains IDE的文件定位功能 可以直接安装插件市场搜索niushuaibing.vs-location, 安装后会有文件定位按钮, 点击后即可…

学习路之uniapp--unipush2.0推送功能--给自己发通知

学习路之uniapp--unipush2.0推送功能--给自己发通知 一、绑定云空间及创建云函数二、编写发送界面三、效果后期展望&#xff1a; 一、绑定云空间及创建云函数 package.json {"name": "server-push","dependencies": {},"main": "…

什么是VR展示?VR展示的用途

随着科技的迅猛发展&#xff0c;我们步入一个全新的数字时代。在这个时代&#xff0c;虚拟现实&#xff08;VR&#xff09;技术崭露头角&#xff0c;逐步改变我们对世界的认知。全景展示厅作为VR技术与传统展览艺术的完美结合&#xff0c;以独特的全景视角&#xff0c;引领我们…

抖音IP属地跟无线网有关吗?如何更改

IP属地显示功能让许多用户感到好奇——为什么自己的位置信息有时准确&#xff0c;有时却显示在其他城市&#xff1f;这时&#xff0c;用户会疑惑&#xff1a;抖音IP属地跟无线网有关系吗&#xff1f;抖音的IP属地显示与其所使用的网络类型&#xff08;包括无线网&#xff09;密…