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

单片机:实现多任务处理(附带源码)

单片机实现多任务处理

多任务处理是现代操作系统的重要特性,通常通过多线程、多进程的方式来并行执行多个任务。在嵌入式系统中,由于资源有限,通常通过时间片轮转或中断机制来模拟多任务处理。本项目将展示如何在8051单片机上实现简单的多任务处理。

在8051单片机中,真正的多任务处理(如操作系统中的多线程)并不常见,因为8051单片机资源有限(内存小、没有硬件支持的线程管理)。但我们可以通过使用定时器中断和轮询机制,模拟多任务处理的功能。

一、项目需求

  1. 任务切换:模拟多任务处理,能够在多个任务之间切换。
  2. 定时器中断:使用定时器中断模拟任务调度。
  3. 任务执行:执行多个不同的任务,例如LED闪烁、按键扫描、数码管显示等。

二、系统设计

2.1 多任务模拟

我们通过使用定时器中断来定期触发任务切换。在8051中,定时器中断通常是最合适的机制来模拟任务调度,因为它允许我们在多个任务之间“轮流”执行,类似于操作系统中的时间片轮转。

2.2 任务设计

我们将设计两个简单的任务:

  • 任务1:LED灯闪烁任务,每秒钟切换一次LED状态。
  • 任务2:按键扫描任务,用于检查按键是否按下,并切换LED的状态。
2.3 任务调度

我们通过一个全局的计时器变量来模拟“任务切换”的概念,每当定时器溢出时,增加一个计数值,根据计数值来决定当前执行哪个任务。

三、硬件设计

  1. 单片机:使用8051单片机(如AT89C51)。
  2. LED灯:用于显示任务执行状态。
  3. 按键:用于输入,控制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) {// 主要任务通过定时器中断执行,不需要在这里处理}
}

五、程序说明

  1. 定时器初始化

    • 使用8051的定时器0,配置为模式1(16位定时器),每10ms触发一次中断。在定时器中断服务程序中,我们通过增加一个计数器来决定当前应该执行哪个任务。
  2. 任务1(LED闪烁任务)

    • 每次执行任务1时,我们切换LED的状态(开关状态)。
  3. 任务2(按键扫描任务)

    • 任务2用来扫描按键状态,如果按键被按下,LED灯会点亮。
  4. 任务调度

    • 每当定时器中断发生时,task_counter增加1。根据task_counter的值,我们选择执行任务1或任务2,实现任务的切换。
    • 每次任务切换时,都会根据task_counter的奇偶性来判断当前执行哪个任务,模拟了一个简单的轮转调度。
  5. 按键去抖动

    • 使用delay_ms函数对按键进行去抖动处理,避免因为按键的抖动导致误判。

六、总结

通过本项目,我们在8051单片机上实现了简单的多任务处理。虽然8051单片机本身不支持多任务处理,但我们可以通过定时器中断和计数器来模拟任务切换,达到并行执行多个任务的效果。我们使用定时器模拟时间片轮转,并通过LED灯和按键扫描实现了两个简单的任务。

这种多任务处理的方法适用于资源有限、对实时性要求较高的嵌入式系统。虽然其功能相对简单,但足以满足一些嵌入式应用的需求,例如控制LED灯、扫描按键等。

在实际的项目中,如果系统需要处理更多的任务,可以通过增加定时器中断的频率或调整任务调度算法来进一步优化系统的多任务处理能力。

相关文章:

单片机:实现多任务处理(附带源码)

单片机实现多任务处理 多任务处理是现代操作系统的重要特性&#xff0c;通常通过多线程、多进程的方式来并行执行多个任务。在嵌入式系统中&#xff0c;由于资源有限&#xff0c;通常通过时间片轮转或中断机制来模拟多任务处理。本项目将展示如何在8051单片机上实现简单的多任…...

负载均衡oj项目:介绍

目录 项目介绍 项目演示 项目介绍 负载均衡oj是一个基于bs模式的项目。 用户使用浏览器向oj模块提交代码&#xff0c;oj模块会在所有在线的后端主机中选择一个负载情况最低的主机&#xff0c;将用户的代码提交给该主机&#xff0c;该主机进行编译运行&#xff0c;将结果返回…...

剑指Offer 03比特位计数

只是记录 题目链接 题目链接 自己想出来的 第一种解法 思路简述 遍历[0,n]之间的数字&#xff0c;对于每一个数字按照二进制的方式展开&#xff0c;判断最低位置是否为1&#xff0c;若为1则1&#xff0c;反之不加&#xff0c;直到该数字等于0就停止。 public static int[] …...

多音轨视频使用FFmpeg删除不要音轨方法

近期给孩子找宫崎骏动画&#xff0c;但是有很多是多音轨视频但是默认的都是日语&#xff0c;电视上看没办法所以只能下载后删除音轨文件只保留中文。 方法分两步&#xff0c;先安装FFmpeg在转文件即可。 第一步FFmpeg安装 FFmpeg是一个开源项目&#xff0c;包含了处理视频的…...

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:软件保护与安全的全面解决方案

