基于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_send和rt_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_send和rt_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的软件包,可以尝试使用一下。
相关文章:
基于RT-Thread的STM32F4开发第五讲——软件模拟I2C
文章目录 前言一、RT-Thread工程创建二、AT24C02三、函数编写1.I2C_soft.c2.I2C_soft.h3.main.h 四、效果展示五、资源分享总结 前言 本章是基于RT-Thread studio实现软件模拟I2C,开发板是正点原子的STM32F4探索者,使用的RT-Thread驱动是5.1.0࿰…...
pkucpc2025 L:Game on Tree
题意 两个人在一棵无根树上玩游戏,每次可以删掉若干个叶子节点,不能操作的人输。 思路 比赛的时候我去写H Quintuple了,队友貌似在我写的时候把这道题讨论出来了。 后来补题的时候花了大概花了70分钟左右ac这道题。 首先考虑一条链的情况…...
大数据实时分析:ClickHouse、Doris、TiDB 对比分析
随着企业对数据分析实时性、复杂性和多样性的要求越来越高,传统的批处理数仓已经无法满足实时指标看板、流量监控、用户行为分析等场景需求。因此,越来越多的公司开始引入实时分析型数据库系统。 目前,国内外常见的实时分析数据库有: ClickHouse:列式数据库,极致的分析性…...
网络流量分析系统的十大应用场景
在现代企业和组织的IT运维体系中,网络流量分析系统(Network Traffic Analysis, NTA)早已不仅仅是用来查看带宽使用率的“流量计数器”。随着网络环境的复杂化、攻击技术的不断演进,以及对业务连续性要求的提升,网络流量…...
问题 | 代码审查:函数是否包含返回语句
“函数是否包含返回语句”这一问题的核心是:在编程中,函数是否按照设计要求正确使用了 返回语句(如 return、return value),以便向调用者传递结果或控制权。以下是详细解释: 1. 什么是函数的返回语句&#…...
Spring Bean 生命周期中设计模式的应用与解析
Spring Bean 生命周期中使用的设计模式 Spring Bean 的生命周期涉及多个阶段和扩展点,Spring 框架在这一过程中巧妙运用了多种设计模式,以实现强大的功能和灵活性。以下是主要设计模式及其应用场景: 1. 工厂模式(Factory Patter…...
设计模式的原理及深入解析
创建型模式 创建型模式主要关注对象的创建过程,旨在通过不同的方式创建对象,以满足不同的需求。 工厂方法模式 定义:定义一个创建对象的接口,让子类决定实例化哪一个类。 解释:工厂方法模式通过定义一个创建对象的…...
kotlin flow的两种SharingStarted策略的区别
一 两种 SharingStarted 策略的区别: SharingStarted.Eagerly: 立即开始收集上游流,即使没有下游订阅者持续保持活跃状态,直到 ViewModel 被清除优点:响应更快,数据始终保持最新缺点:消耗更多资源&#x…...
BGP综合实验(2)
一、实验需求 1、实验拓扑图 2、实验需求 使用 PreVal 策略,让 R4 经 R2 到达 192.168.10.0/24 。 使用 AS_Path 策略,让 R4 经 R3 到达 192.168.11.0/24 。 配置 MED 策略,让 R4 经 R3 到达 192.168.12.0/24 。 使用 Local Preference 策…...
python使用jsonpath-ng库操作json数据
jsonpath-ng 库的详细使用如下: 一、安装与导入 安装 通过 pip 安装库: pip install jsonpath-ng支持 Python 3.6 及以上版本。 导入核心模块 主要使用 parse 函数和 JSONPath 对象: from jsonpath_ng import parse二、基础查询操作 1. 简单…...
通用简洁工作汇报项目评估营销策划工作总结年终汇报PPT模版8套一组分享
工作总结汇报PPT模版8套一组分享:工作总结汇报PPT模版分享https://pan.quark.cn/s/04b7ab7a47c4 第一套PPT模版,主要是黄色和灰色调,上方有大面积黄色不规则形状背景,有“POWERPOINT”和“XXXXPPT模版”字样,左侧是黑…...
掌握Git:版本控制与高效协作指南
一、初始Git 提出问题:无论是在工作还是学习,我们在编写各种文档的时候,更改失误,失误后恢复到原来版本,不得不复制出一个副本。 每个版本由各自的内容,但最终只有一个报告需要被我们使用。 但在此之前的…...
ubuntu下配置vscode生成c_cpp_properties.json
-------------学习记录--------------- 在ubuntu下使用vscode时发现cpp文件无法读到头文件,明明头文件在合适的路径下,由于没有制定头文件的路径造成的这个问题。用这篇文章进行简单记录解决方法 ctrlshiftp打开命令面板,也可以点击左上角, …...
Qt读取Excel文件的技术实现与最佳实践
目录 一、成果展示二、核心方法及原理1. QAxObject(基于COM接口)2. 第三方库QXlsx3. ODBC数据库驱动 三、实现步骤详解1. QAxObject读取Excel(需安装Excel/WPS)2. QXlsx读取Excel(跨平台方案) 四、技术选型…...
双条件拆分工作表,一键生成独立工作簿-Excel易用宝
你是否遇到过这样的崩溃瞬间?面对一张密密麻麻的销售数据表,需要按指定维度拆分成工作簿和工作表,而你却只能手动复制粘贴到不同工作簿、工作表,改一个字段就花半小时,数据量大时甚至要熬夜加班? 别担心&a…...
iOS 蓝牙开发中的 BT 与 BLE
在 iOS 开发者的语境里,大家把 BT 和 BLE 当成两种不同的蓝牙技术在谈——它们来自同一个 Bluetooth 规范,但面向的场景、协议栈乃至 Apple 提供的 API 都截然不同。 缩写全称 / 技术名称规范层叫法iOS 支持现状典型用途BTBluetooth Classic(经典蓝牙)又叫 BR/EDR(Basic R…...
TCP和套接字SSL加密连接行为分析
目录 一、前言 二、背景 三、参数介绍 3.1、 have_openssl 3.2、have_ssl 3.3、require_secure_transport 四、--ssl-modemode 五、CREATE USER SSL/TLS选项 六、问题验证 6.1、使用套接字连接 6.2、使用TCP连接 七、分析与总结 一、前言 SSL(Secure S…...
kafka 问与答
kafka Q&A How does the client connect to kafka and discovery the brokers. client 只需要知道一部分nodes(brokers)的地址既可以,client 会自动发现剩下的所有topic partition leader nodes, 然后连接上。 When a client connects:It uses the bootstrap…...
docker默认存储迁移
在容器化场景下默认存储路径为(/var/lib/docker)大多数平台根目录不支持系统盘扩容,会有空间不足风险隐患,因未配置持久化存储导致容器数据丢失。以迁移Docker存储路径至大容量/data目录说明 一、停止容器 systemctl stop docke…...
Ubuntu20.04系统下使用交叉编译工具链(aarch、x86)交叉编译opencv4.5.0
文章目录 0. 引言1. 准备交叉编译工具链2. 安装依赖工具3. 下载 OpenCV 源码4. 创建交叉编译工具链文件5. 配置 CMake 构建6. 构建 OpenCV7. 安装 OpenCV8. 验证9. 问题及解决办法 0. 引言 Ubuntu20.04系统下使用交叉编译工具链(aarch、x86)交叉编译ope…...
R语言数据可视化
R note book 文档–输出html格式文档,plotly不能生成PDF文件 --- title: "R语言数据可视化" output: html_notebook ---在R语言中进行数据可视化是数据分析和呈现的重要环节,R提供了多种强大的绘图系统和工具。以下是常见的数据可视化方法和示…...
NLP学习路线图(一): 线性代数(矩阵运算、特征值分解等)
引言:语言与矩阵的奇妙邂逅 在自然语言处理(NLP)的魔法世界里,每个词语都像被施了变形术的精灵,在数学的殿堂中翩翩起舞。当我们用"king - man woman queen"这样的向量魔法破解语义密码时,线性…...
【滑动窗口】LeetCode 1004题解 | 最大连续1的个数 Ⅲ
最大连续1的个数 Ⅲ 一、题目链接二、题目三、题目解析四、算法原理解法一:暴力枚举 zero计数器解法二:滑动窗口 五、编写代码六、时空复杂度 一、题目链接 最大连续1的个数 Ⅲ 二、题目 三、题目解析 注意题目中说的是最多k次,在一个数组…...
Linux 内核等待机制详解:prepare_to_wait_exclusive 与 TASK_INTERRUPTIBLE
1. prepare_to_wait_exclusive 函数解析 1.1 核心作用 prepare_to_wait_exclusive 是 Linux 内核中用于将进程以独占方式加入等待队列的关键函数,其主要功能包括: 标记独占等待:通过设置 WQ_FLAG_EXCLUSIVE 标志,表明此等待条目是独占的。 安全入队:在自旋锁保护下,将条…...
分布式数据库TiDB:深度解析原理、优化与架构设计
💂 个人网站:【 摸鱼游戏】【神级代码资源网站】【星海网址导航】 一、TiDB架构设计与核心原理 1.1 分布式架构演进 传统分库分表 vs TiDB架构 #mermaid-svg-8I88Hg2AVkzYTb3O {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fi…...
【深度学习基础】损失函数与优化算法详解:从理论到实践
【深度学习基础】损失函数与优化算法详解:从理论到实践 一、引言 1. 损失函数与优化算法在深度学习中的核心作用 在深度学习中,模型训练的本质是通过不断调整参数,使模型输出尽可能接近真实值。这一过程的核心驱动力是损失函数(…...
睿抗足球机器人
目录 大框架 战术 Lua脚本语言编辑环境 大框架 策略脚本(LUA-官方脚本)、决策算法(C-自定义)、ROS系统 战术 我们研究了场地的长度、宽度、禁区范围、机器人运动速度等等,发现即使 Kicker 点球往极端角度踢…...
助力DBA技能无缝平迁 | YashanDB携最新成果亮相XCOPS智能运维管理人年会
5 月 16 日,由上海市软件行业协会、上海市计算机行业协会指导, dbaplus社群主办的XCOPS智能运维管理人年会在广州盛大召开,活动汇聚500余名金融、政府、能源、教育、电信、交通等领域的行业专家。深算院崖山数据库受邀参会,系统性…...
服务端安全测试:OWASP ZAP使用
ZAP下载地址:https://www.zaproxy.org/download/ ZAP有两种扫描方式: 1、使用 OpenAPI / Swagger 地址进行扫描 2、ZAP Proxy + Postman 因为业务云没有添加swagger插件所以本次介绍第2种方式。 【第一步】设置 ZAP 的代理端口(默认是 127.0.0.1:8080) 成功安装并打…...
Amazon Q 从入门到精通 – 测试与重构
Amazon Q Developer 是亚马逊推出的一个专为专业开发人员设计的人工智能助手,旨在提升代码开发和管理效率。其主要功能包括代码生成、调试、故障排除和安全漏洞扫描,提供一站式代码服务。 众所周知,在软件开发领域,测试代码是软件…...
[CSS3]属性增强2
空间转换 使用transform属性实现元素在空间内的位移、旋转、缩放等效果 空间: 是从坐标轴角度定义的。x、y 和z三条坐标轴构成了一个立体空间,z轴位置与视线方向相同。空间转换也叫3D转换 空间位移 使用translate实现元素空间位移效果 transform: translate3d(x…...
Go 语言 vs C+Lua(Skynet)游戏服务器方案对比分析
为啥挑这两个呢?因为两种技术分别对应CSP模型和Actor模型,都是经过时间检验的成熟且可靠的并发模型,问了很多地方,经过gpt整理得出如下报告。 从开发效率、运行性能、热更新扩展、云部署与水平扩展能力、多类型游戏支持等五个维度…...
ArcGIS Pro 3.4 二次开发 - 内容
环境:ArcGIS Pro SDK 3.4 .NET 8 文章目录 内容1 工程1.1 创建一个空工程1.2 使用指定名称创建新工程1.3 使用Pro的默认设置创建新工程1.4 使用自定义模板文件创建新工程1.5 使用 ArcGIS Pro 提供的模板创建工程1.6 打开现有工程1.7 获取当前工程1.8 获取当前工程的…...
java每日精进 5.19【Excel 导入导出】
基于 EasyExcel 实现 Excel 的读写操作,可用于实现最常见的 Excel 导入导出等功能。 Excel 导入导出功能涉及前后端协作,后端处理数据查询、文件生成和解析,前端提供用户交互和文件下载/上传界面。以下是全流程解析,分为导出流程…...
基于Elasticsearch的搜索引擎简介
## 一、Elasticsearch简介 Elasticsearch(简称ES)是一个开源的、分布式、RESTful风格的搜索和数据分析引擎,基于Apache Lucene开发。它能够实现对海量结构化和非结构化数据的实时存储、搜索和分析,广泛应用于全文检索、日志分析、…...
不同类型桥梁的无人机检测内容及技术难度
不同类型桥梁的无人机检测内容及技术难度 无人机桥梁检测的难度因桥梁类型、结构特点和所处环境的不同而存在显著差异。以下是针对梁桥、拱桥、斜拉桥、悬索桥等主要桥梁类型的无人机检测难度分析: 1. 梁桥(简支梁、连续梁) 检测难度&#x…...
数据结构实验10.1:内部排序的基本运算
文章目录 一,实验目的二,实验内容1. 数据生成与初始化2. 排序算法实现(1)直接插入排序(2)二分插入排序(3)希尔排序(4)冒泡排序(5)快速…...
java20
1.List集合 2.数据结构之栈,队列,数组,链表 3.ArrayList集合 4.LinkedList 5.泛型 注意:E...e是指若干个变量...
LLM笔记(九)KV缓存(2)
文章目录 1. 背景与动机2. 不使用 KV Cache 的情形2.1 矩阵形式展开2.2 计算复杂度 3. 使用 KV Cache 的优化3.1 核心思想3.2 矩阵形式展开3.3 计算复杂度对比 4. 总结5. GPT-2 中 KV 缓存的实现分析5.1 缓存的数据结构与类型5.2 在注意力机制 (GPT2Attention) 中使用缓存5.3 缓…...
将 Element UI 表格拖动功能提取为公共方法
为了在多个页面复用表格拖动功能,我们可以将其封装成以下两种形式的公共方法: 方案一:封装为 Vue 指令(推荐) 1. 创建指令文件 src/directives/tableDrag.js import interact from interactjs;export default {inse…...
项目中把webpack 打包改为vite 打包
项目痛点: 老vu e-cli1创建的项目,项目是ERP系统集成了很多很多管理,本地运行调试的时候,每次修改代码都需要等待3分钟左右的编译时间,严重影响开发效率. 解决方案: 采用vite构建项目工程 方案执行 第一步 使用vite脚手架构件一个项目,然后把build文件自定义的编译逻辑般到…...
Vue3 Element Plus 中el-table-column索引使用问题
在 Element Plus 的 el-table 组件中,使用 scope.index 是不准确的。正确的索引属性应该是 scope.$index。你的代码需要调整为: vue 复制 下载 <el-button type"primary" size"default" text click"onModifyClick(scope…...
盲盒一番赏小程序系统发展:创新玩法激发市场活力
盲盒一番赏小程序系统凭借其创新的玩法,在潮玩市场中脱颖而出,激发了市场的无限活力。它不仅保留了传统一番赏百分百中奖的特点,还结合线上平台的优势,开发出了更多新颖的玩法。 例如,小程序系统设置了赏品回收功能。…...
MySQL故障排查
目录 MySQL 单示例故障排查 故障现象一 故障现象二 故障现象三 故障现象四 故障现象五 故障现象六 故障现象七 故障现象八 MySQL主从复制排查 故障现象一 故障现象二 故障现象三 MySQL 优化 硬件方面 关于CPU 关于内存 关于磁盘 MySQL配置文件 核…...
微服务项目->在线oj系统(Java版 - 4)
相信自己,终会成功 目录 B端用户管理 C端用户代码 发送验证码: 验证验证码 退出登录 登录用户信息功能 用户详情与用户编辑 用户竞赛接口 用户报名竞赛 用户竞赛报名接口查询 用户信息列表 ThreadLocalUtil Hutool工具库 常用功能介绍 B端用户管理 进行列表显示与…...
DDoS与CC攻击:谁才是服务器的终极威胁?
在网络安全领域,DDoS(分布式拒绝服务)与CC(Challenge Collapsar)攻击是两种最常见的拒绝服务攻击方式。它们的目标都是通过消耗服务器资源,导致服务不可用,但攻击方式、威胁程度和防御策略存在显…...
旧物回收小程序,一键解决旧物处理难题
在快节奏的现代生活中,我们常常会面临旧物处理的困扰。扔掉觉得可惜,留着又占空间,而且处理起来还十分麻烦。别担心,我们的旧物回收小程序来啦,只需一键,就能轻松解决你的旧物处理难题! 这款小…...
uniapp小程序获取手机设备安全距离
utils.js let systemInfo null;export const getSystemInfo () > {if (!systemInfo) {systemInfo uni.getSystemInfoSync();// 补充安全区域默认值systemInfo.safeAreaInsets systemInfo.safeAreaInsets || {top: 0,bottom: 0,left: 0,right: 0};// 确保statusBarHei…...
小程序弹出层/抽屉封装 (抖音小程序)
最近忙于开发抖音小程序,最想吐槽的就是,既没有适配的UI框架,百度上还找不到关于抖音小程序的案列,我真的很裂开啊,于是我通过大模型封装了一套代码 效果如下 介绍 可以看到 这个弹出层是支持关闭和标题显示的…...
map与set封装
封装map和set一般分为6步: 1.封装map与set 2.普通迭代器 3.const 迭代器 4.insert返回值处理 5.map operator【】 6.key不能修改的问题 一.红黑树的改造 map与set的底层是通过红黑树来封装的,但是map与set的结点储存的值不一样,set只需要存…...