【STM32】利用CubeMX对FreeRTOS用按键控制任务

对于FreeRTOS中的操作,最常用的就是创建、删除、暂停和恢复任务。

此次实验目标:

1.创建任务一:LED1每间隔1秒闪烁一次,并通过串口打印

2.创建任务二:LED2每间隔0.5秒闪烁一次,并通过串口打印

3.创建任务三:通过KEY1实现对任务一的创建和删除。

按键按下以后如果有任务一就删除任务一,没有任务一就创建任务一。

4. 创建任务四:通过KEY2实现对任务二的暂停和恢复。

按键按下以后如果任务二在执行就暂停任务二,任务二在暂停就恢复任务二。

实现方式:

使用正点原子探索者,主控芯片为STM32F407ZGT6。

一、主要的电气原理图如下:

 

二、CubeMX配置

1.设置FreeRTOS

2.设置usart1

波特率115200

3.设置时钟,选择外部高速时钟

配置时钟树如下

4.注意一定要修改时基

5.生成代码

三、编写代码(都在freertos.c中写)

1.串口重定向

#include <stdio.h>// 包含标准输入输出头文件
 
int fputc(int ch,FILE *f)
{
//采用轮询方式发送1字节数据,超时时间设置为无限等待
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch;
// 采用轮询方式接收 1字节数据,超时时间设置为无限等待
HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
return ch;
}

2.实现任务的代码

void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of LED1 */
  osThreadDef(LED1, led1, osPriorityNormal, 0, 128);
  LED1Handle = osThreadCreate(osThread(LED1), NULL);

  /* definition and creation of LED2 */
  osThreadDef(LED2, led2, osPriorityIdle, 0, 128);
  LED2Handle = osThreadCreate(osThread(LED2), NULL);

  /* definition and creation of KEY1 */
  osThreadDef(KEY1, key1, osPriorityIdle, 0, 128);
  KEY1Handle = osThreadCreate(osThread(KEY1), NULL);

  /* definition and creation of KEY2 */
  osThreadDef(KEY2, key2, osPriorityIdle, 0, 128);
  KEY2Handle = osThreadCreate(osThread(KEY2), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}

/* USER CODE BEGIN Header_led1 */
/**
  * @brief  Function implementing the LED1 thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_led1 */
void led1(void const * argument)
{
  /* USER CODE BEGIN led1 */
  /* Infinite loop */
  for(;;)
  {
		printf("led1\n\r");
		HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
    osDelay(1000);
  }
  /* USER CODE END led1 */
}

/* USER CODE BEGIN Header_led2 */
/**
* @brief Function implementing the LED2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_led2 */
void led2(void const * argument)
{
  /* USER CODE BEGIN led2 */
  /* Infinite loop */
  for(;;)
  {
    printf("led2\n\r");
		HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
    osDelay(500);
  }
  /* USER CODE END led2 */
}

/* USER CODE BEGIN Header_key1 */
/**
* @brief Function implementing the KEY1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_key1 */
void key1(void const * argument)
{
  /* USER CODE BEGIN key1 */
  /* Infinite loop */
  for(;;)
  {
    if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4)==0)
		{
			osDelay(20);//防误触
			if(LED1Handle==NULL)
			{
				printf("key1==creat\n\r");
				osThreadDef(LED1, led1, osPriorityNormal, 0, 128);
				LED1Handle = osThreadCreate(osThread(LED1), (void*)"new task1");
				
			}
			else
			{
				vTaskDelete(LED1Handle);
				LED1Handle=NULL;
				printf("key1==delete\n\r");
			}
		}
  }
  /* USER CODE END key1 */
}

/* USER CODE BEGIN Header_key2 */
/**
* @brief Function implementing the KEY2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_key2 */
void key2(void const * argument)
{
  /* USER CODE BEGIN key2 */
	char Flag=0;
  /* Infinite loop */
  for(;;)
  {
    if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0)
		{
			osDelay(20);//防误触
			if(Flag==0)
			{
				printf("key2 suspend\n\r");
				vTaskSuspend(LED2Handle);
				Flag=1;
			}
			else
			{
				vTaskResume(LED2Handle);
				printf("key2  resume \n\r");
				Flag=0;
			}
		}
  }
  /* USER CODE END key2 */
}

