注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
lugl4313820的个人空间 https://home.eeworld.com.cn/space-uid-1269709.html [收藏] [复制] [分享] [RSS]
日志

【ACM32G103RCT6开发板测评】freertos实现多任务按键控制LED灯

已有 509 次阅读2023-12-30 23:29

【目的】

实现GPIO的输入与输出的体验

【开发环境】

1、MDK5.38

2、freertos

【实现步骤】

在freertos的工程中,创建两个任务,分别为:

1、按键检测任务。开发板板载了1个按键,为PC13,官方的BSP的acm32g103_coreboard.c中已经实现了对他的初始化,代码如下:

/******************************************************************************
*@brief : 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的多任务操作,利用事件标志组来实现任务间的通信,为以后的实验打基础。

整体的工程代码附上。

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章