单片机:实现多任务处理(附带源码)
单片机实现多任务处理
多任务处理是现代操作系统的重要特性,通常通过多线程、多进程的方式来并行执行多个任务。在嵌入式系统中,由于资源有限,通常通过时间片轮转或中断机制来模拟多任务处理。本项目将展示如何在8051单片机上实现简单的多任务处理。
在8051单片机中,真正的多任务处理(如操作系统中的多线程)并不常见,因为8051单片机资源有限(内存小、没有硬件支持的线程管理)。但我们可以通过使用定时器中断和轮询机制,模拟多任务处理的功能。
一、项目需求
- 任务切换:模拟多任务处理,能够在多个任务之间切换。
- 定时器中断:使用定时器中断模拟任务调度。
- 任务执行:执行多个不同的任务,例如LED闪烁、按键扫描、数码管显示等。
二、系统设计
2.1 多任务模拟
我们通过使用定时器中断来定期触发任务切换。在8051中,定时器中断通常是最合适的机制来模拟任务调度,因为它允许我们在多个任务之间“轮流”执行,类似于操作系统中的时间片轮转。
2.2 任务设计
我们将设计两个简单的任务:
- 任务1:LED灯闪烁任务,每秒钟切换一次LED状态。
- 任务2:按键扫描任务,用于检查按键是否按下,并切换LED的状态。
2.3 任务调度
我们通过一个全局的计时器变量来模拟“任务切换”的概念,每当定时器溢出时,增加一个计数值,根据计数值来决定当前执行哪个任务。
三、硬件设计
- 单片机:使用8051单片机(如AT89C51)。
- LED灯:用于显示任务执行状态。
- 按键:用于输入,控制LED的状态。
四、程序设计
4.1 定时器中断
使用8051的定时器中断来定期切换任务,假设每个任务的时间片为10ms。我们可以通过定时器来模拟任务切换,每次中断时判断当前任务是否结束,切换到下一个任务。
4.2 任务切换逻辑
通过一个计数器来跟踪时间片,当计时器中断发生时,增加计数器的值。根据计数器的值,选择当前执行的任务。例如,当计数器的值为偶数时,执行任务1;当计数器的值为奇数时,执行任务2。
4.3 代码实现
#include <reg51.h> // 包含8051单片机的寄存器定义// 定义LED端口
#define LED P2// 定义按键端口(用于启动/停止LED)
#define BUTTON P3_0// 任务切换计数器
volatile unsigned int task_counter = 0;// 定时器初始化
void timer0_init() {TMOD = 0x01; // 设置定时器0为模式1(16位定时器)TH0 = 0xFC; // 定时器初值,使得定时器每溢出一次,周期为10msTL0 = 0x18; // 定时器初值ET0 = 1; // 允许定时器0中断EA = 1; // 允许全局中断TR0 = 1; // 启动定时器0
}// 定时器0中断服务程序
void timer0_isr() interrupt 1 {task_counter++; // 每次定时器中断时,增加任务切换计数器// 重载定时器初值TH0 = 0xFC; // 定时器重新加载初值TL0 = 0x18;// 根据计数器值选择任务if (task_counter % 2 == 0) {task1(); // 执行任务1} else {task2(); // 执行任务2}
}// 任务1:LED闪烁任务
void task1() {static bit led_state = 0; // LED的状态(0:灭,1:亮)// 每次任务1执行时,切换LED的状态led_state = !led_state;LED = led_state ? 0xFF : 0x00;
}// 任务2:按键扫描任务
void task2() {if (BUTTON == 0) { // 如果按键被按下delay_ms(20); // 延时去抖动if (BUTTON == 0) { // 确认按键按下LED = 0xFF; // 点亮LED}}
}// 延时函数,用于按键去抖动
void delay_ms(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++) {for (j = 0; j < 120; j++) {// 空循环,产生延时}}
}// 主程序
void main() {timer0_init(); // 初始化定时器while (1) {// 主要任务通过定时器中断执行,不需要在这里处理}
}
五、程序说明
-
定时器初始化:
- 使用8051的定时器0,配置为模式1(16位定时器),每10ms触发一次中断。在定时器中断服务程序中,我们通过增加一个计数器来决定当前应该执行哪个任务。
-
任务1(LED闪烁任务):
- 每次执行任务1时,我们切换LED的状态(开关状态)。
-
任务2(按键扫描任务):
- 任务2用来扫描按键状态,如果按键被按下,LED灯会点亮。
-
任务调度:
- 每当定时器中断发生时,
task_counter增加1。根据task_counter的值,我们选择执行任务1或任务2,实现任务的切换。 - 每次任务切换时,都会根据
task_counter的奇偶性来判断当前执行哪个任务,模拟了一个简单的轮转调度。
- 每当定时器中断发生时,
-
按键去抖动:
- 使用
delay_ms函数对按键进行去抖动处理,避免因为按键的抖动导致误判。
- 使用
六、总结
通过本项目,我们在8051单片机上实现了简单的多任务处理。虽然8051单片机本身不支持多任务处理,但我们可以通过定时器中断和计数器来模拟任务切换,达到并行执行多个任务的效果。我们使用定时器模拟时间片轮转,并通过LED灯和按键扫描实现了两个简单的任务。
这种多任务处理的方法适用于资源有限、对实时性要求较高的嵌入式系统。虽然其功能相对简单,但足以满足一些嵌入式应用的需求,例如控制LED灯、扫描按键等。
在实际的项目中,如果系统需要处理更多的任务,可以通过增加定时器中断的频率或调整任务调度算法来进一步优化系统的多任务处理能力。
相关文章:
单片机:实现多任务处理(附带源码)
单片机实现多任务处理 多任务处理是现代操作系统的重要特性,通常通过多线程、多进程的方式来并行执行多个任务。在嵌入式系统中,由于资源有限,通常通过时间片轮转或中断机制来模拟多任务处理。本项目将展示如何在8051单片机上实现简单的多任…...
负载均衡oj项目:介绍
目录 项目介绍 项目演示 项目介绍 负载均衡oj是一个基于bs模式的项目。 用户使用浏览器向oj模块提交代码,oj模块会在所有在线的后端主机中选择一个负载情况最低的主机,将用户的代码提交给该主机,该主机进行编译运行,将结果返回…...
剑指Offer 03比特位计数
只是记录 题目链接 题目链接 自己想出来的 第一种解法 思路简述 遍历[0,n]之间的数字,对于每一个数字按照二进制的方式展开,判断最低位置是否为1,若为1则1,反之不加,直到该数字等于0就停止。 public static int[] …...
多音轨视频使用FFmpeg删除不要音轨方法
近期给孩子找宫崎骏动画,但是有很多是多音轨视频但是默认的都是日语,电视上看没办法所以只能下载后删除音轨文件只保留中文。 方法分两步,先安装FFmpeg在转文件即可。 第一步FFmpeg安装 FFmpeg是一个开源项目,包含了处理视频的…...
elasticsearch 使用enrich processor填充数据
文章目录 使用 POST 请求手动插入用户数据1. 创建 Enrich Policy步骤 1.1: 创建 Enrich Policy步骤 1.2: 执行 Enrich Policy 2. 创建 Ingest Pipeline步骤 2.1: 创建 Ingest Pipeline步骤 2.2: 配置 Enrich Processor 参数 3. 使用 Ingest Pipeline步骤 3.1: 使用 Pipeline 进…...
VMProtect:软件保护与安全的全面解决方案
在当今数字化时代,软件的安全性和保密性愈发重要。VMProtect 作为一款备受瞩目的软件保护工具,因其强大的功能和广泛的应用而成为开发者保护软件的首选方案。 VMProtect 是一款新一代的软件保护实用程序,支持多个编译器平台,包括…...
Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:教室信息管理系统(前后端源码 + 数据库 sql 脚本)
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 1.0 项目介绍 开发工具:IDEA、VScode 服务器:Tomcat, JDK 17 项目构建:maven 数据库:mysql 8.0 系统用户前台和管理…...
第十二篇:linux下socket本地套接字通讯
使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。 用途 进程间通信:本地套…...
Spring Boot 2.1.7 数据源自动加载过程详解
在 Spring Boot 中,数据源的自动配置是框架中一个关键功能,本文将以 Spring Boot 2.1.7 版本为例,详细讲解在单数据源情况下数据源是如何自动加载的。我们通过源码分析,追踪整个加载流程。 1. 自动配置类的发现 Spring Boot 使用…...
【Vue.js 3.0】provide 、inject 函数详解
在 Vue 3 中,provide 和 inject 是用于跨组件层次结构进行依赖注入的一对 API。这些 API 主要用于祖先组件和后代组件之间的数据传递,尤其是当这些组件之间没有直接的父子关系时。 1. 示例 1.1 provide provide 函数用于在祖先组件中定义一个值&#…...
JVM(Java虚拟机)的虚拟机栈
JVM(Java虚拟机)的虚拟机栈是Java程序运行时的重要组件,以下是对其的详细解析: 一、概念与功能 概念:虚拟机栈也称为Java栈,是JVM为每个线程分配的一个私有的内存区域。每个线程在创建时都会创建一个虚拟…...
Elasticsearch02-安装7.x
零、文章目录 Elasticsearch02-安装7.x 1、Windows安装Elasticsearch (1)JDK安装 Elasticsearch是基于java开发的,所以需要安装JDK。我们安装的Elasticsearch版本是7.15,对应JDK至少1.8版本以上。也可以不安装jdk,…...
iPhone恢复技巧:如何从 iPhone 恢复丢失的照片
在计算机时代,我们依靠手机来捕捉和存储珍贵的回忆。但是,如果您不小心删除或丢失了手机上的照片怎么办?这真的很令人沮丧和烦恼,不是吗?好吧,如果您在 iPhone 上丢失了照片,您不必担心…...
vba批量化调整word的图和图表标题
vba代码 将图片进行居中操作 Sub ChangePictureFormate()Dim oPara As ParagraphDim oRange As RangeDim i As LongDim beforeIsPicture As BooleanbeforesIsPicture False 确保文档中至少有图片If ActiveDocument.InlineShapes.Count 0 ThenMsgBox "没有找到图片。&qu…...
【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互
前言 欢迎来到第二篇文章,这也是第二个难题,就是原有的移动端本身一些页面H5的形式去呈现(webview),例如某些需要动态更换内容的页面,某些活动页面、支付页面,不仅仅做页面呈现,还包…...
【C语言的奥秘11】指针知识点总结(续)
目录 一、指针的运算 1、指针与整数相加减 2、指针-指针(地址-地址) 3、指针的关系运算 六、指针和数组 七、二级指针 八、指针数组 一、指针的运算 1、指针与整数相加减 看一下下面的代码: #include<stdio.h> int my_strlen(c…...
excel 列名是数据表 的字段名 ,单元格的值 是数据表对应字段的值,生成sql插入语句
在 Excel 中,按 Alt F11 打开 VBA 编辑器。在菜单栏选择 插入 -> 模块,在新模块中粘贴以下代码。 VBA 代码 Sub GenerateSQLInsertStatementsToFile()Dim ws As WorksheetDim lastRow As Long, lastCol As Long, i As Long, j As LongDim sql As S…...
AI Agent与MEME:技术与文化融合驱动Web3创新
AI Agent如何引领Web3新时代? 随着Web3与区块链技术的迅速发展,AI Agent作为人工智能与区块链的交汇点,正在逐步成为推动去中心化生态的重要力量。同时,MEME文化凭借其强大的社区驱动力和文化渗透力,在链上生态中扮演着…...
IO的入门
目录 1.IO概述1.1流的分类 2.字符流2.1 案例 1.IO概述 IO(Input/Output):输入和输出,指的是某个设备或环境进行数据的输入或者输出。例如:键盘的输入,再比如显示器就是输出设备,输出图像。 对于java来说输…...
构建一个rust生产应用读书笔记四(实战1)
我们需要从访客那里收集哪些信息,以便将其登记为电子邮件通讯的订阅者? 电子邮件地址:这是最基本的要求,因为我们需要通过电子邮件地址向订阅者发送内容。姓名:虽然这不是强制性的,但我们希望收集一个名字…...
【FMCW雷达】频率调制连续波FMCW雷达系统(从波形生成到利用小胞平均常误报率CA-CFAR进行目标检测)【含Matlab源码 15242期】含报告
💥💥💥💥💥💥💥💥💞💞💞💞💞💞💞💞💞Matlab武动乾坤博客之家💞…...
Android安全漏洞案例分析:血淋淋的教训
Android安全漏洞案例分析:血淋淋的教训 Android安全漏洞案例分析:血淋淋的教训 案例一:Secret Token泄露导致账户劫持 漏洞危害:攻击者获取用户全部权限 某社交App在客户端硬编码了API密钥,攻击者通过反编译获取密钥…...
千问3.5-27B知识库应用:OpenClaw变身技术问答助手
千问3.5-27B知识库应用:OpenClaw变身技术问答助手 1. 为什么需要本地化技术问答助手? 去年我在开发一个开源项目时,遇到了一个奇怪的Docker网络问题。当时在Stack Overflow上搜索了半天,找到的答案要么过时,要么不适…...
如何快速清理Windows 11臃肿:Win11Debloat完整优化指南
如何快速清理Windows 11臃肿:Win11Debloat完整优化指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and c…...
游戏服务器检测扣除消耗防算数溢出的安全判断及解决方法
游戏服务器检测扣除消耗防算数溢出的安全判断及解决方法 数量 > (类型最大值 / 价格) 负数存在风险 价格 > (类型最大值 / 数量) || 价格 < (最小值 / 数量) 游戏服务器在处理道具消耗时需防止数值溢出问题。当检测扣除消耗时,应进行双重安全判…...
面相对象高级(static)
##静态(static)1.static修饰成员变量:类变量:有static修饰,属于类,在计算机里只有一份,会被类的全部对象共享因为属于类,需要通过类名就可以调用:类名.静态变量##### 实际…...
STM32F407ZGT6最小系统:从原理图到PCB的实战设计解析
1. STM32F407ZGT6最小系统设计入门 第一次接触STM32F407ZGT6最小系统设计时,我也被各种专业术语和复杂的电路图搞得晕头转向。但经过几个项目的实战后,我发现只要掌握几个关键模块,设计一个稳定可靠的最小系统其实并不难。STM32F407ZGT6是STM…...
[STM32问题解决(2)]编译错误:Error: L6218E的深度解析与实战排查指南
1. 认识Error: L6218E编译错误 当你正在Keil MDK环境下开发STM32项目时,突然弹出一个红色错误提示:"Error: L6218E: Undefined symbol xxx (referred from xxx.o)",这可能是每个STM32开发者都会遇到的经典问题。我第一次遇到这个错…...
嵌入式开发者的效率利器:在VS Code里实时看到MISRA-C违规提示(含头文件路径配置避坑)
嵌入式开发实战:用VS Code打造MISRA-C实时检查工作流 每次保存代码后才发现MISRA-C违规有多痛苦?想象一下这样的场景:你正在编写一段关键的车载控制逻辑,反复调试后终于通过了编译,却在提交前的静态检查中被揪出二十多…...
从NTLM中继到域控接管:ADCS-ESC8漏洞实战解析
1. ADCS-ESC8漏洞概述 ADCS-ESC8是Active Directory证书服务(AD CS)中的一个高危漏洞,它允许攻击者通过NTLM中继攻击获取域控制器证书。这个漏洞的核心在于ADCS默认配置中的Web证书注册页面仅使用HTTP协议且支持NTLM认证,但未启用任何中继攻击防护措施。…...
