DSP

任务通知模拟计数型信号量

2019-07-13 18:37发布

main.c #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "beep.h" #include "lcd.h" #include "key.h" #include "malloc.h" #include #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" /************************************************ ************************************************/ //LCD刷屏时使用的颜 {MOD} 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 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); //任务函数 int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4 delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口 LED_Init(); //初始化LED端口 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 17-2"); LCD_ShowString(30,50,200,16,16,"Task Notify count sem"); LCD_ShowString(30,70,220,16,16,"Alientek"); LCD_ShowString(30,90,220,16,16,"2018/1/2"); POINT_COLOR=BLACK; LCD_DrawRectangle(5,110,234,314); LCD_DrawLine(5,130,234,130); POINT_COLOR=RED; LCD_ShowString(30,111,220,16,16,"Notify 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(); //进入临界区 //创建释放信号量任务 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; while(1) { key=KEY_Scan(0);//模式0扫键 if(SemapTakeTask_Handler != NULL) // { switch(key) { case WKUP_PRES: xTaskNotifyGive(SemapTakeTask_Handler); break; default:break; } } i++; if(i==50) { i=0; LED0 =!LED0; } vTaskDelay(10); } } // // //获取计数型信号量任务函数 void SemapTake_task(void *pvParameters) { u8 num; uint32_t NotifyValue; while(1) { NotifyValue=ulTaskNotifyTake(pdFALSE,portMAX_DELAY);//获取任务通知 num++; LCD_ShowxNum(166,111,NotifyValue-1,3,16,0);//显示当前任务通知值 LCD_Fill(6,131,233,313,lcd_discolor[num%14]); LED1=!LED1; vTaskDelay(1000); } }