/* Private application code --------------------------------------------------*/

注意:任务被删除时,句柄不会删除,需要手动清空。

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

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

相关文章

阿里云FRP内网穿透挂载多台服务器

1. FRP介绍 FRP (Fast Reverse Proxy) 是比较流行的一款。FRP 是一个免费开源的用于内网穿透的反向代理应用&#xff0c;它支持 TCP、UDP 协议&#xff0c; 也为 http 和 https 协议提供了额外的支持。你可以粗略理解它是一个中转站&#xff0c; 帮你实现 公网 ←→ FRP(服务器…

Office doc training

1. Wordy文档: step 1.1 格式刷&#xff0c;字体(大小,下划线,背景色,字体颜色)&#xff0c;排版(对齐方式,标题,序号,行距离) step 1.2 插入表格&#xff0c;表格单元格的CRUD 操作例子: 2. Excel: step 2.1: 单元格格式( 文本&#xff0c;数值&#xff0c;边框&#xff0c;…

MySQL卸载并重装指定版本

MySQL卸载并重装制定版本 学习新的项目&#xff0c;发现之前的Navicat已经失去了与现有MySQL的链接&#xff0c;而且版本也不适合&#xff0c;为了少走弯路&#xff0c;准备直接重装相应版本的MySQL 卸载现有MySQL 停止windows的MySQL服务&#xff0c;【windowsR】打开运行框…

SpringBoot请求响应

