单片机裸机编程:状态机与其他高效编程框架
在单片机裸机编程中,状态机是一种非常强大的工具,能够有效管理复杂的逻辑和任务切换。除了状态机,还有其他几种编程模式可以在不使用 RTOS 的情况下实现高效的程序设计。以下是一些常见的方法:
1. 状态机编程
状态机通过定义系统的不同状态和状态之间的转换规则,将复杂的逻辑分解为简单的状态和事件处理。它适用于事件驱动的系统,能够有效管理任务切换和逻辑复杂性。
实现思路:
-
定义状态枚举类型。
-
使用状态变量记录当前状态。
-
在主循环中根据当前状态执行对应的任务。
-
根据事件或条件触发状态转换。
示例代码:
typedef enum {STATE_IDLE,STATE_PROCESS_SENSOR,STATE_HANDLE_BUTTON,STATE_UPDATE_DISPLAY
} StateTypeDef;StateTypeDef currentState = STATE_IDLE;void process_sensor_data(void) {// 处理传感器数据
}void handle_button_press(void) {// 处理按钮事件
}void update_display(void) {// 更新显示
}void main(void) {while (1) {switch (currentState) {case STATE_IDLE:if (sensor_data_ready) {currentState = STATE_PROCESS_SENSOR;} else if (button_pressed) {currentState = STATE_HANDLE_BUTTON;}break;case STATE_PROCESS_SENSOR:process_sensor_data();currentState = STATE_IDLE;break;case STATE_HANDLE_BUTTON:handle_button_press();currentState = STATE_IDLE;break;case STATE_UPDATE_DISPLAY:update_display();currentState = STATE_IDLE;break;}}
}
2. 时间片轮询(Super Loop + 定时器)
时间片轮询是一种模拟多任务调度的方法,通过定时器中断实现时间片的管理。每个任务被分配一个固定的时间片,在主循环中依次执行各个任务的一部分。当时间片用完时,切换到下一个任务。
实现思路:
-
设置一个定时器中断,用于记录时间片的结束。
-
在主循环中,根据时间片的计数器决定当前任务是否继续执行。
示例代码:
#define TASK_COUNT 3
#define TIME_QUANTUM 10 // 时间片大小,单位为毫秒typedef struct {void (*taskFunc)(void); // 任务函数指针int remainingTime; // 剩余时间片
} TaskTypeDef;TaskTypeDef tasks[TASK_COUNT] = {{task1, TIME_QUANTUM},{task2, TIME_QUANTUM},{task3, TIME_QUANTUM}
};void task1(void) {// 执行任务1
}void task2(void) {// 执行任务2
}void task3(void) {// 执行任务3
}void main(void) {int currentTask = 0;while (1) {if (tasks[currentTask].remainingTime > 0) {tasks[currentTask].taskFunc(); // 执行当前任务tasks[currentTask].remainingTime--;}currentTask = (currentTask + 1) % TASK_COUNT; // 轮询下一个任务}
}
3. 中断驱动编程
中断驱动是一种利用单片机中断机制来处理事件的方法。通过配置中断源(如 GPIO、定时器、串口等),可以在事件发生时直接跳转到中断服务例程(ISR),从而实现快速响应。
实现思路:
-
配置中断源,设置中断优先级。
-
在中断服务例程中处理事件,避免在 ISR 中执行耗时操作。
示例代码:
void EXTI0_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line0) != RESET) {// 处理按键中断事件EXTI_ClearITPendingBit(EXTI_Line0);handle_button_press();}
}void handle_button_press(void) {// 按键处理逻辑
}void main(void) {// 初始化中断NVIC_EnableIRQ(EXTI0_IRQn);while (1) {// 主循环可以执行其他任务}
}
4. 非阻塞式编程
非阻塞式编程通过轮询或定时器检测事件状态,而不是在事件未发生时阻塞程序。这种方式可以提高程序的响应速度,避免因等待某个事件而导致程序卡顿。
实现思路:
-
使用定时器或计数器检测事件状态。
-
在主循环中不断检查事件是否发生,并根据状态执行相应操作。
示例代码:
#include "bsp_dwt.h" // 假设使用硬件定时器库#define TIMEOUT 100000 // 超时时间,单位为微秒void handle_button_press(void) {// 按键处理逻辑
}void handle_timeout(void) {// 超时处理逻辑
}void main(void) {uint32_t start_time = DWT_GetTimeline_us(); // 获取当前时间while (1) {if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == SET) {// 按键按下,执行任务handle_button_press();start_time = DWT_GetTimeline_us(); // 重置计时器}if (DWT_GetTimeline_us() - start_time > TIMEOUT) {// 超时处理handle_timeout();start_time = DWT_GetTimeline_us(); // 重置计时器}}
}
5. 超级循环(Super Loop)
超级循环是一种简单的多任务实现方式,通过在一个大循环中轮流执行不同的任务。每个任务函数执行一个任务的一部分,然后将控制权交给下一个任务。
实现思路:
-
在主循环中按顺序调用各个任务函数。
-
可以通过条件语句或计数器控制任务的执行频率。
示例代码:
void task1(void) {// 执行任务1
}void task2(void) {// 执行任务2
}void main(void) {while (1) {task1();task2();}
}
总结
在单片机裸机编程中,状态机、时间片轮询、中断驱动、非阻塞式编程和超级循环都是常见的编程模式。它们各有优缺点,适用于不同的场景:
-
状态机:适用于复杂逻辑和事件驱动的系统,能够有效管理任务切换和逻辑复杂性。
-
时间片轮询:适合多任务并发但对实时性要求不高的场景。
-
中断驱动:适合对实时性要求较高的系统。
-
非阻塞式编程:适合需要快速响应多个事件的系统。
-
超级循环:适合简单的多任务场景。
相关文章:
单片机裸机编程:状态机与其他高效编程框架
在单片机裸机编程中,状态机是一种非常强大的工具,能够有效管理复杂的逻辑和任务切换。除了状态机,还有其他几种编程模式可以在不使用 RTOS 的情况下实现高效的程序设计。以下是一些常见的方法: 1. 状态机编程 状态机通过定义系统…...
图表控件Aspose.Diagram入门教程:使用 Python 将 VSDX 转换为 PDF
将VSDX转换为PDF可让用户轻松共享图表。PDF 文件保留原始文档的布局和设计。它们广泛用于演示文稿、报告和文档。在这篇博文中,我们将探讨如何在 Python 中将 VSDX 转换为 PDF。 本文涵盖以下主题: Python VSDX 到 PDF 转换器库使用 Python 将 VSDX 转…...
DPVS-1:编译安装DPVS (ubuntu22.04)
操作系统 rootubuntu22:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy rootubuntu22:~# 前置软件准备 apt install git apt install meson apt install gcc ap…...
即将发布书籍 - Yocto项目实战教程:高效定制嵌入式Linux系统
以下这本书《Yocto项目实战教程:高效定制嵌入式Linux系统》即将发布,现在请哪位大佬出山写一个序或者推荐,有兴趣的大佬,请联系我! Git仓库地址: https://github.com/jerrysundev/Yocto-Project-Book.git …...
Git 常用指令及其说明
配置相关 # 配置全局用户名 git config --global user.name "YourUsername"# 配置全局邮箱 git config --global user.email "your.emailexample.com"说明:这两条命令用于设置 Git 全局的用户名和邮箱,在提交代码时,这些…...
nginx代理后502
直接访问 https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions正常 使用nginx代理后访问出现502 server {listen 9999;server_name 172.21.3.78;location ^~ /compatible-mode {proxy_pass https://dashscope.aliyuncs.com;}location / {proxy_pass…...
大模型WebUI:Gradio全解12——LangChain原理及其agent构建Gradio(1)
大模型WebUI:Gradio全解12——LangChain原理及其agent构建Gradio(1) 前言本篇摘要12. LangChain原理及其agent构建Gradio12.1 LangChain概念及优势分析12.1.1 概念12.1.2 标准化组件接口1. 示例:聊天模型2. 示例:检索器12.1.3 编排组件12.1.4 便于部署12.1.5 可观测性和评…...
【Unity】鱼群效果模拟
鱼群效果模拟 文章目录 鱼群效果模拟Boid算法实现方式version1_CPUversion2_GPUversion3_Multilaterationversion4_Bitonic_Sorting (GPU友好)version5_Skinning (TODO) 细节项优化项参考链接 Boid算法 Boid算法是一种模拟群体行…...
PHP入门基础学习五(函数1)
函数 一、概念 1、什么是函数? 函数:封装一段用于完成特定功能的代码 当使用一个函数时,只需关心函数的参数和返回值,就可以完成一个特定的功能 2、php中的函数 PHP 的真正威力源自于它的函数,PHP 中提供了超过 1000 个内建的函数。 php函数分为: 系统内部函数和自…...
微信小程序 - 页面跳转(wx.navigateTo、wx.redirectTo、wx.switchTab、wx.reLaunch)
API 跳转 1、wx.navigateTo (1)基本介绍 功能:保留当前页面,跳转到应用内的某个页面,使用该方法跳转后可以通过返回按钮返回到原页面 使用场景:适用于需要保留当前页面状态,后续还需返回的情…...
Typora的Github主题美化
[!note] Typora的Github主题进行一些自己喜欢的修改,主要包括:字体、代码块、表格样式 美化前: 美化后: 一、字体更换 之前便看上了「中文网字计划」的「朱雀仿宋」字体,于是一直想更换字体,奈何自己拖延症…...
2.3 变量
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 变量是用来存放某个值的数据,它可以表示一个数字、一个字符串、一个结构、一个类等。变量包含名称、类型和值。在代码中…...
Docker:Docker从入门到精通(一)- Docker简介
一、前言 通过本专栏的学习,我们将了解 1. 掌握Docker基础知识,能够理解Docker镜像与容器的概念 2. 完成Docker安装与启动 3. 掌握Docker镜像与容器相关命令 4. 掌握Tomcat Nginx 等软件的常用应用的安装 5. 掌握docker迁移与备份相…...
【复习】Redis
数据结构 Redis常见的数据结构 String:缓存对象Hash:缓存对象、购物车List:消息队列Set:点赞、共同关注ZSet:排序 Zset底层? Zset底层的数据结构是由压缩链表或跳表实现的 如果有序集合的元素 < 12…...
在Spring Boot+Vue前后端分离的项目中使用JWT实现基本的权限校验
说明 在 Spring Boot + Vue 前后端分离的项目中,如果不使用第三方服务(如 Spring Security、Shiro 等),可以通过自定义实现基本的权限校验。 使用JWT实现步骤 以下是实现步骤: 1. 设计权限模型 通常权限模型包括: 用户(User):系统的使用者。角色(Role):用户的权…...
蓝桥杯单片机组第十二届省赛第二批次
前言 第十二届省赛涉及知识点:NE555频率数据读取,NE555频率转换周期,PCF8591同时测量光敏电阻和电位器的电压、按键长短按判断。 本试题涉及模块较少,题目不难,基本上准备充分的都能完整的实现每一个功能,并…...
伪404兼容huawei生效显示404
根据上述思考,以下是详细的中文分步说明: --- **步骤 1:获取目标设备的User-Agent信息** 首先,我们需要收集目标设备的User-Agent字符串,包括: 1. **iPhone设备的User-Agent**: Mozi…...
UIAutomation开发常用方法的参考文档
简介 由于UIAutomation的官方文档只有一个github中的readme文件,只是简单的使用示例,具体使用还需要在代码中查找,非常不方便。经过我多年使用UIAutomation开发的经验和整理,把常用的功能梳理成本文档,作为我的开发参考使用,这样就不用每次都翻代码了,同时也可以使用AI…...
数据库面试题(基础常考!!!)
在数据库领域,无论是日常开发还是面试场景,都有一些高频且重要的问题需要我们深入理解和掌握。本文将对这些常见面试题进行详细阐述,帮助大家更好地应对面试和实际工作中的挑战。 面试题一:三范式详解 什么是三范式 三范式是关…...
ASP.NET Core Clean Architecture
文章目录 项目地址一、项目主体1. CQRS1.1 Repository数据库接口1.2 GetEventDetail 完整的Query流程1.3 创建CreateEventCommand并使用validation 2. EFcore层2.1 BaseRepository2.2 CategoryRepository2.3 OrderRepository 3. Email/Excel导出3.1 Email1. IEmail接口层2. Ema…...
【2024生成式推荐算法权威基准报告】:12家主流平台Llama-3/Gemini/DeepSeek适配实测数据,仅开放72小时下载权限
第一章:生成式AI应用推荐算法优化 2026奇点智能技术大会(https://ml-summit.org) 生成式AI正深度重构推荐系统的核心范式——从传统协同过滤与矩阵分解,转向以大语言模型(LLM)和扩散模型为基座的语义理解、意图生成与多模态内容合…...
HideVolumeOSD:彻底隐藏Windows音量栏的终极解决方案
HideVolumeOSD:彻底隐藏Windows音量栏的终极解决方案 【免费下载链接】HideVolumeOSD Hide the Windows 10 volume bar 项目地址: https://gitcode.com/gh_mirrors/hi/HideVolumeOSD 你是否厌倦了在全屏游戏或重要演示时被Windows音量栏打断?这款…...
SAP ECC6 EC-CS 合并报表操作手册(完整版)
SAP ECC6 EC-CS 合并报表操作手册(完整版)适用版本:ECC6.0(含 EHP)模块:EC-CS(Enterprise Controlling – Consolidation)核心用途:法定合并、管理合并、内部交易抵销、股…...
共探智能医疗与人工智能的新时代 | IHAI 2026
探索智能医疗与AI的未来 | IHAI 2026 国际会议 地点: 中国玉溪会议简介2026年智能医疗与人工智能国际会议(IHAI 2026)将于本年度在中国玉溪举行。这座融合了自然美景与多元文化的古城将迎来全球智能医疗和人工智能领域的顶尖专家、学者及行业领袖。本次大…...
别再手动截图了!用Python的PyMuPDF库,5分钟搞定PDF批量转高清图片(附完整代码)
5分钟极速解放生产力:PyMuPDF全自动PDF转高清图片实战指南 每次为了从PDF中提取几张图片,不得不一页页手动截图、调整尺寸、保存文件时,那种重复劳动的烦躁感是否让你抓狂?作为常年与PDF打交道的法律顾问,我曾因手动处…...
Halcon实战:用intensity算子5分钟搞定图像区域灰度分析(含Mean和Deviation详解)
Halcon实战:5分钟掌握图像区域灰度分析的核心技巧 在工业质检和缺陷检测领域,快速准确地评估图像区域的灰度特性是每个工程师的必备技能。Halcon作为机器视觉领域的标杆工具,其intensity算子能以惊人的效率完成这项任务——但很多初学者往往止…...
Payment扩展开发:如何自定义支付网关和添加新支付渠道
Payment扩展开发:如何自定义支付网关和添加新支付渠道 【免费下载链接】payment Payment是php版本的支付聚合第三方sdk,集成了微信支付、支付宝支付、招商一网通支付。提供统一的调用接口,方便快速接入各种支付、查询、退款、转账能力。服务端…...
P13 | 异步任务:后台长时间操作的最佳实践
P13 | 异步任务:后台长时间操作的最佳实践 💰 付费文章 | 第二阶段:后端开发 为什么需要异步任务? 有些操作耗时很长,不适合同步等待: 操作 耗时 是否需要异步 查询列表 < 200ms ❌ 上传单张图片 1-3s ⚠️ 可选 批量生成 ZIP 打包下载 10s-5min ✅ 必须 AI 人脸识别…...
大模型Agent越调越乱?别怪模型不够强,这三层优化才是关键!
文章指出,使用相同大模型的企业,Agent表现差异巨大,原因并非模型强弱,而是系统优化问题。文章提出三层优化框架:模型层(通用能力)、Harness层(系统编排)、Context层&…...
Linux系统遭挖矿入侵:从异常告警到根因定位的实战排查指南
1. 告警触发:CPU异常飙升的第一反应 那天凌晨3点,我正在睡梦中,手机突然疯狂震动。打开一看,监控系统连续发了十几条告警:某台线上服务器的CPU使用率突破95%,持续时间已超过15分钟。这种半夜告警最让人头疼…...
