裸机单片机适用的软件架构

单片机通常分为三种工作模式,分别是

1、前后台顺序执行法                        2、操作系统                         3、时间片轮询法              

1、前后台顺序执行法

        利用单片机的中断进行前后台切换,然后进行任务顺序执行,但其实在很多时候都是处于一种浪费资源的使用,因为大部分时候都要去查看事件是否发生,并且其实时性低,由于每个函数或多或少存在毫秒级别的延时,即使是1ms,也会造成其他函数间隔执行时间的不同,虽然可通过定时器中断的方式,但是前提是中断执行函数花的时间必须短。当程序逻辑复杂度提升时,会导致后来维护人员的大脑混乱,很难理清楚该程序的运行状态。

其也就是大轮训进行执行while里面的函数

2、操作系统

        嵌入式操作系统EOS(Embedded OperatingSystem)是一种用途广泛的系统软件,过去它主要应用于工业控制和国防系统领域,而对于单片机来说,比较常用的有UCOS、FreeRTOS、RT-Thread Nano和RTX 等多种抢占式操作系统(其他如Linux等操作系统不适用于单片机)

        操作系统和“时间片轮询法”,在任务执行方面来说,操作系统对每个任务的耗时没有过多的要求,需要通过设置每个任务的优先级,在高优先级的任务就绪时,会抢占低优先级的任务;操作系统相对复杂,因此这里没有详细介绍了。

3、时间片轮询法 

      时间片轮询法是介于前后台顺序执行法和操作系统之间的一种程序架构设计方案。任务函数无需时刻执行,存在间隔时间(比如按键,一般情况下,都需要软件防抖,初学者的做法通常是延时10ms左右再去判断,但10ms极大浪费了CPU的资源,在这段时间内CPU完全可以处理很多其他事情)。

        该设计方案需要使用一个定时器,一般情况下定时1ms即可(定时时间可随意定,但中断过于频繁效率就低,中断太长,实时性差),因此需要考虑到每个任务函数的执行时间,建议不能超过1ms(能通过程序优化缩短执行时间则最好优化,如果不能优化的,则必须保证该任务的执行周期必须远大于任务所执行的耗时时间),同时要求主循环或任务函数中不能存在毫秒级别的延时。

时间片轮询法的实现(指针方式)

首先定义一个结构体,用于存储一个任务的所有信息,如下所示:

typedef struct
{
	uint8_t  u8_runflag;		/*程序是否运行标志    TASK_OFF_RUN:不运行   TASK_ON_RUN:运行*/
	uint16_t u16_timer;			/*计时器*/
	uint16_t u16_itvTime;		/*运行间隔时间,也就是多久运行一次*/
	void (*p_TaskHook)(void);	/*任务*/
}Task_InfoType;

然后创建一个具有绑定关系的任务数组:

static Task_InfoType Task_Info[TASK_MAX] = {
	{TASK_OFF_RUN,TASK_200ms,TASK_200ms,logic_task},//逻辑任务
	{TASK_OFF_RUN,TASK_1000ms,TASK_1000ms,led_task}	//LED任务
};

        从上图中可以看出,这里创建了两个任务,一个逻辑任务200ms执行一次,另外一个则是1000ms执行一次的LED任务,根据任务的情况,可以自己添加自己需要的。

        有了关系之后,那么就需要让这个小系统跑起来了,下面两个函数分别是函数标志位修改函数和函数执行函数。其实这个小系统也就是一个计时,到时间,则打开标志位,去执行对应的函数,标志位没有打开则跳过。

/*
	任务标志处理函数
	定时器1ms中断处理
*/
void Task_Remarks(void)
{
	for(int i=0;i<TASK_MAX;i++)
    {
		if(Task_Info[i].u16_timer)
		{
			Task_Info[i].u16_timer--;
			if(TASK_TIME_ON == Task_Info[i].u16_timer)
			{//定时器计数到后,打开函数运行标志位
				Task_Info[i].u16_timer = Task_Info[i].u16_itvTime;
				Task_Info[i].u8_runflag = TASK_ON_RUN;
			}
		}
    }
}
/*
	任务函数运行处理
	放入主函数的循环中
*/
void Task_Process(void)
{
	for(int i=0;i<TASK_MAX;i++)
    {
		if(Task_Info[i].u8_runflag == TASK_ON_RUN)
		{
			Task_Info[i].p_TaskHook();
			Task_Info[i].u8_runflag = TASK_OFF_RUN;
		}
    }
}

