STM32-笔记12-实现SysTick模拟多线程流水灯

news/2024/12/28 19:52:05/
1、前言

        正常STM32实现多线程,需要移植一个操作系统FreeRTOS。但是在这里不移植FreeRTOS怎么实现多线程呢?使用SysTick,那么怎么使用SysTick来模拟多线程呢?前面我们知道SysTick就是一个定时器,它不是在主函数的while循环里实现的,就是在旁边自己玩自己的。所以我们可以理解成,main函数是主线程,而SysTick在一边实现自己的,在SysTick里面。可以通过配置让SysTick每一秒钟中断一次,在中断服务函数里面干其他的事情,这样就实现了多线程。

2、动手实现双线程

使用项目文件11-带操作系统的延时函数,复制,重命名为12-SysTick模拟多线程流水灯

打开文件,找到SysTick_Handler函数

在.s文件(只有一个.s文件)中找到SysTick_Handler

ctrl+f查找文件

 在主函数的HAL_Init();函数中

        可以看到HAL_IncTick();函数设置了一个1ms的中断,所以我们不需要配置额外的配置了,只需要在中断服务函数中做自己想要做的事就可以了。

        现在在主函数中,在流水灯中是每隔500ms换一次led1和led2的闪烁情况,现在我们换一下,让led1每隔1000ms闪烁一次,led2每隔500ms闪烁一次,主函数实现led2的闪烁情况,SysTick实现led1的闪烁情况。

主函数情况如下:

这里的定义和头文件都是为了方便才放到这里的

这样就实现了上述描述的实验

还可以都在HAL_IncTick();函数中实现,先把主函数中的实现给注释掉,具体代码如下:

3、遇到多线程

遇到很多条线程的时候,我们不可能每一条都那么写,会显得很冗余

在该目录文件下,新建文件夹tasks,和相应的.c .h文件

用来存放所有的线程,将文件加载进工程文件中

在.c文件中引入#include "tasks.h"

编译,搞出.h文件,打开.h文件

 编译->下载,运行结果一致

但是,没有完,接着做进一步的改装

        这是一个中断服务函数,现在只是点亮led灯不算复杂,未来我们要使用SysTick的时候不可以在这里很复杂的事情,不可以在这里延时很久的时间。

        让sysTick_isr();函数只起到一个计数的功能,并不在这个函数里面延时(现在点灯操作,还没有实现延迟),定义两个flag,用来标志是否达到指定的数目,如果达到,就在另一个线程函数中实现点灯(未来实现延迟功能)。

代码如下:

tasks.c

#include "tasks.h"
#include "led.h"uint32_t task1_cnt = 0; //定义一个变量用来计数
uint32_t task2_cnt = 0; //定义一个变量用来计数
uint8_t task1_flag = 0;
uint8_t task2_flag = 0;void sysTick_isr(void)
{if(task1_cnt <1000)task1_cnt++;else{task1_flag = 1;task1_cnt = 0;}if(task2_cnt <500)task2_cnt++;else{task2_flag = 1;task2_cnt = 0;}}
void task1(void)
{if(task1_flag == 0)return;task1_flag = 0;//置位led1_toggle();}
void task2(void)
{if(task2_flag == 0)return;task2_flag = 0;led2_toggle();}

tasks.h

#ifndef __TASKS_H__
#define __TASKS_H__#include "sys.h"void sysTick_isr(void);
void task1(void);
void task2(void);#endif

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "tasks.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */led_init();                         /* 初始化LED灯 */while(1){//一直在while循环中不断的重复执行task()函数//task()函数只有在满足对应条件的时候才会点灯,否则不点灯,白执行task1();task2();}
}

代码分析:

主函数不断在while中调用task1(); 和task2();函数,当task1(); 和task2();函数中,标志位满足相应的条件就会执行点灯操作,否则不满足不执行直接return返回,对于标志位的操作是看是否满足其数量,如果到指定数目,则标志位为1,否则依旧为0。


http://www.ppmy.cn/news/1558870.html

相关文章

ARM异常处理 M33

1. ARMv8-M异常类型及其详细解释 ARMv8-M Exception分为两类&#xff1a;预定义系统异常(015)和外部中断(1616N)。 各种异常的状态可以通过Status bit查看&#xff0c;获取更信息的异常原因&#xff1a; CFSR是由UFSR、BFSR和MMFSR组成&#xff1a; 下面列举HFSR、MMFSR、…

Spring 容器与配置类

1. 什么是 Spring 容器 首先&#xff0c;我们可以把 Spring 容器想象成一个大管家&#xff0c;这个大管家负责管理家里的各种物件&#xff08;也就是我们在应用程序中使用的对象&#xff0c;在 Spring 中叫 Bean&#xff09;。它知道每个物件放在哪里&#xff0c;也会帮你找到它…

【最后203篇系列】002 - 两个小坑(容器时间错误和kafka模块报错

这里两个小坑填了&#xff0c;希望有用。 1 Multiple conflicting time zone configurations found:\n/etc/timezone: Asia/Shanghai\n/etc/localtime is a symlink to: Etc/UTC\nFix the configuration, or set the time zone in a TZ environment variable. 我碰到这个错误…

Vue指令 和 指令修饰符

v-html v-show 和 v-if v-show 底层原理&#xff1a;切换 css 的 display:none 来控制显示隐藏 v-if 底层原理&#xff1a;根据判断条件 控制元素创建 和 移除 &#xff08;当为false 时&#xff0c;整个元素都隐藏起来了&#xff09; v-else 和 v-else-if v-on v-on:事件名 …

w~视觉~3D~合集5

我自己的原文哦~ https://blog.51cto.com/whaosoft/12898983 #Neural Sewing Machine (NSM) Neural Sewing Machine (NSM)&#xff0c;一种新颖的保持 3D 衣物结构的学习框架&#xff0c;可以有效表示多样化形状和拓扑结构的 3D 衣物&#xff0c;并应用于 3D 衣物表征&…

【Linux】Linux的基础工具

目录 1. 整体学习思维导图 2. 安装工具yum/apt 2.1 安装工具是什么&#xff1f; 2.2 理解安装的过程 3. Vim 编辑器的使用 3.1 vim的多模式 3.2 命令模式&#xff1a;快速编辑 3.3 替换模式 3.4 底行模式 3.5 视图模式 3.6 小技巧 4. gcc/g 5. 理解编译和库的基础…

当代体育科技杂志当代体育科技杂志社当代体育科技编辑部2024年第33期目录

运动人体科学 运动调控代谢综合征的机制研究 张征光;葛贝贝;陈英豪; 1-4 肥胖初中男生体力活动与静息能耗的计量关系 张卫东;乔云峰; 5-9 青少年乒乓球运动中肩部损伤的预防策略 张悦;王英建;黄春艳; 10-1293 运动训练学 青少年啦啦操专项体能训练策略研究 张爱…

IntelliJ Idea常用快捷键详解

文章目录 IntelliJ Idea常用快捷键详解一、引言二、文本编辑与导航1、文本编辑2、代码折叠与展开 三、运行和调试四、代码编辑1、代码补全 五、重构与优化1、重构 六、使用示例代码注释示例代码补全示例 七、总结 IntelliJ Idea常用快捷键详解 一、引言 在Java开发中&#xff…