在当今数字化时代&#xff0c;软件的安全性和保密性愈发重要。VMProtect 作为一款备受瞩目的软件保护工具&#xff0c;因其强大的功能和广泛的应用而成为开发者保护软件的首选方案。 VMProtect 是一款新一代的软件保护实用程序&#xff0c;支持多个编译器平台&#xff0c;包括…...

Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:教室信息管理系统(前后端源码 + 数据库 sql 脚本)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 1.0 项目介绍 开发工具&#xff1a;IDEA、VScode 服务器&#xff1a;Tomcat&#xff0c; JDK 17 项目构建&#xff1a;maven 数据库&#xff1a;mysql 8.0 系统用户前台和管理…...

第十二篇:linux下socket本地套接字通讯

使用套接字除了可以实现网络间不同主机间的通信外&#xff0c;还可以实现同一主机的不同进程间的通信&#xff0c;且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口&#xff0c;只是地址结构与某些参数不同。 用途 进程间通信&#xff1a;本地套…...

Spring Boot 2.1.7 数据源自动加载过程详解

在 Spring Boot 中&#xff0c;数据源的自动配置是框架中一个关键功能&#xff0c;本文将以 Spring Boot 2.1.7 版本为例&#xff0c;详细讲解在单数据源情况下数据源是如何自动加载的。我们通过源码分析&#xff0c;追踪整个加载流程。 1. 自动配置类的发现 Spring Boot 使用…...

【Vue.js 3.0】provide 、inject 函数详解

在 Vue 3 中&#xff0c;provide 和 inject 是用于跨组件层次结构进行依赖注入的一对 API。这些 API 主要用于祖先组件和后代组件之间的数据传递&#xff0c;尤其是当这些组件之间没有直接的父子关系时。 1. 示例 1.1 provide provide 函数用于在祖先组件中定义一个值&#…...

JVM(Java虚拟机)的虚拟机栈

JVM&#xff08;Java虚拟机&#xff09;的虚拟机栈是Java程序运行时的重要组件&#xff0c;以下是对其的详细解析&#xff1a; 一、概念与功能 概念&#xff1a;虚拟机栈也称为Java栈&#xff0c;是JVM为每个线程分配的一个私有的内存区域。每个线程在创建时都会创建一个虚拟…...

Elasticsearch02-安装7.x

零、文章目录 Elasticsearch02-安装7.x 1、Windows安装Elasticsearch &#xff08;1&#xff09;JDK安装 Elasticsearch是基于java开发的&#xff0c;所以需要安装JDK。我们安装的Elasticsearch版本是7.15&#xff0c;对应JDK至少1.8版本以上。也可以不安装jdk&#xff0c;…...

iPhone恢复技巧:如何从 iPhone 恢复丢失的照片

在计算机时代&#xff0c;我们依靠手机来捕捉和存储珍贵的回忆。但是&#xff0c;如果您不小心删除或丢失了手机上的照片怎么办&#xff1f;这真的很令人沮丧和烦恼&#xff0c;不是吗&#xff1f;好吧&#xff0c;如果您在 iPhone 上丢失了照片&#xff0c;您不必担心&#xf…...

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之后数据如何交互

前言 欢迎来到第二篇文章&#xff0c;这也是第二个难题&#xff0c;就是原有的移动端本身一些页面H5的形式去呈现&#xff08;webview&#xff09;&#xff0c;例如某些需要动态更换内容的页面&#xff0c;某些活动页面、支付页面&#xff0c;不仅仅做页面呈现&#xff0c;还包…...

【C语言的奥秘11】指针知识点总结(续)

目录 一、指针的运算 1、指针与整数相加减 2、指针-指针&#xff08;地址-地址&#xff09; 3、指针的关系运算 六、指针和数组 七、二级指针 八、指针数组 一、指针的运算 1、指针与整数相加减 看一下下面的代码&#xff1a; #include<stdio.h> int my_strlen(c…...

excel 列名是数据表 的字段名 ,单元格的值 是数据表对应字段的值,生成sql插入语句

在 Excel 中&#xff0c;按 Alt F11 打开 VBA 编辑器。在菜单栏选择 插入 -> 模块&#xff0c;在新模块中粘贴以下代码。 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新时代&#xff1f; 随着Web3与区块链技术的迅速发展&#xff0c;AI Agent作为人工智能与区块链的交汇点&#xff0c;正在逐步成为推动去中心化生态的重要力量。同时&#xff0c;MEME文化凭借其强大的社区驱动力和文化渗透力&#xff0c;在链上生态中扮演着…...

IO的入门

目录 1.IO概述1.1流的分类 2.字符流2.1 案例 1.IO概述 IO&#xff08;Input/Output&#xff09;:输入和输出&#xff0c;指的是某个设备或环境进行数据的输入或者输出。例如&#xff1a;键盘的输入&#xff0c;再比如显示器就是输出设备&#xff0c;输出图像。 对于java来说输…...

构建一个rust生产应用读书笔记四(实战1)

我们需要从访客那里收集哪些信息&#xff0c;以便将其登记为电子邮件通讯的订阅者&#xff1f; 电子邮件地址&#xff1a;这是最基本的要求&#xff0c;因为我们需要通过电子邮件地址向订阅者发送内容。姓名&#xff1a;虽然这不是强制性的&#xff0c;但我们希望收集一个名字…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...