FreeRTOS任务通知

FreeRTOS任务通知

FreeRTOS任务通知简介

在这里插入图片描述

任务通知发送函数

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

任务通知获取函数

在这里插入图片描述
在这里插入图片描述
返回值:任何值
在这里插入图片描述
在这里插入图片描述

实验

任务通知模拟二值信号量

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


//优先级
#define START_TASK_PRIO		1
#define TASK1_TASK_PRIO		2
#define DATAPROCESS_TASK_PRIO 3

//堆栈大小
#define START_STK_SIZE 		256 
#define TASK1_STK_SIZE 		256  
#define DATAPROCESS_STK_SIZE  256  
//句柄
TaskHandle_t StartTask_Handler;
TaskHandle_t Task1Task_Handler;
TaskHandle_t DataProcess_Handler;
//任务函数
void start_task(void *pvParameters);
void task1_task(void *pvParameters);
void DataProcess_task(void *pvParameters);

//用于命令解析用的命令值
#define LED1ON	1
#define LED1OFF	2
#define BEEPON	3
#define BEEPOFF	4
#define COMMANDERR	0XFF

//字符串小写转大写
void LowerToCap(u8 *str,u8 len)
{
	u8 i;
	for(i=0;i<len;i++)
	{
		if((96<str[i])&&(str[i]<123))	//小写字母
		 str[i]=str[i]-32;				//转大写字母
	}
}

//命令函数,将字符串变成命令
u8 CommandProcess(u8 *str)
{
	u8 CommandValue=COMMANDERR;
	if(strcmp((char*)str,"LED1ON")==0) CommandValue=LED1ON;
	else if(strcmp((char*)str,"LED1OFF")==0) CommandValue=LED1OFF;
	else if(strcmp((char*)str,"BEEPON")==0) CommandValue=BEEPON;
	else if(strcmp((char*)str,"BEEPOFF")==0) CommandValue=BEEPOFF;
	return CommandValue;
}

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	delay_init(168);			
	uart_init(115200);     				
	LED_Init();		        			
	KEY_Init();						
	BEEP_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();           //进入临界区
	
	
    //创建任务1
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建任务2
    xTaskCreate((TaskFunction_t )DataProcess_task,     
                (const char*    )"keyprocess_task",   
                (uint16_t       )DATAPROCESS_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )DATAPROCESS_TASK_PRIO,
                (TaskHandle_t*  )&DataProcess_Handler); 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//task1任务
void task1_task(void *pvParameters)
{
	while(1)
	{
		LED0=!LED0;
        vTaskDelay(500);             	
	}
}

//DataProcess_task任务
void DataProcess_task(void *pvParameters)
{
	u8 len=0;
	u8 CommandValue=COMMANDERR;
	u32 NotifyValue;
	
	u8 *CommandStr;

	while(1)
	{
	    NotifyValue=ulTaskNotifyTake(pdTRUE,portMAX_DELAY);	//获取任务通知

			
			if(NotifyValue==1)										//成功
			{
				len=USART_RX_STA&0x3fff;						//得到数据长度
				CommandStr=mymalloc(SRAMIN,len+1);				//申请内存
			
				CommandStr[len]='\0';							//加结束符
				LowerToCap(CommandStr,len);						//转大写	
				CommandValue=CommandProcess(CommandStr);		//命令解析
				if(CommandValue!=COMMANDERR)
				{
				
					printf("命令:%s\r\n",CommandStr);
					switch(CommandValue)						//处理命令
					{
						case LED1ON: 
							LED1=0;
							break;
						case LED1OFF:
							LED1=1;
							break;
						case BEEPON:
							BEEP=1;
							break;
						case BEEPOFF:
							BEEP=0;
							break;
					}
				}
				else
				{
					printf("命令无效!!\r\n");
				}
				USART_RX_STA=0;
				memset(USART_RX_BUF,0,USART_REC_LEN);			//串口接受缓存区清0
				myfree(SRAMIN,CommandStr);						//释放内存
			}
		
		else if(err==pdFALSE)
		{
			vTaskDelay(10);      
		}
	}
}

