FreeRTOS事件组

exti.c
#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;

//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
	BaseType_t Result,xHigherPriorityTaskWoken;
	
	//delay_ms(20);	//消抖
	
	if(KEY0==0)	 
	{				 
		Result=xEventGroupSetBitsFromISR(EventGroupHandler,EVENTBIT_0,&xHigherPriorityTaskWoken);
		if(Result!=pdFAIL)
		{
			portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
		}
	}		 
	 EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中断标志位  
}












main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "lcd.h"
#include "key.h"
#include "exti.h"
//#include <string.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "event_groups.h"

/************************************************

************************************************/

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

#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);//设置系统中断优先级分组4
	delay_init(168);		//初始化延时函数
	uart_init(115200);     	//初始化串口
	LED_Init();		        //初始化LED端口
	KEY_Init();
	BEEP_Init();
	LCD_Init();
	EXTIX_Init();//初始化外部中断 这里中key0在下降沿触发
	//my_mem_init(SRAMIN);//初始化内部内存池

	POINT_COLOR=RED;
	LCD_ShowString(30,10,200,16,16,"STM32F407");
	LCD_ShowString(30,30,200,16,16,"FREERTOS 16-1");
	LCD_ShowString(30,50,200,16,16,"Event Group");
	LCD_ShowString(30,70,220,16,16,"alientek");
	LCD_ShowString(30,90,220,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();           //进入临界区
	//创建事件标志组
	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)EVENTGROUP_STK_SIZE,
				(void*)NULL,
				(UBaseType_t)EVENTGROUP_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);
		
	}

}

//事件标志组处理任务
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);
			LCD_ShowxNum(174,110,EventValue,1,16,0);
			
			num++;
			LED1=!LED1;
			LCD_Fill(6,131,233,313,lcd_discolor[num%14]);
		}
		else
			vTaskDelay(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);
				LCD_ShowxNum(174,110,NewValue,1,16,0);
			}
		}
		num++;
		if(num==0)
		{
			num=0;
			LED0=!LED0;
		}
		vTaskDelay(50);
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值