任务的综合应用

news2025/4/16 11:05:09

需求

创建 4 个任务:TaskLED_1TaskLED_2TaskKEY_1TaskKEY_2

任务要求如下:

TaskLED_1:间隔 500ms 闪烁 LED1

TaskLED_2:间隔 1000ms 闪烁 LED2

TaskKEY_1:如果 taskLED1 存在,则按下 KEY1 后删除 taskLED1 ,否则创建 taskLED1 

TaskKEY_2:如果 taskLED2 正常运行,则按下 KEY2 后挂起 taskLED2 ,否则恢复 taskLED2

CubeMX

直接在上上节的“mjm_freeRTOS_credel_Task”的Cube文件中进行修改:

1. 再额外配置两个KEY的GPIO:

由原理图可知:按钮1按下对应PA0变低,按钮2按下对应PA1变低:

 2. 再额外增加两个任务:

Keil

在freertos.c中:

#include "stdio.h"

/* USER CODE END Header_StartTaskLED_1 */
void StartTaskLED_1(void const * argument)
{
  /* USER CODE BEGIN StartTaskLED_1 */
  /* Infinite loop */
  for(;;) //相当于一个while(1)
  {
		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);//翻转LED1的状态
    osDelay(500); //一个Cube封装的Delay函数,毫秒为单位
  }
  /* USER CODE END StartTaskLED_1 */
}

/* USER CODE BEGIN Header_StartTaskLED_2 */
/**
* @brief Function implementing the TaskLED_2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskLED_2 */
void StartTaskLED_2(void const * argument)
{
  /* USER CODE BEGIN StartTaskLED_2 */
  /* Infinite loop */
  for(;;)
  {
		HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);//翻转LED2的状态
    osDelay(1000);
  }
  /* USER CODE END StartTaskLED_2 */
}

/* USER CODE BEGIN Header_StartTaskKEY_1 */
/**
* @brief Function implementing the TaskKEY_1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskKEY_1 */
void StartTaskKEY_1(void const * argument)
{
  /* USER CODE BEGIN StartTaskKEY_1 */
  /* Infinite loop */
  for(;;)
  {
		if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){
			osDelay(20);
			if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){ //按键消抖
				printf("KEY1 has been pressed\r\n");
				if(TaskLED_1Handle != NULL){ //判断LED1任务是否存在,此处是NULL而不是pdPASS还是因为Cube自己的封装
					//如果任务存在
					printf("LED1_task detected\r\n");
					osThreadTerminate(TaskLED_1Handle); //则删除LED1任务,此处的osThreadTerminate也是Cube封装了vTaskDelete的函数
					TaskLED_1Handle = NULL;//这句不能忘
					if(TaskLED_1Handle == NULL){
						printf("LED1_task has been deleted\r\n");
					}
				}else{
					//如果任务不存在                                                                                  
					printf("LED1_task not detected\r\n");
					osThreadDef(TaskLED_1, StartTaskLED_1, osPriorityNormal, 0, 128); 
					TaskLED_1Handle = osThreadCreate(osThread(TaskLED_1), NULL);//则创建LED1任务,这两句话就照抄上面创建任务的语句就可以
					if(TaskLED_1Handle != NULL){
						printf("LED1_task has been created\r\n");			
					}
				}
			}
			while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET); //等待按键松开,防止出现按钮一直按着,就一直删除创建任务			
		}
		osDelay(10);
  }
  /* USER CODE END StartTaskKEY_1 */
}

/* USER CODE BEGIN Header_StartTaskKEY_2 */
/**
* @brief Function implementing the TaskKEY_2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskKEY_2 */
void StartTaskKEY_2(void const * argument)
{
  /* USER CODE BEGIN StartTaskKEY_2 */
	static int flag = 0; //每次创建
  /* Infinite loop */
  for(;;)
  {
    if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){
			osDelay(20);
			if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){ //按键消抖
				printf("KEY2 has been pressed\r\n");
				if(flag == 0){///判断LED2任务是否是运行态
					//如果是运行态
					printf("LED2_task is now running\r\n");
					osThreadSuspend(TaskLED_2Handle);//将LED2任务挂起,使其进入挂起态,osThreadSuspend也是Cube对vTaskSuspend()函数的封装
					printf("LED2_task has been suspended\r\n");
					flag = 1; //flag为1表示任务被挂起
				}else{
					//如果是挂起态
					printf("LED2_task is now suspended\r\n");
					osThreadResume(TaskLED_2Handle);//将LED2任务恢复,使其进重新进入运行态,osThreadResume也是Cube对xTaskResume()函数的封装
					printf("LED2_task has been resumed\r\n");
					flag = 0; //flag为1表示任务正在运行
				}		
			}
			while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET); //等待按键松开,防止出现按钮一直按着,就一直挂起恢复任务			
		}
		osDelay(10);
	}
  /* USER CODE END StartTaskKEY_2 */
}

