FreeRTOS(一)LED与按键扫描

最近接触了FreeRTOS,基本看完FreeRTOS的语法知识点,终于可以动手实践了。第一篇,先实现 LED与按键扫描的移植。

功能:LED1周期性闪烁(300ms),LED0在按键按下后改变亮灭状态一次。
平台:STM32F767IGT6

PART1: main.c —— 调用系统初始化、任务创建、开启任务调度

#include "mytask.h"
#include "init.h"

TaskHandle_t LED_TaskHandler;
TaskHandle_t KEY_TaskHandler;

int main()
{

	//系统初始化
	SYS_Init();
	
	//创建任务LED_Task, 是一个死循环的函数
	//名称 LED_Task, 任意名称都可以,调试是方便知道函数名
	//分配内存 256 Words, 注意单位不是 Byte
	//传入LED_Task() 函数的参数,此处为 0, 
	//优先级 1, 优先级从低到高,同等情况下优先级越高越先执行
	//任务句柄 LED_TaskHandler,用于任务删除、挂起等
	
	xTaskCreate(LED_Task, "LED_Task", 256, (void*)0, 1, &LED_TaskHandler);
	
	//创建任务KEY_Task, 名称 KEY_Task, 分配内存 256Word,传入参数 空,优先级 2,任务句柄 KEY_TaskHandler
	xTaskCreate(KEY_Task, "KEY_Task", 256, NULL,     2, &KEY_TaskHandler);
	
	//开始任务调度
	vTaskStartScheduler();
}

PART2:init.h 与 init.c —— 实现IO口、时钟等初始化
init.h

#ifndef _INIT_H
#define _INIT_H

#include "sys.h"

#define LED_PIN   			GPIO_PIN_0 | GPIO_PIN_1
#define LED_PORT  			GPIOB
#define LED_CLK_EN()  	    __HAL_RCC_GPIOB_CLK_ENABLE()		
#define LED_Toggle(x) 	    (HAL_GPIO_TogglePin(LED_PORT, GPIO_PIN_0+x)) //LED翻转 x=0 -- LED0; x=1 -- LED1
#define Get_KEY0()          HAL_GPIO_ReadPin(LED_PORT, GPIO_PIN_3) //读取KEY0状态

#define KEY_PIN				GPIO_PIN_3
#define KEY_PORT			GPIOH
#define KEY_CLK_EN()		__HAL_RCC_GPIOH_CLK_ENABLE();


void LED_Init(void);
void KEY_Init(void);

void SYS_Init(void);

#endif

init.c

#include "init.h"


//LED 硬件初始化
void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    LED_CLK_EN();			
	
    GPIO_Initure.Pin   			= LED_PIN; 
    GPIO_Initure.Mode  			= GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull  			= GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed			= GPIO_SPEED_HIGH;      //高速
    HAL_GPIO_Init(LED_PORT, &GPIO_Initure);     
	
    HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
}

//KEY 硬件初始化
void KEY_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    KEY_CLK_EN();                                       //开启时钟
    
    GPIO_Initure.Pin			= KEY_PIN;          
    GPIO_Initure.Mode			= GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull			= GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed			= GPIO_SPEED_HIGH;      //高速
    HAL_GPIO_Init(KEY_PORT, &GPIO_Initure);
}

//系统初始化
void SYS_Init(void)
{
	Cache_Enable();                 				    //打开L1-Cache
    HAL_Init();				        				    //初始化HAL库
    Stm32_Clock_Init(432,25,2,9);   				    //设置时钟,216Mhz 
	
	LED_Init();											//初始化LED
	KEY_Init();											//初始化KEY
}

PART3: 具体的任务函数 mytask.h 与 mytask.c
mytask.h


#ifndef _TASK_H
#define _TASK_H

#include "sys.h"
#include "init.h"
#include "FreeRTOS.h"
#include "task.h"

void LED_Task(void *pvParameters);
void KEY_Task(void *pvParameters);

#endif

mytask.c

#include "mytask.h"
#include "init.h"


//LED任务:LED1闪烁,间隔 300ms
void LED_Task(void *pvParameters)
{
	while(1)						//操作系统都有的无限循环
	{
		LED_Toggle(0);
		vTaskDelay(300);			//已经将系统心跳设置为1ms,故300 即300ms
	}
}

//KEY任务:按下KEY0,LED0闪烁一次
void KEY_Task(void *pvParameters)
{
	u8 key=1;
	while(1)
	{
		key = Get_KEY0();   		//KEY0,低电平有效,按下为0
		vTaskDelay(20);     		//消抖
		key = Get_KEY0();
		
		if(key == 0)
		{
			LED_Toggle(1);
			vTaskDelay(500);  		//保持当前状态0.5s
		}
	}
}

以上就是FreeRTOS实现LED 亮灭闪烁和按键扫描。操作系统实现的是任务管理,但是并没有改变硬件初始化,硬件要实现的功能流程。

对于小白,第一次自己实现这个已经有点沾沾自喜了,下次继续努力深入。

你可能感兴趣的:(软件,操作系统)