在没有接触到FreeRTOS时,也没有想过同时叫两个或两个以上的led灯闪烁的想法,接触后,发现如果想叫两个灯同时以不同的频率闪烁,不能说是不可能,就算是做到了也要非常的麻烦。但是学习了FreeRTOS后,发现要想同时执行几个函数还是很简单的一件事,虽然CPU是单核心的,这就好比是电脑编程中的多线程,这个函数执行1毫秒,那个函数执行1毫秒,就这样不停地切换,由于切换的速度相当的快,给人的感觉就是这几个函数在同时执行。我们编程中难免会遇到这种需要同时运行的函数,所以学习一下FreeRTOS还是很有必要的。
好了,说了这么多,把我今天的结果展示一下吧:
图片中的A0到A3端口的led灯在以不同的频率闪烁。
下面把代码贴出来看看吧:
main.c文件:
#include "stm32f10x.h" // Device header
#include "led.h"
#include "freertos.h"
#include "task.h"
void Mytask0( void * arg) //任务0函数
{
while(1) //所干的事就是死循环
{
FANZHUAN0; //翻转A0端口电平
vTaskDelay(40); //延时40毫秒
} //整个函数就是控制A0端口的led灯以40毫秒的间隔不停的闪烁
}
void Mytask1( void * arg) //任务1函数
{
while(1)
{
FANZHUAN1;
vTaskDelay(140);
} // 整个函数就是控制A1端口的led灯以140毫秒的间隔不停的闪烁
}
void Mytask2( void * arg) //任务2函数
{
while(1)
{
FANZHUAN2;
vTaskDelay(400);
} // 整个函数就是控制A2端口的led灯以400毫秒的间隔不停的闪烁
}
void Mytask3( void * arg) //任务3函数
{
while(1)
{
FANZHUAN3;
vTaskDelay(800);
} // 整个函数就是控制A3端口的led灯以800毫秒的间隔不停的闪烁
}
TaskHandle_t TaskHandle_t0; //创建任务0所需要的任务句柄变量
TaskHandle_t TaskHandle_t1; //创建任务1所需要的任务句柄变量
TaskHandle_t TaskHandle_t2; //创建任务2所需要的任务句柄变量
TaskHandle_t TaskHandle_t3; //创建任务3所需要的任务句柄变量
int main(void)
{
LED_Init(); //初始化led配置
xTaskCreate(Mytask0, "Mytask0", 120, NULL, 1, &TaskHandle_t0); //创建任务0(任务0函数名, 任务字符串, 堆栈大小随便,任务参数, 优先级, 任务句柄地址)
xTaskCreate(Mytask1, "Mytask1", 120, NULL, 2, &TaskHandle_t1); //创建任务1(任务0函数名, 任务字符串, 堆栈大小随便,任务参数, 优先级, 任务句柄地址)
xTaskCreate(Mytask2, "Mytask2", 120, NULL, 3, &TaskHandle_t2); //创建任务2(任务0函数名, 任务字符串, 堆栈大小随便,任务参数, 优先级, 任务句柄地址)
xTaskCreate(Mytask3, "Mytask3", 120, NULL, 4, &TaskHandle_t3); //创建任务3(任务0函数名, 任务字符串, 堆栈大小随便,任务参数, 优先级, 任务句柄地址)
vTaskStartScheduler(); //开启调度器
}
led.h文件:
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h" // Device header
#define GPIOx GPIOA
#define GPIO_PIN GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
#define GPIO_CLK RCC_APB2Periph_GPIOA
#define ON 1
#define OFF 0
#define LED(x) if(x)\
GPIO_ResetBits(GPIOx, GPIO_PIN);\
else \
GPIO_SetBits(GPIOx, GPIO_PIN);
#define FANZHUAN0 {GPIOx->ODR ^= GPIO_Pin_0;}
#define FANZHUAN1 {GPIOx->ODR ^= GPIO_Pin_1;}
#define FANZHUAN2 {GPIOx->ODR ^= GPIO_Pin_2;}
#define FANZHUAN3 {GPIOx->ODR ^= GPIO_Pin_3;}
void LED_Init(void);
#endif
led.c文件:
#include "led.h" // Device header
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(GPIO_CLK, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOx, &GPIO_InitStruct);
}
FreeRTOS的代码,太多了,我就不都贴出来了,前面我写过一篇这样的文章,不懂的可以往前自己找找。这个工程创建好了,就不用每次都创建了,每次赋值粘贴重命名就好了,还是很省事的啊!