串口中断

extern TaskHandle_t DataProcess_Handler;;	

void USART1_IRQHandler(void)                
{
	u8 Res;
	BaseType_t xHigherPriorityTaskWoken;
	
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
		
		if((USART_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É
		{
			if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d
			{
				if(Res!=0x0a)USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼
				else USART_RX_STA|=0x8000;	//½ÓÊÕÍê³ÉÁË 
			}
			else //»¹Ã»ÊÕµ½0X0D
			{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0; 
				}		 
			}
		}   		 
	} 
	
//发送任务通知
	if((USART_RX_STA&0x8000)&&(DataProcess_Handler!=NULL))//接收到数据,并且任务有效
	{
		vTaskNotifyGiveFromISR(DataProcess_Handler,&xHigherPriorityTaskWoken);//发送任务通知
		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//任务切换
	}
} 

注意:该程序和之前发的二值信号量程序一样,不同的是所用函数不同

任务通知模拟计数信号量

#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 "string.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"


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

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

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

//计数信号量句柄
//SemaphoreHandle_t CountSemaphore;

//LCDË刷频颜色
int lcd_discolor[14]={	WHITE, BLACK, BLUE,  BRED,      
						GRED,  GBLUE, RED,   MAGENTA,       	 
						GREEN, CYAN,  YELLOW,BROWN, 			
						BRRED, GRAY };

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	delay_init(168);					
	uart_init(115200);     				
	LED_Init();		        			
	KEY_Init();						
	BEEP_Init();						
	LCD_Init();							
	my_mem_init(SRAMIN);            	//初始化内部内存池
    
    POINT_COLOR = RED;
	LCD_ShowString(30,10,200,16,16,"STM32F407");	
	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 14-2");
	LCD_ShowString(30,50,200,16,16,"Count Semaphore");
	LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,90,200,16,16,"2016/11/25");
	
	POINT_COLOR = BLACK;
	LCD_DrawRectangle(5,110,234,314);	
	LCD_DrawLine(5,130,234,130);
	POINT_COLOR = RED;
	LCD_ShowString(30,111,200,16,16,"COUNT_SEM Value: 0");
	POINT_COLOR = BLUE;
	
	//创建开始任务
    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();           //进入临界区
	
	//创建计数信号量
//	CountSemaphore=xSemaphoreCreateCounting(255,0);	
    //创建释放信号量任务
    xTaskCreate((TaskFunction_t )SemapGive_task,             
                (const char*    )"semapgive_task",           
                (uint16_t       )SEMAPGIVE_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )SEMAPGIVE_TASK_PRIO,        
                (TaskHandle_t*  )&SemapGiveTask_Handler);   
    //创建获取信号量任务
    xTaskCreate((TaskFunction_t )SemapTake_task,     
                (const char*    )"semaptake_task",   
                (uint16_t       )SEMAPTAKE_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )SEMAPTAKE_TASK_PRIO,
                (TaskHandle_t*  )&SemapTakeTask_Handler); 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//释放信号量任务
void SemapGive_task(void *pvParameters)
{
	u8 key,i=0;
   // u8 semavalue;
	//BaseType_t err;
	while(1)
	{
		key=KEY_Scan(0);           	//扫描按键
        if(SemapTakeTask_Handler!=NULL)  	//创建成功
        {
            switch(key)
            {
                case WKUP_PRES:
                  //  err=xSemaphoreGive(CountSemaphore);//释放信号量
					//if(err==pdFALSE)
					//{
					//	printf("释放信号量失败!!!\r\n");
					//}
                    //semavalue=uxSemaphoreGetCount(CountSemaphore);	//获取计数信号量值
                   // LCD_ShowxNum(155,111,semavalue,3,16,0);	    	//显示
                    tifyGive(SemapTakeTask_Handler);//发送任务通知
                    break;
            }
        }
        i++;
        if(i==50)
        {
            i=0;
            LED0=!LED0;
        }
        vTaskDelay(10);     
	}
}