弄完这些后,只需要去配置一个1ms定时器,将计时函数放入其中,即可

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *hitm)
{
	if(hitm->Instance == TIM7)
	{
		Task_Remarks();
	}
}

到这里,这个小系统就完成了一大半了,在这里还需要添加一个打印函数,但是如何做到控制这个打印函数,只需要改变宏定义就可以实现关闭所以的打印呢,在实际的项目中,都会使用这种方式来进行系统的调试。

宏定义控制printf-CSDN博客

STM32关于UART的接收方式_stm32中huart1-CSDN博客

关于STM32CubeIDE使用printf串口打印_stm32cubeide printf-CSDN博客

这些都是跟调试有关的一些文章,可以查看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/237634.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[排序篇] 冒泡排序

目录 一、概念 二、冒泡排序 2.1 冒泡降序(从大到小排序) 2.2 冒泡升序(从小到大排序) 三、冒泡排序应用 总结 一、概念 冒泡排序核心思想&#xff1a;每次比较两个相邻的元素&#xff0c;如果它们不符合排序规则&#xff08;升序或降序&#xff09;则把它们交换过来。…

Web自动化测试工具起到哪些重要作用

随着互联网的迅猛发展&#xff0c;Web应用程序已经成为企业不可或缺的一部分。为了确保Web应用的质量和可靠性&#xff0c;Web自动化测试工具变得至关重要。以下是Web自动化测试工具在软件开发生命周期中发挥的作用&#xff1a; 1. 提高测试效率和速度 Web自动化测试工具可以快…

【媒体开发】利用FFMPEG进行推拉流

1. 下载并启动媒体服务 MediaMTX&#xff0c;也即之前的rtsp-simple-server&#xff0c;是一个即用型、零依赖的实时媒体服务器和媒体代理&#xff0c;允许发布、读取、代理和记录视频和音频流。 从Releases bluenviron/mediamtx GitHub找到最新版&#xff0c;下载对应平台…

Web UI 自动化 元素定位利器

序 元素定位&#xff0c;对于 Web UI 自动化而言&#xff0c;绝对是大家成长道路上的一道绊脚石。 很多初学者&#xff0c;都“死”在了元素定位上&#xff0c;从而失去了学习的兴趣。导致职业规划不得不半途而废~ 那么&#xff0c;今天&#xff0c;我们就使用 Katalon Stu…

python实战演练之迎接冬至的第一场雪

写在前面 WINTER IS COMING Python实现大雪纷飞的效果&#xff0c;完整代码在文末哦~ 准备开始 WINTER IS COMING Python是一种高级编程语言&#xff0c;Turtle是Python的一个图形化模块&#xff0c;它可以帮助学习者更好地理解编程概念&#xff0c;同时可以进行图形化编程。 …

DS二叉排序树之删除

Description 给出一个数据序列&#xff0c;建立二叉排序树&#xff0c;并实现删除功能 对二叉排序树进行中序遍历&#xff0c;可以得到有序的数据序列 Input 第一行输入t&#xff0c;表示有t个数据序列 第二行输入n&#xff0c;表示首个序列包含n个数据 第三行输入n个数据…

修改汽车的控制系统实现自动驾驶,基于一个开源的汽车驾驶辅助系统实现全自动驾驶

修改汽车的控制系统实现自动驾驶,基于一个开源的汽车驾驶辅助系统实现全自动驾驶。 自动驾驶汽车依靠人工智能、视觉计算、雷达、监控装置和全球定位系统协同合作,让电脑可以在没有任何人类主动的操作下,自动安全地操作机动车辆。 演示视频: Openpilot :一个开源的汽车驾…

音乐制作工具 Ableton Live 12中文最新 for Mac

Ableton Live 12 Mac具有直观的界面和强大的功能&#xff0c;使得音乐制作变得更加简单和高效。它支持实时录制、编辑和混音&#xff0c;用户可以在创作过程中随时进行修改和调整。此外&#xff0c;该软件还提供了各种音频效果、虚拟乐器和采样器&#xff0c;使用户可以创建出更…

el-table的复选框占满全格