实现效果

1. 首先可以看到LED1和LED2和上上节一样以不同的频率同时闪烁

2. 打开串口助手,并按下KEY1:

此时LED1任务被删除,只有黄色的LED2灯在闪烁

3. 再按一下KEY1:

此时LED1任务被重新创建,两盏LED灯又开始一起不同频率闪烁

4. 按一下KEY2:

 

 此时LED2任务被挂起,蓝色的LED1灯在闪烁,而黄色的LED2灯会保持在按键按下时的状态

5. 再按一下KEY2:

 

此时LED2任务恢复运行,两盏LED灯又开始一起不同频率闪烁

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows10强制删除文件或文件夹内容

一、需求描述 我们的Windows电脑中,会存在一些特殊的应用场景比如【(文件、文件夹)被读写保护、隐藏、或被程序一直占用、被感染了病毒】导致无法删除;此时候就需要采取强制删除的方式解决。 二、需求分析 文件、文件夹被占用,无法正常删除;但是有需要强制删除。 三、解…

安全攻击 --- XSS攻击

XSS跨站脚本攻击 (1)简介 OWASP TOP 10 之一,XSS被称为跨站脚本攻击(Cross-Site-Scripting)主要基于JavaScript(JS)完成攻击行为XSS通过精心构造JS代码注入到网页中,并由浏览器解释…

生态合作丨MemFireDB通过麒麟软件NeoCertify认证

近日,敏博科技“MemFireDB分布式关系数据库系统V2.8”与麒麟软件“银河麒麟高级服务器操作系统V10” 完成兼容性测试,获得麒麟软件 NeoCertify 认证证书。测试结果显示,MemFireDB数据库在国产操作系统上运行稳定,产品已经达到通用…

曲线拟合曲面拟合(MATLAB拟合工具箱)前馈量计算(压力闭环控制应用)

利用PLC进行压力闭环控制的项目背景介绍请查看下面文章链接,这里不再赘述。 信捷PLC压力闭环控制应用(C语言完整PD、PID源代码)_RXXW_Dor的博客-CSDN博客闭环控制的系列文章,可以查看PID专栏的的系列文章,链接如下:张力控制之速度闭环(速度前馈量计算)_RXXW_Dor的博客-CSD…

Windows下Python调用海康SDK实时显示网络摄像头

参考资源: 1.《Windows下Python调用海康SDK实时显示网络摄像头》 2.《HikVision SDK: C 至 Python》 3.《linux下Python调用海康SDK实时显示网络摄像头》 4.《python调用海康sdk操作热成像设备获取对应点温度》 5.《Windows下Python调用海康SDK实时视频流获取》 6.《…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)六:后台主页功能实现下

一、本章内容 接上一章,继续实现后端主页内容,主要实现工具栏对应相关内容的实现,包括系统消息、系统公告、全屏切换、语言切换、主题切换等。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 基于VUE3+Layui从头搭建通用后台管理系统合集…

(五)RabbitMQ-进阶 死信队列、延迟队列、防丢失机制

Lison <dreamlison163.com>, v1.0.0, 2023.06.23 RabbitMQ-进阶 死信队列、延迟队列、防丢失机制 文章目录 RabbitMQ-进阶 死信队列、延迟队列、防丢失机制死信队列延迟队列延迟队列介绍**延迟队列_死信队列_的实现**延迟队列_插件实现下载插件RabbitMQ 配置类RabbitMQ …

知网的caj格式怎么转化成pdf格式?两个方法简单快捷!

在使用知网等学术资源时&#xff0c;我们常常会遇到CAJ格式的文件&#xff0c;然而CAJ格式并不是常见的文件格式&#xff0c;给我们的查阅和分享带来一些不便。为了更方便地处理这些文件&#xff0c;我们可以将其转换为常见的PDF格式。在本文中&#xff0c;我将为您介绍两种简单…

Docker——网络原理