//获取信号量
void SemapTake_task(void *pvParameters)
{
    u8 num;
    //u8 semavalue;
     uint32_t NotifyValue;
	while(1)
	{
       // xSemaphoreTake(CountSemaphore,portMAX_DELAY); 	//等待数值信号量
       NotifyValue=ulTaskNotifyTake(pdFALSE,portMAX_DELAY);//获取任务通知
        num++;
        //semavalue=uxSemaphoreGetCount(CountSemaphore); 	//获取
        LCD_ShowxNum(155,111,semavalue,3,16,0);         //显示
		LCD_Fill(6,131,233,313,lcd_discolor[num%14]);   //清屏
		LED1=!LED1;
        vTaskDelay(1000);                              
	}
}


注意:该程序和之前发的计数信号量程序一样,不同的是所用函数不同

任务通知模拟消息邮箱

#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 "string.h"
#include "malloc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "limits.h"

//ÈÎÎñÓÅÏȼ¶
#define START_TASK_PRIO		1
//ÈÎÎñ¶ÑÕ»´óС	
#define START_STK_SIZE 		256  
//ÈÎÎñ¾ä±ú
TaskHandle_t StartTask_Handler;
//ÈÎÎñº¯Êý
void start_task(void *pvParameters);

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

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

//LCDË¢ÆÁʱʹÓõÄÑÕÉ«
int lcd_discolor[14]={	WHITE, BLACK, BLUE,  BRED,      
						GRED,  GBLUE, RED,   MAGENTA,       	 
						GREEN, CYAN,  YELLOW,BROWN, 			
						BRRED, GRAY };

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é4
	delay_init(168);					//³õʼ»¯ÑÓʱº¯Êý
	uart_init(115200);     				//³õʼ»¯´®¿Ú
	LED_Init();		        			//³õʼ»¯LED¶Ë¿Ú
	KEY_Init();							//³õʼ»¯°´¼ü
	BEEP_Init();						//³õʼ»¯·äÃùÆ÷
	LCD_Init();							//³õʼ»¯LCD
	my_mem_init(SRAMIN);            	//³õʼ»¯ÄÚ²¿ÄÚ´æ³Ø
      
	POINT_COLOR = RED;
	LCD_ShowString(10,10,200,16,16,"ATK STM32F103/407");	
	LCD_ShowString(10,30,200,16,16,"FreeRTOS Examp 17-3");
	LCD_ShowString(10,50,200,16,16,"Task Notify Maibox");
	LCD_ShowString(10,70,220,16,16,"KEY_UP:LED1  KEY2:BEEP");
	LCD_ShowString(10,90,200,16,16,"KEY0:Refresh LCD");
	
	POINT_COLOR = BLACK;
	LCD_DrawRectangle(5,125,234,314);	//»­¾ØÐÎ
	
	//´´½¨¿ªÊ¼ÈÎÎñ
    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();           //½øÈëÁÙ½çÇø

    //´´½¨TASK1ÈÎÎñ
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //´´½¨°´¼ü´¦ÀíÈÎÎñ
    xTaskCreate((TaskFunction_t )Keyprocess_task,     
                (const char*    )"keyprocess_task",   
                (uint16_t       )KEYPROCESS_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )KEYPROCESS_TASK_PRIO,
                (TaskHandle_t*  )&Keyprocess_Handler); 
    vTaskDelete(StartTask_Handler); //ɾ³ý¿ªÊ¼ÈÎÎñ
    taskEXIT_CRITICAL();            //Í˳öÁÙ½çÇø
}

