FreeRTOS——事件标志组

FreeRTOS——事件标志组

事件标志组

事件标志组简介

使用信号量同步任务只能与单个时间或任务进行同步,如果要莫个任务与多个事件或者任务进行同步,这时需要事件标志组来处理。

在这里插入图片描述

事件标志组相关函数

事件标志组创建函数

在这里插入图片描述
在这里插入图片描述

设置事件位函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

获取事件标志组值函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

等待指定事件位函数

在这里插入图片描述

实验

要求

在这里插入图片描述
在这里插入图片描述

程序

主程序

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "beep.h"
#include "exti.h"
#include "string.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"

//任务优先级
#define START_TASK_PRIO			1
//任务堆栈大小
#define START_STK_SIZE 			256  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define EVENTSETBIT_TASK_PRIO	2
//ÈÎÎñ¶ÑÕ»´óС	
#define EVENTSETBIT_STK_SIZE 	256  
//ÈÎÎñ¾ä±ú
TaskHandle_t EventSetBit_Handler;
//ÈÎÎñº¯Êý
void eventsetbit_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define EVENTGROUP_TASK_PRIO	3
//ÈÎÎñ¶ÑÕ»´óС	
#define EVENTGROUP_STK_SIZE 	256  
//ÈÎÎñ¾ä±ú
TaskHandle_t EventGroupTask_Handler;
//ÈÎÎñº¯Êý
void eventgroup_task(void *pvParameters);

//ÈÎÎñÓÅÏȼ¶
#define EVENTQUERY_TASK_PRIO	4
//ÈÎÎñ¶ÑÕ»´óС	
#define EVENTQUERY_STK_SIZE 	256  
//ÈÎÎñ¾ä±ú
TaskHandle_t EventQueryTask_Handler;
//ÈÎÎñº¯Êý
void eventquery_task(void *pvParameters);


EventGroupHandle_t EventGroupHandler;	//事件标志组任务句柄

#define EVENTBIT_0	(1<<0)				//事件位
#define EVENTBIT_1	(1<<1)
#define EVENTBIT_2	(1<<2)
#define EVENTBIT_ALL	(EVENTBIT_0|EVENTBIT_1|EVENTBIT_2)



int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	delay_init(168);	
	uart_init(115200);     				
	LED_Init();		        		
	KEY_Init();							
	EXTIX_Init();						
	my_mem_init(SRAMIN);            	//初始化内部内存池

	
	
	//开始创建任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //给任务传递的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄            
    vTaskStartScheduler();          //开启任务调度器
}

//开始创建任务
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建事件标志组
	EventGroupHandler=xEventGroupCreate();	 //´´½¨Ê¼þ±êÖ¾×é
	
	//创建设置事件标志位任务
    xTaskCreate((TaskFunction_t )eventsetbit_task,             
                (const char*    )"eventsetbit_task",           
                (uint16_t       )EVENTSETBIT_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )EVENTSETBIT_TASK_PRIO,        
                (TaskHandle_t*  )&EventSetBit_Handler);   	
   //创建事件标志组处理任务
    xTaskCreate((TaskFunction_t )eventgroup_task,             
                (const char*    )"eventgroup_task",           
                (uint16_t       )EVENTGROUP_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )EVENTGROUP_TASK_PRIO,        
                (TaskHandle_t*  )&EventGroupTask_Handler);  
  //创建事件标志组查询任务
    xTaskCreate((TaskFunction_t )eventquery_task,             
                (const char*    )"eventquery_task",           
                (uint16_t       )EVENTQUERY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )EVENTQUERY_TASK_PRIO,        
                (TaskHandle_t*  )&EventQueryTask_Handler);    
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}


//设置事件标志位任务
void eventsetbit_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		if(EventGroupHandler!=NULL)
		{
			key=KEY_Scan(0);
			switch(key)
			{
				case KEY1_PRES:
					xEventGroupSetBits(EventGroupHandler,EVENTBIT_1);
					break;
				case KEY2_PRES:
					xEventGroupSetBits(EventGroupHandler,EVENTBIT_2);
					break;	
			}
		}
        vTaskDelay(10); //ÑÓʱ10ms£¬Ò²¾ÍÊÇ10¸öʱÖÓ½ÚÅÄ
	}
}

