嵌入式软件代码开发或者代码优化的一些方法(持续更新)

发布时间:2026/9/24 23:47:30

嵌入式软件代码开发或者代码优化的一些方法(持续更新)
一、消抖这段代码为例消抖前判断一次消抖后判断一次Delay之后记得重新读取数据。uint8_t servo_change HAL_GPIO_ReadPin(GPIOE,trash_servo); uint8_t trash_change HAL_GPIO_ReadPin(GPIOE,monitor1); while (1) { uint8_t new_servo_state HAL_GPIO_ReadPin(GPIOE,trash_servo); uint8_t new_trash_state HAL_GPIO_ReadPin(GPIOE,monitor1); if(trash_change!new_trash_state) { HAL_Delay(10); new_trash_state HAL_GPIO_ReadPin(GPIOE,monitor1); if(trash_change!new_trash_state) { if(new_trash_stateGPIO_PIN_RESET) //monitor1 catch the sign of full { HAL_GPIO_WritePin(GPIOE,LED_Warning,GPIO_PIN_RESET); //light up the warning LED printf(FULL LED_ON\r\n); } else if(new_trash_stateGPIO_PIN_SET) //normal situation { HAL_GPIO_WritePin(GPIOE,LED_Warning,GPIO_PIN_SET); printf(nomal LED_OFF\r\n); } } trash_changenew_trash_state; } if(servo_change!new_servo_state) { HAL_Delay(50); new_servo_state HAL_GPIO_ReadPin(GPIOE,trash_servo); if(servo_change!new_servo_state) // { if(new_servo_stateGPIO_PIN_RESET) { Servo_Set_angle(angle_left); printf(left!\r\n); HAL_Delay(2000); servo_stop(); } else if(new_servo_stateGPIO_PIN_SET) { Servo_Set_angle(angle_right); printf(right!\r\n); HAL_Delay(2000); servo_stop(); } servo_changenew_servo_state;//״̬ } } }二、初级状态机防止连续转换导致崩溃的技巧也是以上面的代码为例合理利用2个变量来体现状态转换的时机。保证代码不会因为频繁转换状态控制器件反复转换状态导致器件崩溃或者发热损坏。上面的代码就利用 servo_change和new_servo_state 这2个变量来读取舵机状态转换的瞬间只读取状态变化的瞬间而不是一味的识别高电平或者低电平来控制舵机有效防止舵机崩溃。三、状态机初级状态机和状态机的共同点都是读取变化的瞬间而不是读取数据前者更适用于状态只有2种的时候后者适合需要转换多种状态的时候一般是利用枚举还有switch结构组成。枚举用于列举各种状态switch用于读取各种状态下应该完成什么事。例如下面的例子定义一个枚举以及一个枚举类型的变量typedef enum { LED_OFF, // 熄灭 LED_ON, // 常亮 LED_BLINK_SLOW, // 慢闪 LED_BLINK_FAST // 快闪 } LED_State; LED_State current_state LED_OFF;结合switch结构实现按一下转换一次状态的功能while (1) { // 按键检测状态变化才切换 if (key_press_flag) { key_press_flag 0; // 状态切换按一下变一个模式 switch (current_state) { case LED_OFF: current_state LED_ON; break; case LED_ON: current_state LED_BLINK_SLOW; break; case LED_BLINK_SLOW: current_state LED_BLINK_FAST; break; case LED_BLINK_FAST: current_state LED_OFF; break; } } // 根据当前状态做动作 switch (current_state) { case LED_OFF: HAL_GPIO_WritePin(GPIOx, GPIO_PIN_0, GPIO_PIN_RESET); break; case LED_ON: HAL_GPIO_WritePin(GPIOx, GPIO_PIN_0, GPIO_PIN_SET); break; case LED_BLINK_SLOW: HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_0); HAL_Delay(500); break; case LED_BLINK_FAST: HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_0); HAL_Delay(100); break; } }四、阅读数据手册的心得2026.7.11大二小学期期间最近是在搞LVGLCANIAP的那个项目虽然自己手搓出来没看教程但是其实中间不少依赖AI最大的问题就是遇到自己不知道怎么解决的问题时不清楚从什么地方下手最近通过AI帮我排查错误时学到一招就是依靠硬件寄存器说话当然排查代码错误首先还是得从正常的思路去排查比如说我做的仪表盘的项目发现的问题是2个CAN收发器不通讯最好最简单的办法就是切半调试缩小问题的范围找到出问题的地方。大家都经常这么调试但是总会遇到一些奇奇怪怪的问题于是就靠数据手册里的状态寄存器来排查问题了。下面是AI告诉我的排查方法我自己复盘了一下当时我遇到的问题是CAN不通后面AI告诉我让我不要猜哪里出问题先测试c8t6有没有问题让我打开回环模式如果CAN的回环模式能通说明问题不在c8t6的软件代码层面如果CAN的回环模式不通说明大概率是c8t6这边出了问题或者是硬件的问题了。然后就是读取CAN的主状态寄存器了AI加了中间的读取状态寄存器的代码我查了数据手册发现读取的是发送状态寄存器CAN_TSRTXKO0这一位是为了看看邮箱0的数据到底有没有发送出去。还读取了错误状态寄存器ESR的LEC位为的是看看CAN通信过程中到底是哪一步出了问题。终于在这这几行代码的调试帮助下我发现问题了打印的日志显示错误的地方是在CAN 控制器尝试发送隐性位高电平/逻辑1时监控到总线上的电平却是显性低电平/逻辑0。总线上有东西在强行把电平拉低说明总线电气特性异常。然后AI就让我测试回环模式看看是不是CAN控制器的问题结果发现回环模式能正常进行则大概率是CAN收发器的问题了。AI就让我检测引脚有没有接对让我检查供电是不是5V结果最后发现居然是c8t6的板子的CAN收发器供电不足5V导致的一系列问题uint32_t Can_Send_Msg(uint32_t id,uint32_t len,uint8_t *buf) { CAN_TxHeaderTypeDef TxMessage; uint32_t Tx_Mail CAN_TX_MAILBOX0; TxMessage.StdId id; TxMessage.IDECAN_ID_STD; TxMessage.DLClen; TxMessage.RTRCAN_RTR_DATA; if(HAL_OK!HAL_CAN_AddTxMessage(hcan,TxMessage,buf,Tx_Mail)) return 1; printf(Sending\r\n); while(HAL_CAN_GetTxMailboxesFreeLevel(hcan)!3); uint32_t tsr hcan.Instance-TSR; printf(TSR0x%08lX, TXOK0%d\r\n, tsr, (tsr CAN_TSR_TXOK0) ? 1 : 0); uint32_t esr hcan.Instance-ESR; printf(ESR0x%08lX, LEC%d\r\n, esr, (esr 4) 7); printf(Send_OK\r\n); return 0; }以上排查流程都是我从来没想到的其实也是我不太会使用数据手册现在知道数据手册的重要性了到真正的项目开发没有教程给你指导可能出现的错误或者教程压根就不会让你碰这些可能出现的错误我就一直不会想到使用数据手册就会导致我一离开教程或者手把手教学就啥都做不出来。总的来看虽然只是一个小小的供电的问题但是其中的排查过程可谓是十分艰辛这也体现细节的重要性我之前犯过这个错好几次了但是也让我学会很多让我意识到数据手册的重要性。

相关新闻

FreeCAD插件终极指南:打造你的专属3D建模工具箱

FreeCAD插件终极指南:打造你的专属3D建模工具箱

2026/9/5 15:21:01

FreeCAD插件终极指南:打造你的专属3D建模工具箱 【免费下载链接】FreeCAD Official source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler. 项目地址: https://gitcode.com/GitHub_Trending/fr/freecad 想要将FreeCAD从基础建…

服务器双机热备软件推荐

服务器双机热备软件推荐

2026/8/28 19:34:48

在当今的这个年代,信息安全十分重要,今天推荐一款牛逼的服务器双机热备软件PanguHA,它是我目前用过的软件中配置最方便的,界面也是花里胡哨,在多台服务器上部署该款软件可以使多个节点形成一个集群,当某台服…

【Java从入门到入土】52:Java学习路线图:从入门到入土,再到重生

【Java从入门到入土】52:Java学习路线图:从入门到入土,再到重生

2026/8/23 0:30:10

【Java从入门到入土】52:Java学习路线图:从入门到入土,再到重生 Java作为长盛不衰的编程语言,凭借跨平台、高稳定性、丰富的生态体系,仍是后端开发的核心选择。但从“入门敲Hello World”到“架构级工程师”&#xff…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/25 10:06:33

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/25 9:40:47

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/25 10:06:21

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/25 9:53:52

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/25 8:58:17

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/25 10:00:17

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/24 16:02:49

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/25 9:41:47

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/25 4:22:14

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…