当前位置: 首页 > article >正文

告别混乱的全局变量:在TC264上用状态机重构你的多级菜单(按键+IPS200屏)

告别混乱的全局变量在TC264上用状态机重构多级菜单系统当你在TC264芯片上开发一个带IPS200屏幕的多级菜单时是否遇到过这样的困境随着功能不断增加代码里到处是flag_menu、gb_flag这样的全局变量if-else嵌套越来越深每次修改都要小心翼翼生怕影响其他功能我曾接手过一个类似项目光是理清各种标志位的逻辑关系就花了两天时间。直到引入状态机设计模式才彻底解决了这个痛点。1. 为什么全局变量会成为嵌入式菜单的噩梦在嵌入式系统中菜单逻辑本质上是一系列状态和状态转换的集合。传统实现方式通常依赖全局变量和条件判断比如原文中的flag_main、flag_menu等。这种写法在简单场景下尚可应付但随着复杂度提升会暴露出几个致命问题可读性差十几个全局变量交叉影响很难一眼看出某个变量的修改会影响哪些功能维护困难添加新菜单时需要手动维护各种标志位容易遗漏边界条件扩展性弱菜单层级和交互逻辑的变化往往需要重构大量代码调试痛苦状态异常时难以追踪是哪个环节的标志位设置出错// 典型的问题代码片段 if (flag_main 1 flag_menu 0) { // 主菜单逻辑 } else if (modify_zhili_flag) { // 参数修改逻辑 } else if (...) { // 更多条件嵌套 }状态机State Machine为解决这些问题提供了优雅的方案。它将菜单系统抽象为有限的状态集合如主菜单、子菜单、参数编辑等明确的事件触发按键输入、超时等确定的状态转移规则2. 状态机基础与菜单建模2.1 状态机核心概念状态机由三个基本要素构成要素说明菜单系统示例状态(State)系统所处的稳定状态主菜单、功能子菜单、参数编辑模式事件(Event)触发状态转换的外部输入按键按下、定时器超时转移(Transition)状态变化的规则和对应的动作按下OK键从主菜单进入选中的子菜单2.2 菜单状态机设计针对TC264IPS200的硬件组合我们可以这样建模菜单状态机stateDiagram-v2 [*] -- 主菜单 主菜单 -- 功能子菜单: 选择FunctionOK 主菜单 -- IMU子菜单: 选择Imu660raOK 功能子菜单 -- 主菜单: 按下返回键 IMU子菜单 -- 参数编辑: 选择参数项OK 参数编辑 -- IMU子菜单: 再次按下OK对应的状态枚举可以定义为typedef enum { STATE_MAIN_MENU, STATE_FUNC_SUBMENU, STATE_IMU_SUBMENU, STATE_PARAM_EDIT, // 其他状态... } MenuState;3. 状态机实现方案对比3.1 三种实现方式对比在嵌入式环境中状态机有几种典型实现方式实现方式优点缺点适用场景switch-case简单直接资源占用低状态多时代码冗长简单菜单(5个状态)状态表扩展性强逻辑清晰需要额外存储空间复杂菜单系统面向对象封装性好易于维护嵌入式C支持有限开销较大有C支持的平台考虑到TC264的资源限制和开发习惯推荐使用状态表事件处理器的混合方案。3.2 状态表实现示例首先定义状态转移表typedef struct { MenuState currentState; EventType event; void (*action)(void); MenuState nextState; } StateTransition; const StateTransition transitionTable[] { {STATE_MAIN_MENU, EVENT_OK, enterSubmenu, STATE_FUNC_SUBMENU}, {STATE_FUNC_SUBMENU, EVENT_BACK, returnToMain, STATE_MAIN_MENU}, {STATE_IMU_SUBMENU, EVENT_OK, startEditParam, STATE_PARAM_EDIT}, // 其他转移规则... };然后实现事件处理循环void handleEvent(EventType event) { for (int i 0; i TRANSITION_COUNT; i) { if (transitionTable[i].currentState currentState transitionTable[i].event event) { if (transitionTable[i].action) { transitionTable[i].action(); } currentState transitionTable[i].nextState; break; } } }4. TC264上的具体实现技巧4.1 按键事件处理在TC264上我们需要将物理按键映射为状态机事件typedef enum { EVENT_NONE, EVENT_OK, // KEY2 EVENT_BACK, // KEY3 EVENT_UP, // KEY1 EVENT_DOWN, // KEY4 // 其他事件... } EventType; EventType getKeyEvent() { if (!gpio_get_level(KEY2)) return EVENT_OK; if (!gpio_get_level(KEY3)) return EVENT_BACK; // 其他按键检测... }4.2 屏幕刷新优化IPS200屏幕的刷新需要考虑性能问题。建议采用差异刷新策略void refreshScreen() { static MenuState lastState STATE_INIT; if (lastState ! currentState) { // 状态变化时全屏刷新 ips200_clear(); drawFullMenu(); lastState currentState; } else { // 仅刷新变化部分如参数值 updateChangedParams(); } }4.3 参数编辑处理参数编辑状态需要特殊处理用户输入void handleParamEdit(EventType event) { switch(event) { case EVENT_UP: currentParam stepSize; flash_param(currentParam); // 保存到Flash break; case EVENT_DOWN: currentParam - stepSize; flash_param(currentParam); break; case EVENT_OK: transitionTo(STATE_IMU_SUBMENU); break; // 其他事件... } }5. 状态机带来的扩展优势采用状态机架构后系统获得了几个意想不到的扩展能力菜单历史堆栈自动记录导航路径实现返回上一级功能void pushState(MenuState state) { stateStack[stackTop] state; } MenuState popState() { return stateStack[--stackTop]; }超时自动返回利用定时器实现无操作时自动返回主菜单void checkTimeout() { if (idleTimer TIMEOUT_THRESHOLD) { transitionTo(STATE_MAIN_MENU); } }菜单配置化将菜单结构存储在外部Flash或EEPROM中实现动态配置6. 性能优化与调试技巧在资源受限的TC264上实现状态机需要注意状态表存储优化// 使用PROGMEM存储常量状态表 const StateTransition transitionTable[] PROGMEM {...};调试日志输出void logStateChange(MenuState old, MenuState new) { printf([State] %s - %s\n, stateName(old), stateName(new)); }内存占用监控# 编译时查看内存占用 arm-none-eabi-size firmware.elf实际项目中状态机实现后代码量比原始方案减少了约30%而可维护性大幅提升。添加新菜单项的时间从原来的2小时缩短到20分钟且再未出现过因标志位冲突导致的异常。

