【ACM32G103RCT6开发板测评】freertos实现多任务按键控制LED灯
[复制链接]
【目的】
实现GPIO的输入与输出的体验
【开发环境】
1、MDK5.38
2、freertos
【实现步骤】
在freertos的工程中,创建两个任务,分别为:
1、按键检测任务。开发板板载了1个按键,为PC13,官方的BSP的acm32g103_coreboard.c中已经实现了对他的初始化,代码如下:
/******************************************************************************
*[url=home.php?mod=space&uid=159083]@brief[/url] : PB init
*@param : none
*@return: none
******************************************************************************/
void BSP_PB_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
BSP_PB_CLK_ENABLE();
GPIO_InitStruct.Pin = BSP_PB_PIN;
GPIO_InitStruct.Mode = BSP_PB_MODE;
GPIO_InitStruct.Pull = BSP_PB_PULL;
GPIO_InitStruct.Drive = BSP_PB_DRIVE;
GPIO_InitStruct.Alternate = BSP_PB_ALTERNATE;
HAL_GPIO_Init(BSP_PB_GPIO, &GPIO_InitStruct);
// HAL_EXTI_ClearPending(BSP_PB_PIN);
// NVIC_ClearPendingIRQ(BSP_PB_IRQ);
// NVIC_SetPriority(BSP_PB_IRQ, 0x00);
// NVIC_EnableIRQ(BSP_PB_IRQ);
}
我这里不需要中断,所以注释掉了中断的配置。
2、LED灯的初始化,在acm32g103_coreboard.h也已有初始化的代码,所以我们直接调用就行了。库中也有翻转的函数BSP_LED_Toggle();
【任务的创建】
1、检测按键代码如下,主要的编程思想为检测是否按下,如果按下,则延时、消抖,再检测是否抬起,如果符合则翻转按键。
void task_1(void *msg)
{
printfS("task_1 run.... \r\n");
while (1)
{
if(BSP_PB_GetState() == GPIO_PIN_RESET)
{
vTaskDelay(100);
if(BSP_PB_GetState() == GPIO_PIN_SET)
{
BSP_LED_Toggle();
}
}
vTaskDelay(20);
}
}
烧写代码后,按下按建便可以实现LED灯的翻转。
【任务间的通信】
为体验事件标志组,所以我建立了任务事件组,为以后的编做准备:
#define LEDTOGGLE_0 ( 1 << 0 ) //0001 为按LED灯翻转事件标志
#define ALLBITS 0xFFFFFF //24bits都为1
我们在按键任务,如果检测到了按键按下后抬起,我们将事件标志置1,代码如下:
void task_1(void *msg)
{
printfS("task_1 run.... \r\n");
while (1)
{
if(BSP_PB_GetState() == GPIO_PIN_RESET)
{
vTaskDelay(100);
if(BSP_PB_GetState() == GPIO_PIN_SET)
{
xEventGroupSetBits(xEventPurchase, LEDTOGGLE_0); //将事件置1
}
}
vTaskDelay(20);
}
}
然后在led的任务中,我们判断示志位是否为1,如果为1,测翻反LED灯,代码如下:
void task_2(void *msg)
{
EventBits_t uxBits; // Event Group 24Bits 的 值
printfS("task_2 run.... \r\n");
while (1)
{
uxBits = xEventGroupWaitBits (xEventPurchase, //Event Group Handler
LEDTOGGLE_0, //等待Event Group中的那个Bit(s)
pdTRUE, //执行后,对应的Bits是否重置为 0
pdTRUE, //等待的Bits判断关系 True为 AND, False为 OR
xTimeOut);
if(uxBits & LEDTOGGLE_0)
{
BSP_LED_Toggle();
}
}
}
在主程序中,我们创建标组标志组:
void task_1(void *msg);
void task_2(void *msg);
int main(void)
{
uint32_t count=0;
HAL_Init();
SystemClock_Config();
TIM6_Init();
BSP_UART_Init();
BSP_LED_Init();
BSP_PB_Init();
xTaskCreate(task_1,"task1",100,NULL,0,NULL);
xTaskCreate(task_2,"task2",100,NULL,0,NULL);
xEventPurchase = xEventGroupCreate(); //创建 event group
vTaskStartScheduler();
while (1)
{
}
}
下载到开发板后,我们就可以实现用按键实现对LED灯的翻转控制了。
【小结】
本次实验主要体验freertos的多任务操作,利用事件标志组来实现任务间的通信,为以后的实验打基础。
整体的工程代码附上。
|