Docker——网络 一、Docker 网络1&#xff0e;Docker 网络实现原理2&#xff0e;Docker 的网络模式 二、网络模式详解1&#xff0e;host模式2&#xff0e;container模式3&#xff0e;none模式4&#xff0e;bridge模式5&#xff0e;自定义网络 三、资源控制1&#xff0e;CPU 资源…

做测开的3年总结

大家好&#xff0c;我是洋子 进入测试行业刚满3年了&#xff0c;毕业北漂也满3年了&#xff0c;回顾一下这3年的工作和生活 下面文章我将会从QA这个岗位的角度复盘一下这3年来的所思所想&#xff0c;有刚入行的小伙伴可能不太清楚QA&#xff08;Quality Assurance&#xff09…

【RabbitMQ】之高可用集群搭建

目录 一、RabbitMQ 集群原理 1、默认集群原理2、镜像集群原理3、负载均衡方案 二、RabbitMQ 高可用集群搭建 1、RabbitMQ 集群搭建2、配置镜像队列3、HAProxy 环境搭建4、Keepalived 环境搭建 一、RabbitMQ 集群简介 1、默认集群原理 3-1、RabbitMQ 集群简介 单台 RabbitM…

第二招牌——创造企业结构性增长的有效战略工具

在现代商业环境中&#xff0c;企业面临着激烈的竞争和不断变化的市场条件。为了在这个竞争激烈的环境中生存和持续发展&#xff0c;企业必须不断寻求创新和增长的机会。这就需要企业创造结构性增长&#xff0c;不仅仅是依靠传统的业务模式和产品线&#xff0c;还要不断的拓展新…

elasticsearch报错问题

标题1.报错问题 标题2.新建一个配置类 package cn.itcast.hotel.config;import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import o…

SecureCRT如何将复制的内容粘贴到word中仍然保持原有字体颜色

SecureCRT如何将复制的内容粘贴到word中仍然保持原有字体颜色 QQ 109792317 说明&#xff1a;当SecureCRT加载了配色文件后&#xff0c;输出的关键字会被不同颜色高亮显示&#xff0c;但是如果复制粘贴到word中会发现成了纯文本&#xff0c;字体颜色消失了。 如何保留 &#x…

真空压力控制技术在三轴仪土壤制样、力学和渗透性能测试中的应用

摘要&#xff1a;在当前的各种三轴测试仪中&#xff0c;对月壤和月壤模拟物的样品制备和力学性能测试还无法实现样品的真空制备、测试过程中的可变围压控制和样品的超真空度准确控制。为此本文提出了实现这些功能的解决方案&#xff0c;解决方案采用不同气体流量控制技术以及特…

npm i babel-plugin-import -D之后报错

替换modules/.bin/XX文件 1.vue-cli-service #!/bin/sh basedir$(dirname "$(echo "$0" | sed -e s,\\,/,g)")case uname in*CYGWIN*) basedircygpath -w "$basedir";; esacif [ -x "$basedir/node" ]; then"$basedir/node"…

Cilium系列-4-Cilium本地路由

系列文章 Cilium 系列文章 前言 在前文中我们提到, cilium install 默认安装后, Cilium 功能启用和禁用情况如下: datapath mode: tunnel: 因为兼容性原因&#xff0c;Cilium 会默认启用 tunnel&#xff08;基于 vxlan) 的 datapatch 模式&#xff0c;也就是 overlay 网络结…

【主成分分析(PCA)】

主成分分析&#xff08;PCA&#xff09; 摘要 在现代数据科学中&#xff0c;维度灾难常常是数据处理与分析的一大难题。主成分分析&#xff08;PCA&#xff09;是一种广泛使用的数据降维技术&#xff0c;它通过将原始数据转换为新的低维空间&#xff0c;保留最重要的信息&…

【docker】docker部署tomcat

目录 1.1 搜索tomcat镜像1.2 拉取tomcat镜像1.3 创建容器&#xff0c;设置端口映射、目录映射1.4 测试 1.1 搜索tomcat镜像 docker search tomcat1.2 拉取tomcat镜像 docker pull tomcat1.3 创建容器&#xff0c;设置端口映射、目录映射 # 在/root目录下创建tomcat目录用于存…

网络:TCP/IP协议

1. OSI七层参考模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 2. TCP/IP模型 应用层 传输层 网络层 数据链路层 物理层 3. 各链路层对应的名称 应用层对应的是协议数据单元 传输层对应的是数据段 网络层对应的是数据包 链路层对应的是数据帧 物理层对应的是比特…