相关文章:

告别混乱的全局变量:在TC264上用状态机重构你的多级菜单(按键+IPS200屏)

告别混乱的全局变量:在TC264上用状态机重构多级菜单系统 当你在TC264芯片上开发一个带IPS200屏幕的多级菜单时,是否遇到过这样的困境:随着功能不断增加,代码里到处是flag_menu、gb_flag这样的全局变量,if-else嵌套越来…...

逐步指导在OpenClaw工具中配置Taotoken作为大模型供应商

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 逐步指导在OpenClaw工具中配置Taotoken作为大模型供应商 对于使用OpenClaw构建智能体工作流的开发者而言,能够灵活接入…...

ViGEmBus完全指南:Windows游戏控制器模拟的终极解决方案

ViGEmBus完全指南:Windows游戏控制器模拟的终极解决方案 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否曾经遇到过这样的困扰&#xff1f…...

从亿航EH216-S取证看载人无人机适航:一份给硬件工程师的避坑指南

亿航EH216-S适航取证背后的硬件工程实战:关键挑战与设计启示 当全球首款载人无人机EH216-S的型号合格证(TC)颁发时,整个航空工业的目光都聚焦在了这个不足600公斤的飞行器上。作为硬件工程师,我们看到的不仅是里程碑式…...

LabVIEW与Xplane飞行界面数据仿真交互

在做飞行仿真时候,有一点是使用视景仿真。也就是通过屏幕,显示飞机的姿态,经纬度等信息。一般的,做飞行仿真,如果自己使用Unity3D或者UnReal的虚拟引擎来做,比较费时间,需要对机场环境建模。 而…...

AI与韦伯理性化:构建税收政策智能模拟器的工程实践

1. 项目概述:当AI遇见税收政策最近几年,我身边不少在公共部门做政策研究的朋友,都开始频繁地讨论一个词:AI。从最初的数据报表自动化,到后来的风险模型预测,再到如今开始尝试介入政策制定的核心环节。这背后…...

