试比较GD32E230系列与L233/235芯片在IIC上使用温度传感器SHT40的异同
不说废话,上代码,不同之处直接用宏 展开
1. 首先是i2c 时钟配置 函数有些出入
void sensirion_i2c_attribute_config(){#ifdef GD32E230/* I2C clock configure */i2c_clock_config(I2C1, 100000, I2C_DTCY_2);/* I2C address configure */i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_OWN_ADDRESS7);/* enable I2C1 */i2c_enable(I2C1);/* enable acknowledge */i2c_ack_config(I2C1, I2C_ACK_ENABLE);#endif#ifdef GD32L235/* configure I2C timing */i2c_timing_config(I2C0, 0, 0x3, 0);i2c_master_clock_config(I2C0, 0x13, 0x36);i2c_address_config(I2C0, I2C1_OWN_ADDRESS7, I2C_ADDFORMAT_7BITS);/* configure slave address *///i2c_master_addressing(I2C0, 0x82, I2C_MASTER_TRANSMIT);/* enable I2C0 */i2c_enable(I2C0);#endif
}
2. 然后是 i2c 的读与 写,请看
a. 读
uint8_t sensirion_i2c_ReadByte_timeout(uint8_t Addr,uint8_t *data,uint16_t count){// IMPLEMENT#ifdef GD32E230uint8_t state = I2C_START;uint16_t timeout = 0;uint8_t i2c_timeout_flag = 0;i2c_ackpos_config(I2C1, I2C_ACKPOS_NEXT);while(!(i2c_timeout_flag)){switch (state){case I2C_START:while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_start_on_bus(I2C1);//i2c_starttimeout = 0;state = I2C_SEND_ADDRESS;}else{timeout = 0;state = I2C_START;//PR_DEBUG("i2c bus is busy in byte read \r\n");}break;case I2C_SEND_ADDRESS:/* i2c master sends START signal successfully */while((!i2c_flag_get(I2CX, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_master_addressing(I2CX, (Addr << 1), I2C_RECEIVER);timeout = 0;state = I2C_CLEAR_ADDRESS_FLAG;}else{timeout = 0;state = I2C_START;//add //提前退出循环i2c_timeout_flag = I2C_OK;//PR_DEBUG("i2c master sends start signal timeout in BYTE READ!\n");}break;case I2C_CLEAR_ADDRESS_FLAG:/* address flag set means i2c slave sends ACK */while((!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);timeout = 0;state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;//add //提前退出循环i2c_timeout_flag = I2C_OK;//PR_DEBUG("i2c master clears address flag timeout in BYTE WRITE!\n");}break;case I2C_TRANSMIT_DATA:/* wait until the transmit data buffer is empty */while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}while(count){if(count == 1){i2c_ackpos_config(I2C1, I2C_ACKPOS_CURRENT);i2c_ack_config(I2C1, I2C_ACK_DISABLE);}if(i2c_flag_get(I2C1, I2C_FLAG_RBNE)){*data = i2c_data_receive(I2C1);i2c_ack_config(I2C1, I2C_ACK_ENABLE);data++;count--;}else{state = I2C_START;timeout = 0;}}state = I2C_STOP;timeout = 0;break;case I2C_STOP:/* send a stop condition to I2C bus */i2c_stop_on_bus(I2CX);/* i2c master sends STOP signal successfully */while((I2C_CTL1(I2CX) & 0x0200) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_ackpos_config(I2C1, I2C_ACKPOS_CURRENT);/* enable acknowledge */i2c_ack_config(I2C1, I2C_ACK_ENABLE);timeout = 0;state = I2C_END;i2c_timeout_flag = I2C_OK;}else{timeout = 0;state = I2C_START;//PR_DEBUG("i2c master sends stop signal timeout in BYTE READ\n");}break;default:state = I2C_START;i2c_timeout_flag = I2C_OK;timeout = 0;//PR_DEBUG("i2c master sends start signal in BYTE READ!\n");break;}}#endif#ifdef GD32L235i2c_process_enum state = I2C_START;uint32_t timeout = 0;uint8_t end_flag = 0;//i2c_nack_disable(I2CX);i2c_transfer_byte_number_config(I2CX, count);
#if 1i2c_reload_disable(I2CX);/* enable I2C automatic end mode in master mode */i2c_automatic_end_enable(I2CX);
#endifwhile(!(end_flag)){//printf("i2c bus is busy in read_state:%d,LINE: %d!\r\n",state,__LINE__);switch (state){case I2C_START:/* configure number of bytes to be transferred */while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {timeout++;}if(timeout < I2C_TIME_OUT) {i2c_start_on_bus(I2CX);timeout = 0;state = I2C_SEND_ADDRESS;} else {/* timeout, bus reset *///i2c_bus_reset();timeout = 0;state = I2C_START;end_flag = I2C_OK;printf("i2c bus is busy in read_%d!\r\n",__LINE__);}break;case I2C_SEND_ADDRESS:while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {timeout++;}if(timeout < I2C_TIME_OUT) {i2c_master_addressing(I2CX, (Addr<<1), I2C_MASTER_RECEIVE);state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;end_flag = I2C_OK;printf("i2c bus is I2C_SEND_ADDRESS timeout:%d!\r\n",__LINE__);}break;case I2C_TRANSMIT_DATA:while(count){if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)){*data = i2c_data_receive(I2CX);data++;count--;}}state = I2C_STOP;timeout = 0;//printf("i2c transmit complete %d \r\n",i2c_flag_get(I2CX, I2C_FLAG_RBNE));break;case I2C_STOP:/* wait until the stop condition is finished */while((!i2c_flag_get(I2CX, I2C_FLAG_STPDET)) && (timeout < I2C_TIME_OUT)) {timeout++;}if(timeout < I2C_TIME_OUT) {/* clear STPDET flag */i2c_flag_clear(I2CX, I2C_FLAG_STPDET);timeout = 0;state = I2C_END;end_flag = I2C_OK;} else {timeout = 0;state = I2C_START;//printf("i2c master sends stop signal timeout in read!\n");}break;default:/* default status */state = I2C_START;end_flag = 1;timeout = 0;printf("i2c master sends start signal in read!\n");break;}}#endifreturn state;
}
b. 写
uint8_t sensirion_i2c_WriteByte_timeout(uint8_t Addr,const uint8_t *data,uint16_t count){#ifdef GD32E230uint8_t state = I2C_START;uint16_t timeout = 0;uint8_t i2c_timeout_flag = 0;while(!(i2c_timeout_flag)){switch (state){case I2C_START:while(i2c_flag_get(I2C1, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_start_on_bus(I2C1);//i2c_starttimeout = 0;state = I2C_SEND_ADDRESS;}else{timeout = 0;state = I2C_START;i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c bus is busy in byte write \r\n",SENSIR_STR);}break;case I2C_SEND_ADDRESS:/* i2c master sends START signal successfully */while((!i2c_flag_get(I2CX, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_master_addressing(I2CX, (Addr << 1), I2C_TRANSMITTER);timeout = 0;state = I2C_CLEAR_ADDRESS_FLAG;}else{timeout = 0;state = I2C_START;i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c master sends start signal timeout in BYTE WRITE!\r\n",SENSIR_STR);}break;case I2C_CLEAR_ADDRESS_FLAG:/* address flag set means i2c slave sends ACK */while((!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);timeout = 0;state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;//add 提前退出循环i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c master clears address flag timeout in BYTE WRITE!\r\n",SENSIR_STR);}break;case I2C_TRANSMIT_DATA:/* wait until the transmit data buffer is empty */while((!i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}while(count){i2c_data_transmit(I2CX, *data);data++;count--;while((!i2c_flag_get(I2CX, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;}else{timeout = 0;state = I2C_START;i2c_timeout_flag = I2C_OK;//PR_ERR("%s,i2c master sends data timeout in PAGE WRITE!\n",SENSIR_STR);break;}}state = I2C_STOP;timeout = 0;break;case I2C_STOP:/* send a stop condition to I2C bus */i2c_stop_on_bus(I2CX);/* i2c master sends STOP signal successfully */while((I2C_CTL1(I2CX) & 0x0200) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;state = I2C_END;i2c_timeout_flag = I2C_OK;}else{timeout = 0;state = I2C_START;//PR_ERR("%s,i2c master sends stop signal timeout in BYTE WRITE\r\n",SENSIR_STR);}break;default:state = I2C_START;i2c_timeout_flag = I2C_OK;timeout = 0;//PR_DEBUG("%s,i2c master sends start signal in BYTE WRITE!\r\n",SENSIR_STR);break;}}#endif#ifdef GD32L235i2c_process_enum state = I2C_START;uint16_t timeout = 0;uint8_t end_flag = 0;i2c_transfer_byte_number_config(I2C0, 16);//printf("i2c_master_addressing:0x%x\r\n",Addr<<1);while(!(end_flag)){//printf("IIC writeByte,state: %d\r\n",state);switch(state){case I2C_START:while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){i2c_start_on_bus(I2C0);timeout = 0;state = I2C_SEND_ADDRESS;}else{timeout = 0;state = I2C_START;end_flag = I2C_OK;//printf("i2c bus is busy in writeByte! %d\r\n",__LINE__);}break;case I2C_SEND_ADDRESS:while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;i2c_master_addressing(I2C0, Addr<<1, I2C_MASTER_TRANSMIT);state = I2C_TRANSMIT_DATA;}else{timeout = 0;state = I2C_START;//printf("i2c master sends 's internal address timeout in writeByte!\r\n");}break;case I2C_TRANSMIT_DATA:while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;i2c_data_transmit(I2C0, *data);state = I2C_STOP;}else{timeout = 0;state = I2C_START;//printf("i2c master sends data timeout in writeByte! \r\n");}//printf("i2c_step2 NCK:%d! \r\n",i2c_flag_get(I2C0, I2C_FLAG_NACK));break;case I2C_STOP:/* send a stop condition to I2C bus */i2c_stop_on_bus(I2C0);/* i2c master sends STOP signal successfully */while(!i2c_flag_get(I2C0, I2C_FLAG_STPDET) && (timeout < I2C_TIME_OUT)){timeout++;}if(timeout < I2C_TIME_OUT){timeout = 0;state = I2C_END;end_flag = I2C_OK;/* clear the STPDET bit */i2c_flag_clear(I2C0, I2C_FLAG_STPDET);}else{timeout = 0;state = I2C_START;printf("i2c master sends stop signal timeout in writeByte!\r\n");}break;default:state = I2C_START;end_flag = I2C_OK;timeout = 0;printf("i2c master sends start signal in WRITE!\r\n");break;}}#endifreturn state;
}
因为 两套api 接口不一致,所以还是有较大出入的。希望 在用这款单片机的兄弟闷,少走弯路,我这已经调好,拿走不谢!
相关文章:
试比较GD32E230系列与L233/235芯片在IIC上使用温度传感器SHT40的异同
不说废话,上代码,不同之处直接用宏 展开 1. 首先是i2c 时钟配置 函数有些出入 void sensirion_i2c_attribute_config(){#ifdef GD32E230/* I2C clock configure */i2c_clock_config(I2C1, 100000, I2C_DTCY_2);/* I2C address configure */i2c_mode_a…...
超强算力 Orange Pi Kunpeng Pro 开发板基础测评与体验
目录 开箱体验资源简介系统启动连接网络登录系统通过桌面登录通过串口登录通过 SSH 登录配置散热风扇 算力测试MNIST示例MBNET示例 体验总结 大家好,我是 Hello 阿尔法,有幸接到 CSDN 的邀请参与 Orange Pi Kunpeng Pro 开发板的测评活动,本文…...
vs - ms官方查看pdb文件内容的例子工程
文章目录 vs - ms官方查看pdb文件内容的例子工程概述笔记END vs - ms官方查看pdb文件内容的例子工程 概述 不管哪个版本的VS,生成debug版工程时,除了工程自己的.pdb还会有vc*.pdb. e.g. vc.pdb, vc70.pdb, vc90.pdb, vc120.pdb, vc140.pdb, vc142.pdb,…...
【excel】设置二级可变联动菜单
文章目录 【需求】在一级菜单选定后,二级菜单联动显示一级菜单下的可选项【步骤】step1 制作辅助列1.列转行2.在辅助列中匹配班级成员 step2 名称管理器step3 制作二级下拉菜单step4 消除二级菜单中的空白 【总结】 之前做完了 【excel】设置可变下拉菜单ÿ…...
8月1-3日西安国际储能产业博览会
同期举办:2024西部国际氢能源及燃料电池产业博览会 2024年12月5-7日 西安国际会展中心 一、展会概况: 在能源转型和“双碳”目标的推动下,风电、太阳能、氢能等能源产业得到快速的发展,新型储能日益成为我国建设新型能源体…...
MySQL事务处理:ACID属性基础与实现概览
前言 本文核心思想就是介绍一下 Mysql ACID 的实现,至于事务、锁、redo 的底层结构及实现原理,后面会单独出文章介绍。之所以这样是不希望一篇文章过长,在闲暇时间就可轻易掌握一个知识点。 ACID 介绍 ACID 是数据库管理系统&#x…...
PostgreSQL 修改表结构卡住不动
目录 1 问题2 实现 1 问题 今天遇到的一个问题记录一下,因为系统上的一个改动需要同步脚本至测试库上,具体的脚本内容也很简单,就是修改了某张表的一个字段。但是无论怎么操作都是一直卡住,表的数据量很小就十几条数据所以初步怀疑是表被锁了…...
wvp-gb28181-pro搭建流媒体服务器,内存占用过高问题
直接给出解决办法,端口暴露的太多了,暴露了500个端口导致从3g---->11g 遇到的问题,直接使用镜像《648540858/wvp_pro:latest》在宿主机上运行,如我下面的博客 https://blog.csdn.net/weixin_41012767/article/details/137112338?spm=1001.2014.3001.5502 docker run …...
项目-双人五子棋对战: websocket的讲解与使用 (1)
项目介绍 接下来, 我们将制作一个关于双人五子棋的项目, 话不多说先来理清一下需求. 1.用户模块 用户的注册和登录 管理用户的天梯分数, 比赛场数, 获胜场数等信息. 2.匹配模块 依据用户的天梯积分, 实现匹配机制. 3.对战模块 把两个匹配到的玩家放到同一个游戏房间中, 双方通…...
性能飙升50%,react-virtualized-list如何优化大数据集滚动渲染
在处理大规模数据集渲染时,前端性能常常面临巨大的挑战。本文将探讨 react-virtualized-list 库如何通过虚拟化技术和 Intersection Observer API,实现前端渲染性能飙升 50% 的突破!除此之外,我们一同探究下该库还支持哪些新的特性…...
颠覆传统:探索Web3对传统计算机模式的冲击
随着Web3技术的崛起,传统计算机模式正面临着前所未有的冲击与挑战。Web3作为下一代互联网的代表,以其去中心化、安全可信的特性,正在颠覆着传统计算机模式的种种假设和局限性。本文将深入探讨Web3对传统计算机模式的冲击,并探索其…...
最适合上班族和宝妈的兼职副业,一天500多,小众副业项目
近年来,地方特色小吃逐渐受到人们的热烈追捧,尤其是在直播的助力下,许多地方的特色小吃得以走进大众视野,吸引了大量流量和人气。因此,有很大一部分商家和创业者看准了这一商机,纷纷投身于地方特色小吃的制…...
HFish蜜罐实践:网络安全防御的主动出击
引言 随着网络攻击手段的不断演进,传统的被动防御策略已难以应对复杂多变的安全威胁。HFish蜜罐作为一种主动防御工具,通过模拟易受攻击的服务,吸引攻击者,不仅能有效捕获攻击行为,还能为安全分析和溯源提供宝贵信息。…...
vue3+three.js给glb模型设置视频贴图
1.在网上下载一个显示屏或者自己画一个,在blender中设置好显示屏的Mesh,UV设置好,这样方便代码中添加纹理贴图。可以让美术在建模软件中,先随机设置一张图片作为纹理,验证UV是否设置好 关于如何 在blender中给模型设置UV贴图百度很多的 // 视频 import * as THREE from…...
SCARA机器人中旋转花键的维护和保养方法!
作为精密传动元件的一种,旋转花键在工作过程中承受了较大的负荷。在自动化设备上运用广泛,如:水平多关节机械手臂(SCARA)、产业用机器人、自动装载机、雷射加工机、搬运装置、机械加工中心的ATC装置等,最适…...
Linux运维-服务器系统配置初始化脚本
方案一 ,是一个简化的Linux服务器初始化脚本 下面这个是一个简化的Linux服务器初始化脚本示例,它包括了更新软件包、安装常用工具、配置网络和安全设置等基本步骤:这个脚本提供了一个基本的初始化配置示例,包括软件更新、安装工具…...
暑期来临,AI智能视频分析方案筑牢防溺水安全屏障
随着夏季暑期的来临,未成年人溺水事故频发。传统的防溺水方式往往依赖于人工巡逻和警示标识的设置,但这种方式存在人力不足、反应速度慢等局限性。近年来,随着视频监控智能分析技术的不断发展,其在夏季防溺水中的应用也日益凸显出…...
【第3章】SpringBoot实战篇之登录接口(含JWT和拦截器)
文章目录 前言一、JWT1. 什么是JWT2. 使用场景3. 结构3.1 Header3.2 Payload3.3 Signature 4. 使用 二、案例1.引入库2.JwtUtils3. UserController14. ArticleController 三、拦截器1. 定义拦截器2. 注册拦截器 四、测试1. 登录2. 无token3. 有token4. 全局配置 总结 前言 前面…...
vue el-table使用、el-popover关闭、el-image大图预览
1、html <el-table :data"list" :header-cell-style"{ background: #F7F8F9 }"><el-table-column type"index" width"100px" label"序号"></el-table-column><el-table-column prop"pic" l…...
星网智云总经理韦炜:低代码与智能制造融合,探索未来制造的无限可能
下文为广西星网智云总经理韦炜的演讲全文: 大家下午好,今天给大家分享一下玉柴的数字化转型过程,以及整个过程中我们会怎样使用低代码。 ﹀ ﹀ ﹀ #玉柴数字化战略 #两个要点 我们的数字化,是在公司的整一个战略转型下去做的。…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