简单参数 1. 原始方式获取请求参数 Controller方法形参中声明httpServletRequest对象 调用对象的getParameter参数名 RestController public class RequestController {RequestMapping("/simpleParam")public String simpleParam(HttpServletRequest request){Strin…

SpringBoot概述及项目的创建使用

文章目录 一. Spring Boot概述1. 什么是Spring Boot&#xff1f;2. Spring Boot的优点 二. Spring Boot项目的创建1. 使用IDEA创建1.1. 准备工作1.2. 创建运行Spring Boot项目1.3. 进行Web交互1.4. 目录工程介绍1.5. 项目快速添加依赖1.6. 防止配置文件乱码所需的配置1.7. Spri…

Arcgis中POI找到建筑面内距离最近的标准地址通过模型构建器来实现

背景 之前写过一篇文章 Arcgis通过矢量建筑面找到POI对应的标准地址 这里面的大致思路跟本篇文章是类似的&#xff0c;不过上一篇文章有部分有瑕疵&#xff0c;就是在POI去找建筑面内的标准地址时&#xff0c;找到的虽然是建筑面内的&#xff0c;但是不一定是距离最近的&#…

C#__事件event的简单使用:工具人下楼问题

// 工具人类 namespace DownStair {delegate void DownStairDelegate(); // 定义了一个下楼委托class ToolMan{public string Name { get; set; } // 声明工具人的名字属性// public DownStairDelegate downStairDelegate null; // 初始化委托downStair为空委托// 解决方案pu…

【BASH】回顾与知识点梳理(二十七)

【BASH】回顾与知识点梳理 二十七 二十七. 磁盘配额(Quota)27.1 磁盘配额 (Quota) 的应用与实作什么是 QuotaQuota 的一般用途Quota 的使用限制Quota 的规范设定项目 27.2 一个 XFS 文件系统的 Quota 实作范例实作 Quota 流程&#xff1a;设定账号实作 Quota 流程-1&#xff1a…

iTOP-i.MX8M开发板添加USB网络设备驱动

选中支持 USB 网络设备驱动&#xff0c;如下图所示&#xff1a; [*] Device Drivers→ *- Network device support → USB Network Adapters→ {*} Multi-purpose USB Networking Framework 将光标移动到 save 保存&#xff0c;如下图所示&#xff1a; 保存到 arch/arm64/c…

springboot工程集成前端编译包,用于uni-app webView工程,解决其需独立部署带来的麻烦,场景如页面->画布->图片->pdf

前端工程 访问方式 http://127.0.0.1:8080/context/frontEnd/index放行 public class SecurityConfig extends WebSecurityConfigurerAdapter { "/frontEnd/**",SysFrontEndController import lombok.extern.slf4j.Slf4j; import nl.basjes.shaded.org.springfram…

Sentinel使用实例

不说了&#xff0c;直接上官方文档 https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md Sentinel Example 项目说明 本项目演示如何使用 Sentinel starter 完成 Spring Clo…

试岗第一天问题

1、公司的一个项目拉下来 &#xff0c;npm i 不管用显示 后面百度 使用了一个方法 虽然解决 但是在增加别的依赖不行&#xff0c;后面发现是node版本过高&#xff0c;更换node版本解决。 2、使用插件动态的使数字从0到100&#xff08;vue-animate-number插件&#xff09; 第一…

C++ 继承

1.继承的概念及定义 定义 定义格式 继承关系和访问限定符 继承基类成员访问方式的变化 1. 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是 被继承到了派生类对象中&#xff0c;但是语法上限制派生类对象不管在类里面还是类外面…

JavaFx基础学习【四】:UI控件的通用属性

目录 前言 一、介绍 二、继承关系 三、常用通用属性 四、属性Properties 五、属性绑定 六、属性监听 七、事件驱动 八、其他章节 前言 如果你还没有看过前面的文章&#xff0c;可以通过以下链接快速前往学习&#xff1a; JavaFx基础学习【一】&#xff1a;基本认识_明…

探讨uniapp的生命周期问题

在uniapp中,生命周期函数分为应用生命周期函数、页面生命周期函数和组件生命周期函数. 1应用声明周期 应用生命周期函数只能在 App.vue 中监听有效&#xff0c;在其他页监听无效。 onLaunch&#xff1a;当uni-app 初始化完成时触发&#xff08;全局只触发一次&#xff09;on…

Jmeter性能测试系列-性能测试需求分析

性能测试需求分析 性能测试需求分析与传统的功能测试需求有所不同&#xff0c;功能测试需求分析重点在于从用户层面分析被测对象的功能性、易用性等质量特性&#xff0c;性能测试则需要从终端用户应用、系统架构设计、硬件配置等多个纬度分析系统可能存在性能瓶颈的业务。 性…

线上售楼vr全景看房成为企业数字化营销工具

在房地产业中&#xff0c;VR全景拍摄为买家提供了虚拟看房的全新体验。买家可以通过相关设备&#xff0c;远程参观各个楼盘的样板间和实景&#xff0c;感受房屋的空间布局和环境氛围&#xff0c;极大地提高了购房决策的准确性。对于房地产开发商和中介机构来说&#xff0c;VR全…

在不破坏原有隔离状态的情况下,怎么实现网间数据安全摆渡?

随着网络技术的演进&#xff0c;网络攻击、数据窃取、数据泄露事件也愈发频繁&#xff0c;给企业造成损失和负面影响&#xff0c;企业数据防泄漏治理是大趋势&#xff0c;也是自身迫切需求。 2021年1月&#xff0c;中国农业银行因存在数据泄露风险、互联网门户网站泄露敏感信息…

《起风了》C++源代码

使用方法 Visual Studio、Dev-C、Visual Studio Code等C/C创建一个 .cpp 文件&#xff0c;直接粘贴赋值即可。 #include <iostream> #include <Windows.h> #pragma comment(lib,"winmm.lib") using namespace std; enum Scale {Rest 0, C8 108, B7 …

分布式 - 服务器Nginx:一小时入门系列之代理缓冲与缓存

官方文档&#xff1a;https://nginx.org/en/docs/http/ngx_http_proxy_module.html 1. 代理缓冲 proxy_buffer 代理缓冲用于临时存储从后端服务器返回的响应数据。通过使用代理缓冲&#xff0c;Nginx可以在接收完整的响应后再将其发送给客户端&#xff0c;从而提高性能和效率…