AI编程实测:ChatGPT在专业OJ平台Kattis的解题能力与局限分析

1. 项目概述:当AI解题者遇上专业OJ 最近,我花了整整一周时间,做了一件在程序员圈子里可能有点“无聊”但又极具探索价值的事情:系统性地测试了以ChatGPT为代表的大语言模型,在专业在线判题系统(Online Judg…...

AI-XR元宇宙隐私保护:同态加密与联邦学习实战解析

1. 项目概述:当AI-XR元宇宙撞上隐私保护,我们该何去何从?最近几年,元宇宙(Metaverse)的概念火得一塌糊涂,从科技巨头到创业公司,都铆足了劲想在这个被认为是下一代互联网的虚拟世界里…...

终极指南:Handlebars.js如何快速解析模板字符串的核心原理

终极指南:Handlebars.js如何快速解析模板字符串的核心原理 【免费下载链接】handlebars.js Minimal templating on steroids. 项目地址: https://gitcode.com/gh_mirrors/ha/handlebars.js Handlebars.js作为一款高效的模板引擎,以其"Minima…...

TensorFlow优化器完全指南:Adam、SGD、RMSprop算法性能深度对比与实战选择

TensorFlow优化器完全指南:Adam、SGD、RMSprop算法性能深度对比与实战选择 【免费下载链接】TensorFlow-Course :satellite: Simple and ready-to-use tutorials for TensorFlow 项目地址: https://gitcode.com/gh_mirrors/te/TensorFlow-Course TensorFlow…...

昇腾SHMEM故障排除指南

SHMEM 使用限制 【免费下载链接】shmem CANN SHMEM 是面向昇腾平台的多机多卡内存通信库,基于OpenSHMEM 标准协议,实现跨设备的高效内存访问与数据同步。 项目地址: https://gitcode.com/cann/shmem GM2GM的highlevel RMA操作使用默认buffer&…...

ChatPaper离线模型支持终极指南:如何用本地部署开源LLM实现完全隐私保护论文总结

ChatPaper离线模型支持终极指南:如何用本地部署开源LLM实现完全隐私保护论文总结 【免费下载链接】ChatPaper Use ChatGPT to summarize the arXiv papers. 全流程加速科研,利用chatgpt进行论文全文总结专业翻译润色审稿审稿回复 项目地址: https://gi…...

可解释AI如何重塑医学系统综述:从黑箱到透明决策的实践

1. 项目概述:当AI的“黑箱”遇上严谨的医学证据如果你做过系统文献综述,尤其是医学领域的,你肯定知道那是个什么滋味。那是一个体力、脑力和意志力的三重考验:从海量数据库中检索成千上万的文献,然后像淘金一样&#x…...

Python整数有上限吗?揭秘动态大整数的原理与工程边界

1. 这个问题比你想象的更根本:Python整数到底有没有“最大值”?很多人第一次听说“Python最大整数”时,下意识会去查sys.maxint或sys.maxsize,然后发现结果要么报错,要么是个看起来很奇怪的数字(比如 92233…...

GRU与注意力机制在ICU多重耐药菌感染预测中的实战应用

1. 项目概述:当重症监护室遇上AI预测 在重症监护室(ICU)里,时间是以分钟甚至秒来计算的。医生们面对的不仅是复杂的病情,还有像“多重耐药菌感染”这样的隐形杀手。这类感染一旦发生,意味着常规抗生素基本失…...

#86_【无标题】每次 .h 被 #include,就等于在所有包含它的 .c 文件中都复制了一份定义。

我在.h中定义了/CN:数码管段码表 (扫描引脚复用型)-- EN:Digital Tube Segment Code Table (Scan Pin Multiplexing Type)/ const uint8_t NUM_TAB[10] {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; 但是这个时候突然间报错了所以感觉有意思 错误原因 Err…...

CANN/catlass分组矩阵乘反量化示例

GroupedMatmulSliceMPerTensorPerChannelDequant Example Readme 【免费下载链接】catlass 本项目是CANN的算子模板库,提供NPU上高性能矩阵乘及其相关融合类算子模板样例。 项目地址: https://gitcode.com/cann/catlass 代码组织 ├── 48_ascend950_group…...

#85_库函数开发

前言 在很久很久很久以前 C 语言和 STM32 走在一条幽静的道路上 他们在一起过上了幸福的生活 一、 问题引入… 1 二、 寄存器的基础概念… 1 三、 STM32 寄存器实例解析… 3 GPIO 输入/输出 → 对应 GPIOx_CRL / GPIOx_CRH / GPIOx_IDR /… 3定时器(Timer&#xff…...

5个简单步骤:OpenCore Legacy Patcher终极指南让老旧Mac焕发新生

5个简单步骤:OpenCore Legacy Patcher终极指南让老旧Mac焕发新生 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否还在为老旧的Mac无法升级到…...

Lobu多租户AI助手网关:安全隔离与规模化部署实践

1. 项目概述:构建企业级多租户AI助手网关 最近在折腾一个挺有意思的开源项目,叫Lobu。简单来说,它解决了一个很实际的问题:如何安全、高效地在一个组织内部署和管理多个独立的AI助手(Agent)。想象一下&…...

Koel下载功能终极指南:批量下载与压缩包生成的完整教程

Koel下载功能终极指南:批量下载与压缩包生成的完整教程 【免费下载链接】koel Music streaming solution that works. 项目地址: https://gitcode.com/gh_mirrors/ko/koel Koel作为一款优秀的个人音乐流媒体解决方案,其强大的下载功能让用户可以轻…...

如何快速掌握加密算法基础:面向初学者的完整指南

如何快速掌握加密算法基础:面向初学者的完整指南 【免费下载链接】Algorithms A collection of algorithms and data structures 项目地址: https://gitcode.com/gh_mirrors/algorithms39/Algorithms 想要快速掌握加密算法基础吗?加密算法是现代计…...

基于MPA的微前端架构:实现技术栈无关与独立部署的现代Web应用方案

1. 项目概述:一个为现代Web应用量身定制的微前端架构如果你正在为一个大型、多团队协作的Web应用寻找一个既能保持技术栈灵活性,又能实现高效集成与独立部署的解决方案,那么mattmezza/mpa这个项目绝对值得你花时间深入研究。它不是一个简单的…...

为什么你需要HolyTips:7个让漏洞赏金狩猎更高效的实用技巧

为什么你需要HolyTips:7个让漏洞赏金狩猎更高效的实用技巧 【免费下载链接】HolyTips A Collection of Notes, Checklists, Writeups on Bug Bounty Hunting and Web Application Security. 项目地址: https://gitcode.com/gh_mirrors/ho/HolyTips 在网络安全…...

深度学习在人工耳蜗中的应用:从语音增强到医学影像分析

1. 项目概述:当深度学习“听见”声音作为一名长期在医疗科技与信号处理交叉领域摸爬滚打的从业者,我见证过太多技术从实验室走向临床的艰难旅程。其中,“深度学习在人工耳蜗应用中的进展”这个话题,尤其让我感到兴奋。它远不止是一…...

CANN基础设施漏洞管理指南

cve-manager(漏洞管理)使用说明 【免费下载链接】infrastructure 本仓库用于托管CANN社区基础设施团队的公开信息,包括不限于:会议日程,成员信息,服务文档和配置等信息 项目地址: https://gitcode.com/ca…...

JAVA基础教学计划【欢迎指点】

学习JAVA,首先要了解Java语言的第一个特性——面向对象。编程语言就像我们现实生活中面对种种情景是一样的,可以说这是属于计算机的世界,我们人来到计算机世界自然要熟悉这个世界构成方式。在现实中,我们认识一件事物,…...

收藏!2026年普通人也能干的5个高薪AI新职业(无需代码,小白也能学)

文章介绍了5个无需编程技能的AI相关职业:AI训练师、AI内容运营、提示词工程师、AI数据标注员和AI销售顾问。这些职业为没有高学历或技术背景的人提供了进入AI行业的机会,强调了学习AI工具和技能的重要性,鼓励人们抓住AI时代的机遇。 2026年&a…...

CANN/ge添加输出API

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

AI赋能边缘计算安全:从联邦学习到异常检测的实战指南

1. 项目概述:当边缘计算遇上AI,安全与隐私的十字路口最近几年,我身边做物联网、车联网和工业互联网项目的朋友,聊得最多的两个词,一个是“边缘计算”,另一个就是“AI”。把AI模型部署到摄像头、网关、工控机…...