el-table的复选框格子很小每次点击都点不到&#xff0c;又不想设置行点击&#xff0c;因为每次复制内容都会选中&#xff0c;实现效果是点击el-table的复选框单元格就可以选中 <template><div style"width: 60vw; margin: 10px;"><el-table :data&quo…

1 CPU实现的基本框图

汇编语言 && 指令格式 CPU设计的框架&#xff1a;三级流水线 ROM存放指令和数据&#xff0c;大端模式&小端模式&#xff0c;地址对齐 取指 译码&#xff1a; 执行&#xff1a; 汇编语言 & 指令格式 流水线实现工作机制 模块功能划分&接口信号 参考…

新工科:数据科学与大数据技术实验中心解决方案,赋能高校新工科数智人才培养

随着数字经济蓬勃发展&#xff0c;数字化产业和产业数字化成为就业增长新动能。据人瑞人才与德勤调研显示&#xff0c;未来3年&#xff0c;数字产业化企业最需要运营人员和开发人员&#xff08;包括大数据开发工程师、数据建模开发工程师等&#xff09;&#xff0c;其次是数据分…

12 位多通道国产芯片ACM32F403/F433 系列,支持 MPU 存储保护功能,应用于工业控制,智能家居等产品中

ACM32F403/F433 芯片的内核基于 ARMv8-M 架构&#xff0c;支持 Cortex-M33 和 Cortex-M4F 指令集。芯片内核 支持一整套DSP指令用于数字信号处理&#xff0c;支持单精度FPU处理浮点数据&#xff0c;同时还支持Memory Protection Unit &#xff08;MPU&#xff09;用于提升应用的…

lv13 交叉开发环境搭建

1 ubuntu网络环境配置 目的&#xff1a;让Ubuntu可以上外网&#xff0c;让开发板可以与ubuntu互通 2 tftp 服务器环境搭建 tftp&#xff08;Trivial File Transfer Protocol&#xff09;即简单文件传输协议 是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件 传输…

LabVIEW发开发电状态监测系统

LabVIEW发开发电状态监测系统 对发电设备的持续监测对于确保可靠的电力供应至消费者极为重要。它不仅能够及时提醒操作员注意发电设备的潜在损坏&#xff0c;还能减少由于设备故障造成的停机时间。为了达到这一目标&#xff0c;开发了一款基于LabVIEW的软件&#xff0c;专门用…

基于YOLOv8深度学习的血细胞检测与计数系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战、智慧医疗

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【UE5】监控摄像头效果(下)

目录 效果 步骤 一、多摄像机视角切换 二、摄像头自动旋转巡视 三、摄像头跟踪拍摄 效果 步骤 一、多摄像机视角切换 1. 打开玩家控制器“MyPlayerController”&#xff0c;添加一个变量&#xff0c;命名为“BP_SecurityCameraArray”&#xff0c;类型为“BP_SecurityCa…

Word插件-好用的插件-批量插入图片-大珩助手

现有100张图片&#xff0c;需要批量插入word中&#xff0c;并在word中以每页6张图片的形式呈现&#xff0c;请问怎样做&#xff1f; 使用word大珩助手&#xff0c;多媒体-插入图片&#xff0c;根据图片的长宽&#xff0c;选择连续图片、一行2个图或一行3个图&#xff0c;可一次…

线程互斥与同步

用户级线程 内核的LWP Linux线程 OS概念中经常说的 用户级线程 和 内核级线程 也就是线程实现真的是在OS内部实现&#xff0c;还是应用层或用户层实现 很明显Linux是属于用户级线程 用户级执行流&#xff08;用户级线程&#xff09; &#xff1a;内核lwp 1 : 1 也有1&…

#define宏定义

#define 语法规定 #define定义标识符 语法: #define name stuff #define例子 #include<stdio.h> #define A 100 #define STR "abc" #define FOR for(;;)int main() {printf("%d\n", A);printf("%s\n", STR);FOR;return 0; } 运行结果…

Flutter实现自定义二级列表

在Flutter开发中&#xff0c;其实系统已经给我们提供了一个可靠的二级列表展开的API&#xff08;ExpansionPanelList&#xff09;&#xff0c;我们先看系统的二级列表展开效果&#xff0c;一次只能展开一个&#xff0c;用ExpansionPanelList.radio实现 由此可见&#xff0c;已经…