单片机裸机编程-时机管理
对于 RTOS 实时操作系统,我们是通过 TASK(任务)进行底层操作的,这与裸机编程中的函数(fun)类似。不同的任务或函数实现不同的功能,在RTOS中,单片机有信号量、队列等不同任务之间的通信机制,但对于裸机编程来说就引出了一个问题:不同任务或函数是如何配合工作的呢?换句话说,单片机是如何知道什么时候该做什么事情,或者为什么做完一件事之后再做另一件事呢?
1、裸机的逻辑轮询
在裸机编程中,任务的执行顺序通常是固定的,由程序的流程控制语句(如 if、while、switch 等)决定。程序从入口点开始,按顺序执行代码,直到遇到分支或循环。当然,也可以通过中断来实现某些功能。
例如,以下代码展示了通过全局变量的状态来控制不同函数的执行逻辑:
void main() {while (1) {if (sensor_data_ready) { // 检查传感器数据是否准备好process_sensor_data();}if (button_pressed) { // 检查按钮是否被按下handle_button_press();}update_display(); // 更新显示}
}
在这个例子中,程序通过全局变量(sensor_data_ready 和 button_pressed)来判断是否执行某个函数。
也就是说,在不同的执行函数之间的通信使用的是全局变量,或者说是标志位。我们通过if,switch这样的逻辑语句让单片机知道在什么情况下该做什么事,所以只需要一直轮询下去即可。
这种方式简单直接,但存在以下问题:
-
耦合性高:全局变量的使用使得代码之间的耦合性增加,难以维护和扩展。
-
灵活性差:任务的执行顺序固定,难以动态调整。
2、使用状态机进行任务管理
为了改善上述问题,我们可以引入 状态机 的概念,对不同的任务进行局部管理。状态机通过定义不同的状态和状态之间的转换条件,使得代码更加模块化和灵活。例如:
typedef enum {STATE_IDLE,STATE_PROCESS_SENSOR,STATE_HANDLE_BUTTON,STATE_UPDATE_DISPLAY
} StateTypeDef;StateTypeDef currentState = STATE_IDLE;void main() {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;}}
}
通过状态机,我们可以清晰地定义每个任务的执行条件和状态转换逻辑,从而提高代码的可读性和可维护性。
3、在裸机中实现时间片轮询
进一步思考,我们可以在裸机编程中借鉴 RTOS 的时间片轮询机制。虽然裸机没有 RTOS 内核的支持,但可以通过定时器中断来实现类似的效果。例如:
-
设置定时器中断:配置定时器以固定频率(如 10ms)触发中断。
-
维护任务状态:在定时器中断中维护一个任务状态数组,记录每个任务的执行状态和剩余时间片。
-
轮询任务执行:在主循环中,根据任务状态数组依次执行每个任务的一部分。
示例代码如下:
#define TASK_COUNT 3
#define TIME_QUANTUM 10 // 时间片大小,单位为毫秒typedef struct {void (*taskFunc)(void); // 任务函数指针int remainingTime; // 剩余时间片
} TaskTypeDef;TaskTypeDef tasks[TASK_COUNT] = {{process_sensor_data, TIME_QUANTUM},{handle_button_press, TIME_QUANTUM},{update_display, TIME_QUANTUM}
};void Timer_ISR(void) {static int tick = 0;tick++;
}void main() {int currentTask = 0;while (1) {if (tasks[currentTask].remainingTime > 0) {tasks[currentTask].taskFunc(); // 执行当前任务tasks[currentTask].remainingTime--;}currentTask = (currentTask + 1) % TASK_COUNT; // 轮询下一个任务}
}
通过这种方式,我们可以在裸机中实现类似 RTOS 的时间片轮询机制,使得任务的执行更加公平和灵活。
个人喜欢使用状态机进行裸机编程,这样直接是多个代码块直接的裸机判断。也就相当于是有多个while(1)循环,方便代码的管理和调试。在不同的state模式下执行不同的小模块代码。
相关文章:
单片机裸机编程-时机管理
对于 RTOS 实时操作系统,我们是通过 TASK(任务)进行底层操作的,这与裸机编程中的函数(fun)类似。不同的任务或函数实现不同的功能,在RTOS中,单片机有信号量、队列等不同任务之间的通…...
Flutter系列教程之(2)——Dart语言快速入门
目录 1.变量与类型 1.1 num类型 1.2 String类型 1.3 Object与Dynamic 1.4 类型判断/转换 1.5 变量和常量 2.方法/函数 3.类、接口、抽象类 3.1 类 3.2 接口 4.集合 4.1 List 4.2 Set 4.3 Map 5.总结 Dart语言的语法和Kotlin、Java有类似之处,这里就通…...
pyecharts介绍
文章目录 介绍安装pyecharts基本使用全局配置选项 折线图相关配置地图模块使用柱状图使用 介绍 echarts虑是个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可,而Pyhon是门富有表达力的语言&a…...
前缀和相关题目记录(未完待续...)
1 前缀和 一维前缀和是指对于一个数组 a a a,我们定义一个新的数组 s s s,其中每个元素 s [ i ] s[i] s[i] 表示从数组开头到第 i i i 个元素的累加和: s [ i ] a [ 1 ] a [ 2 ] ⋯ a [ i ] ∑ j 1 i a [ j ] s[i] a[1] a[2] \…...
Https解决了Http的哪些问题
部分内容来源:小林coding 详细解析 Http的风险 HTTP 由于是明文传输,所以安全上存在以下三个风险: 1.窃听风险 比如通信链路上可以获取通信内容,用户号容易没。 2.篡改风险 比如强制植入垃圾广告,视觉污染&#…...
OpenCV给图像添加噪声
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 如果你已经有了一张干净的图像,并希望通过编程方式向其添加噪声,可以使用 OpenCV 来实现这一点。以下是一个简单的例子&a…...
湖北中医药大学谱度众合(武汉)生命科技有限公司研究生工作站揭牌
2025年2月11日,湖北中医药大学&谱度众合(武汉)生命科技有限公司研究生工作站揭牌仪式在武汉生物技术研究院一楼101会议室举行,湖北中医药大学研究生院院长刘娅教授、基础医学院院长孔明望教授、基础医学院赵敏教授、基础医学院…...
欢乐力扣:快乐数
文章目录 1、题目描述2、思路1代码 1、题目描述 快乐数。 编写一个算法来判断一个数 n 是不是快乐数。 快乐数定义为:对于一个正整数,每次不断将其转化成 每位数字的平方和。 判断是否最终和会为1,是1就是快乐数,否则不是。 …...
【聊天室后端服务器开发】功能设计-框架与微服务
服务器功能设计 微服务思想应用 微服务架构 主要组成分析 客户端 客户端通过 HTTP 协议与网关进行交互,进行操作如用户注册、好友申请等客户端只需要知道网关的地址,无需关心后端服务的具体实现 网关 作为系统的统一入口,网关负责接收客…...
国标28181协议在智联视频超融合平台中的接入方法
一. 国标28181介绍 国标 28181 协议全称是《安全防范视频监控联网系统信息传输、交换、控制技术要求》,是国内视频行业最重要的国家标准,目前有三个版本: 2011 年:推出 GB/T 28181-2011 版本,为安防行业的前端设备、平…...
让网页“浪“起来:打造会呼吸的波浪背景
每次打开那些让人眼前一亮的网页时,你是否有注意到那些看似随波逐流的动态背景?今天咱们不聊高深的技术,就用最朴素的CSS,来解锁这个让页面瞬间鲜活的秘籍。无需JavaScript,不用复杂框架,准备好一杯咖啡&am…...
linux-多进程基础(1) 程序、进程、多道程序、并发与并行、进程相关命令,fork
程序是什么 程序是包含一系列信息的文件。这些信息描述了如何在运行时创建一个进程,包含二进制格式标识、机器语言指令、程序入口地址、数据、符号表及重定位表、共享库信息及其他信息 二进制格式标识,每个程序包含了描述可执行文件的元信息(是否可读之…...
美颜相机1.0
项目开发步骤 1 界面开发 美颜相机界面构成: 标题 尺寸 关闭方式 位置 可视化 2 创建主函数调用界面方法 3 添加两个面板 一个是按钮面板一个是图片面板 用JPanel 4 添加按钮到按钮面吧【注意:此时要用初始化按钮面板的方法initBtnPanel 并且将按钮添…...
Docker内存芭蕾:优雅调整容器内存的极限艺术
title: “💾 Docker内存芭蕾:优雅调整容器内存的极限艺术” author: “Cjs” date: “2025-2-23” emoji: “🩰💥📊” 当你的容器变成内存吸血鬼时… 🚀 完美内存编排示范 📜 智能内存管家脚本…...
gitlab初次登录为什么登不上去
今天又写了一次gitlab安装后,第一次登录的问题。 gitlab工作笔记_gitlab默认用户名密码-CSDN博客 因为又掉这个坑里了。 # 为什么第一次登录这么难? 第一是因为gitlab启动的时间很长,有时候以为装错了。 第二是初始密码,如果…...
单链表相关操作(基于C语言)
文章目录 单链表定义版本一(可自己选择是否含头节点)创建单链表打印单链表对单链表进行冒泡排序删除单链表中值为key的节点求单链表表长在单链表位序为i的位置插入新元素e 单链表定义 typedef struct node {int data;struct node* next; }LinkNode,*LinkList;版本一(可自己选择…...
SPRING10_SPRING的生命周期流程图
经过前面使用三大后置处理器BeanPostProcessor、BeanFactoryPostProcessor、InitializingBean对创建Bean流程中的干扰,梳理出SPRING的生命周期流程图如下...
从零到一学习c++(基础篇--筑基期十一-类)
从零到一学习C(基础篇) 作者:羡鱼肘子 温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。 温馨提示2:本篇会尽量用更加通俗的语言介绍c的基础,用通俗的语言去…...
Java String 类
Java String 类常用方法详解 在 Java 编程里,字符串操作十分常见,而 String 类作为 Java 标准库的核心类,用于表示不可变的字符序列。任何对字符串的修改操作都会返回一个新的字符串对象,不会改变原始字符串。本文将详细介绍 Str…...
P8665 [蓝桥杯 2018 省 A] 航班时间
P8665 [蓝桥杯 2018 省 A] 航班时间 题目代码分析 题目 代码 #include <iostream> #include <vector> #include <string> #include <algorithm> #include <math.h> #include <queue>#include <cctype> using namespace std; int t;…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