//事件标志组处理任务
void eventgroup_task(void *pvParameters)
{
	u8 num;
	EventBits_t EventValue;
	while(1)
	{

		if(EventGroupHandler!=NULL)
		{
			//等待事件标志组相应时间
			EventValue=xEventGroupWaitBits((EventGroupHandle_t	)EventGroupHandler,		
										   (EventBits_t			)EVENTBIT_ALL,
										   (BaseType_t			)pdTRUE,				
										   (BaseType_t			)pdTRUE,
								           (TickType_t			)portMAX_DELAY);	
			printf("事件标志组的值:%d\r\n",EventValue);
		
			
			num++;
			LED1=!LED1;	
		
		}
		else
		{
			vTaskDelay(10); //ÑÓʱ10ms£¬Ò²¾ÍÊÇ10¸öʱÖÓ½ÚÅÄ
		}
	}
}

//时间查询任务
void eventquery_task(void *pvParameters)
{	
	u8 num=0;
	EventBits_t NewValue,LastValue;
	while(1)
	{
		if(EventGroupHandler!=NULL)
		{
			NewValue=xEventGroupGetBits(EventGroupHandler);	//获取事件标志组
			if(NewValue!=LastValue)
			{
				LastValue=NewValue;
				printf("事件标志组的值:%d\r\n",NewValue);
			
			}
		}
		num++;
		if(num==10) 	//ÿ500msLED0ÉÁ˸һ´Î
		{
			num=0;
			LED0=!LED0;	
		}
		vTaskDelay(50); //ÑÓʱ50ms£¬Ò²¾ÍÊÇ50¸öʱÖÓ½ÚÅÄ
	}
}


中断程序

#ifndef __EXTI_H
#define __EXIT_H	 
#include "sys.h"  	


void EXTIX_Init(void);	//外部中断初始化		 					    
#endif
#include "exti.h"
#include "delay.h" 
#include "key.h"
#include "FreeRTOS.h"
#include "event_groups.h"


#define EVENTBIT_0 (1<<0)

//ÍⲿÖжϳõʼ»¯³ÌÐò
//³õʼ»¯PE4ΪÖжÏÊäÈë.
void EXTIX_Init(void)
{
	NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	KEY_Init(); //°´¼ü¶ÔÓ¦µÄIO¿Ú³õʼ»¯
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//ʹÄÜSYSCFGʱÖÓ
 
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//PE4 Á¬½Óµ½ÖжÏÏß4
	
	/* ÅäÖÃEXTI_Line4 */
	EXTI_InitStructure.EXTI_Line =  EXTI_Line4;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//ÖжÏʼþ
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //ϽµÑØ´¥·¢
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//ÖжÏÏßʹÄÜ
	EXTI_Init(&EXTI_InitStructure);							//ÅäÖÃ
 
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;		//ÍⲿÖжÏ4
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;//ÇÀÕ¼ÓÅÏȼ¶6
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;	//×ÓÓÅÏȼ¶0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//ʹÄÜÍⲿÖжÏͨµÀ
	NVIC_Init(&NVIC_InitStructure);							//ÅäÖÃ	   
}

//事件标志组的句柄
extern EventGroupHandle_t EventGroupHandler;

//外部中断服务函数
void EXTI4_IRQHandler(void)
{
	BaseType_t Result,xHigherPriorityTaskWoken;
	
	delay_xms(20);	//消抖
	if(KEY0==0)	 
	{				 
		Result=xEventGroupSetBitsFromISR(EventGroupHandler,EVENTBIT_0,&xHigherPriorityTaskWoken);
		if(Result!=pdFAIL)
		{
			portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
		}
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line4);//清除中断标志位  
}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值