//task1ÈÎÎñº¯Êý
void task1_task(void *pvParameters)
{
	u8 key,i=0;
    BaseType_t err;
	while(1)
	{
		key=KEY_Scan(0);            			//ɨÃè°´¼ü
        if((Keyprocess_Handler!=NULL)&&(key))   
        {
			err=xTaskNotify((TaskHandle_t	)Keyprocess_Handler,		//接收通知任务的句柄
							(uint32_t		)key,						//任务通知值
							(eNotifyAction	)eSetValueWithOverwrite);	//覆写方式发送任务
			if(err==pdFAIL)
			{
				printf("发送失败\r\n");
			}
        }
        i++;
        if(i==50)
        {
            i=0;
            LED0=!LED0;
        }
        vTaskDelay(10);           //ÑÓʱ10ms£¬Ò²¾ÍÊÇ10¸öʱÖÓ½ÚÅÄ	
	}
}


//Keyprocess_taskº¯Êý
void Keyprocess_task(void *pvParameters)
{
	u8 num;
	uint32_t NotifyValue;
	BaseType_t err;
	
	while(1)
	{
		err=xTaskNotifyWait((uint32_t	)0x00,				//进入函数是不清除任务bit
							(uint32_t	)ULONG_MAX,			//退出函数时清除所有任务bit
							(uint32_t*	)&NotifyValue,		//保存任务通知值
							(TickType_t	)portMAX_DELAY);	//阻塞时间
		if(err==pdTRUE)				//获取任务通知成功
		{
			switch((u8)NotifyValue)
			{
                case WKUP_PRES:		//KEY_UP¿ØÖÆLED1
                    LED1=!LED1;
					break;
				case KEY2_PRES:		//KEY2¿ØÖÆ·äÃùÆ÷
                    BEEP=!BEEP;
					break;
				case KEY0_PRES:		//KEY0Ë¢ÐÂLCD±³¾°
                    num++;
					LCD_Fill(6,126,233,313,lcd_discolor[num%14]);
                    break;
			}
		}
	}
}

任务通知模拟事件标志组

#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 "limits.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 EVENTBIT_0	(1<<0)				//ʼþλ
#define EVENTBIT_1	(1<<1)
#define EVENTBIT_2	(1<<2)

//LCDË¢ÆÁʱʹÓõÄÑÕÉ«
int lcd_discolor[14]={	WHITE, BLACK, BLUE,  BRED,      
						GRED,  GBLUE, RED,   MAGENTA,       	 
						GREEN, CYAN,  YELLOW,BROWN, 			
						BRRED, GRAY };

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é4
	delay_init(168);					//³õʼ»¯ÑÓʱº¯Êý
	uart_init(115200);     				//³õʼ»¯´®¿Ú
	LED_Init();		        			//³õʼ»¯LED¶Ë¿Ú
	KEY_Init();							//³õʼ»¯°´¼ü
	EXTIX_Init();						//³õʼ»¯ÍⲿÖжÏ
	LCD_Init();							//³õʼ»¯LCD
	my_mem_init(SRAMIN);            	//³õʼ»¯ÄÚ²¿ÄÚ´æ³Ø
	
    POINT_COLOR = RED;
	LCD_ShowString(30,10,200,16,16,"ATK STM32F103/407");	
	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 17-4");
	LCD_ShowString(30,50,200,16,16,"Task Notify Event Group");
	LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,90,200,16,16,"2016/11/25");

	POINT_COLOR = BLACK;
	LCD_DrawRectangle(5,130,234,314);	//»­¾ØÐÎ
	POINT_COLOR = BLUE;
	LCD_ShowString(30,110,220,16,16,"Event Group Value:0");
	
	//´´½¨¿ªÊ¼ÈÎÎñ
    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();           //½øÈëÁÙ½çÇø
	
	//´´½¨ÉèÖÃʼþλµÄÈÎÎñ
    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);     
    vTaskDelete(StartTask_Handler); //ɾ³ý¿ªÊ¼ÈÎÎñ
    taskEXIT_CRITICAL();            //Í˳öÁÙ½çÇø
}


