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ÉϵÄÖжϱê־λ
}
注意:该程序和之前发的事件标志组一样,不同的是所用函数不同