//设置事件位的任务
void eventsetbit_task(void *pvParameters)
{
	u8 key,i;
	while(1)
	{
		if(EventGroupTask_Handler!=NULL)
		{
			key=KEY_Scan(0);
			switch(key)
			{
				case KEY1_PRES:
					xTaskNotify((TaskHandle_t	)EventGroupTask_Handler,//接受任务通知的任务句柄
								(uint32_t		)EVENTBIT_1,			//更新bit
								(eNotifyAction	)eSetBits);				//更新指定的bit
					break;
				case KEY2_PRES:
					xTaskNotify((TaskHandle_t	)EventGroupTask_Handler,//½ÓÊÕÈÎÎñ֪ͨµÄÈÎÎñ¾ä±ú
								(uint32_t		)EVENTBIT_2,			//Òª¸üеÄbit
								(eNotifyAction	)eSetBits);				//¸üÐÂÖ¸¶¨µÄbit
					break;	
			}
		}
		i++;
		if(i==50)
		{
			i=0;
			LED0=!LED0;
		}
        vTaskDelay(10); //ÑÓʱ10ms£¬Ò²¾ÍÊÇ10¸öʱÖÓ½ÚÅÄ
	}
}

//ʼþ±êÖ¾×é´¦ÀíÈÎÎñ
void eventgroup_task(void *pvParameters)
{
	u8 num=0,enevtvalue;
	static u8 event0flag,event1flag,event2flag;
	uint32_t NotifyValue;
	BaseType_t err;
	
	while(1)
	{
		//»ñÈ¡ÈÎÎñֵ֪ͨ
		err=xTaskNotifyWait((uint32_t	)0x00,				//进入函数不清除bit
							(uint32_t	)ULONG_MAX,			//退出函数清除所有bit
							(uint32_t*	)&NotifyValue,		//保存任务通知值
							(TickType_t	)portMAX_DELAY);	//阻塞时间
		
		if(err==pdPASS)	   //任务通知获取成功
		{
			if((NotifyValue&EVENTBIT_0)!=0)			//事件0发生
			{
				event0flag=1;	
			}				
			else if((NotifyValue&EVENTBIT_1)!=0)	//ʼþ1·¢Éú	
			{
				event1flag=1;
			}
			else if((NotifyValue&EVENTBIT_2)!=0)	//ʼþ2·¢Éú	
			{
				event2flag=1;	
			}
	
			enevtvalue=event0flag|(event1flag<<1)|(event2flag<<2);	//模拟事件标志组值
			printf("ÈÎÎñֵ֪ͨΪ:%d\r\n",enevtvalue);
			LCD_ShowxNum(174,110,enevtvalue,1,16,0);				//ÔÚLCDÉÏÏÔʾµ±Ç°Ê¼þÖµ
			
			if((event0flag==1)&&(event1flag==1)&&(event2flag==1))	//三个事件同时发生
			{
				num++;
				LED1=!LED1;	
				LCD_Fill(6,131,233,313,lcd_discolor[num%14]);
				event0flag=0;								//清0
				event1flag=0;
				event2flag=0;
			}
		}
		else
		{
			printf("ÈÎÎñ֪ͨ»ñȡʧ°Ü\r\n");
		}

	}
}



#include "exti.h"
#include "delay.h" 
#include "key.h"
#include "FreeRTOS.h"
#include "task.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 TaskHandle_t EventGroupTask_Handler;
//ÍⲿÖжÏ4·þÎñ³ÌÐò
void EXTI4_IRQHandler(void)
{
	BaseType_t xHigherPriorityTaskWoken;
	
	delay_xms(20);	//Ïû¶¶
	if(KEY0==0)	 
	{				 
		xTaskNotifyFromISR((TaskHandle_t	)EventGroupTask_Handler, 	//任务句柄
						   (uint32_t		)EVENTBIT_0, 				//更新bit
						   (eNotifyAction	)eSetBits, 					//更新指定的bit
						   (BaseType_t*		)xHigherPriorityTaskWoken);

		portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line4);//Çå³ýLINE4ÉϵÄÖжϱê־λ  
}


注意:该程序和之前发的事件标志组一样,不同的是所用函数不同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值