FreeRTOS任務掛起和恢復實驗-庫函數版本

 

 

*********************************************************************

*********************************************************************

******************************主函數*******************************

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "exti.h"
#include "FreeRTOS.h"
#include "task.h"
/************************************************
 ALIENTEK Mini STM32F103開發板 FreeRTOS實驗
 FreeRTOS任務掛起和恢復實驗-庫函數版本
 技術支持:www.openedv.com
 淘寶店鋪:http://eboard.taobao.com 
 關注微信公衆平臺微信號:"正點原子",免費獲取STM32資料。
 廣州市星翼電子科技有限公司  
 作者:正點原子 @ALIENTEK  KEY0  修改PC5爲PA13 2020 2 5測試通過
************************************************/

//任務優先級
#define START_TASK_PRIO        1
//任務堆棧大小    
#define START_STK_SIZE         128  
//任務句柄
TaskHandle_t StartTask_Handler;
//任務函數
void start_task(void *pvParameters);

//任務優先級
#define KEY_TASK_PRIO        2
//任務堆棧大小    
#define KEY_STK_SIZE         128  
//任務句柄
TaskHandle_t KeyTask_Handler;
//任務函數
void key_task(void *pvParameters);

//任務優先級
#define TASK1_TASK_PRIO        3
//任務堆棧大小    
#define TASK1_STK_SIZE         128  
//任務句柄
TaskHandle_t Task1Task_Handler;
//任務函數
void task1_task(void *pvParameters);

//任務優先級
#define TASK2_TASK_PRIO        4
//任務堆棧大小    
#define TASK2_STK_SIZE         128  
//任務句柄
TaskHandle_t Task2Task_Handler;
//任務函數
void task2_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();                                             //延時函數初始化     
    uart_init(115200);                                       //初始化串口
    LED_Init();                                                   //初始化LED
    KEY_Init();                                                   //初始化按鍵
    EXTIX_Init();                                               //初始化外部中斷
    LCD_Init();                                                   //初始化LCD
    POINT_COLOR = RED;
    LCD_ShowString(30,90,200,16,16,"2020/2/6");
//創建開始任務
    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();                               //進入臨界區
    //創建KEY任務
    xTaskCreate((TaskFunction_t )key_task,             
                (const char*    )"key_task",           
                (uint16_t       )KEY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )KEY_TASK_PRIO,        
                (TaskHandle_t*  )&KeyTask_Handler);  
    //創建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);   
    //創建TASK2任務
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
    vTaskDelete(StartTask_Handler);                          //刪除開始任務
    taskEXIT_CRITICAL();                                     //退出臨界區
}
/****************key任務函數************************/
void key_task(void *pvParameters)
{
    u8 key,statflag=0;
    while(1)
    {
        key=KEY_Scan(0);
        switch(key)
        {
              case WKUP_PRES:
                statflag=!statflag;
                if(statflag==1)
                {
                    vTaskSuspend(Task1Task_Handler);                   //掛起任務
                    LCD_ShowString(30,10,200,16,16,"Susp Task1\r\n");    
                }
                else if(statflag==0)
                {
                    vTaskResume(Task1Task_Handler);                       //恢復任務1
                    LCD_ShowString(30,10,200,16,16,"Resum Task1\r\n");
                }        
                break;
              case KEY1_PRES:
                vTaskSuspend(Task2Task_Handler);                     //掛起任務2
                LCD_ShowString(30,40,200,16,16,"Susp Task2\r\n");    
                break;
        }
        vTaskDelay(10);                                                 //延時10ms 
    }
}
/***************task1任務函數***********************/
void task1_task(void *pvParameters)
{
    u8 task1_num=0;
    POINT_COLOR = BLACK;
  LCD_DrawRectangle(5,110,115,314);                            //畫一個矩形    
    LCD_DrawLine(5,130,115,130);                                   //畫線
    POINT_COLOR = BLUE;
    LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
    while(1)
    {
        task1_num++;                                               //任務執1行次數加1 注意task1_num1加到255的時候會清零!!
        LED0=!LED0;
        //printf("任務1已經執行:%d次\r\n",task1_num);
        POINT_COLOR = BLUE;
        LCD_ShowString(30,60,200,16,16,"Task1 Run\r\n");    
        LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]);      //填充區域
        LCD_ShowxNum(86,111,task1_num,3,16,0x80);                   //顯示任務執行次數
    vTaskDelay(1000);                                        //延時1s,也就是1000個時鐘節拍    
    }
}
/***************task2任務函數***********************/
void task2_task(void *pvParameters)
{
    u8 task2_num=0;
    POINT_COLOR = BLACK;
  LCD_DrawRectangle(125,110,234,314);                        //畫一個矩形    
    LCD_DrawLine(125,130,234,130);                                 //畫線
    POINT_COLOR = BLUE;
    LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
    while(1)
    {
        task2_num++;                                               //任務2執行次數加1 注意task1_num2加到255的時候會清零!!
    LED1=!LED1;
        //printf("任務2已經執行:%d次\r\n",task2_num);
        POINT_COLOR =BROWN;
        LCD_ShowString(30,60,200,16,16,"Task2 Run\r\n,");    
        LCD_ShowxNum(206,111,task2_num,3,16,0x80);               //顯示任務執行次數
        LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充區域
    vTaskDelay(1000);                                        //延時1s,也就是1000個時鐘節拍    
    }
}

*********************************************************************

*********************************************************************

*******************************EXTI.C******************************

#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
//////////////////////////////////////////////////////////////////////////////////     
//本程序只供學習使用,未經作者許可,不得用於其它任何用途
//Mini STM32開發板
//外部中斷 驅動代碼               
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//修改日期:2010/12/01  
//版本:V1.0
//版權所有,盜版必究。
//Copyright(C) 正點原子 2009-2019
//All rights reserved      
//////////////////////////////////////////////////////////////////////////////////       
 
 
//外部中斷初始化函數
void EXTIX_Init(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;    
      NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中斷,需要使能AFIO時鐘
    KEY_Init();//初始化按鍵對應io模式
//GPIOC.5 中斷線以及中斷初始化配置   改  GPIOA.13 中斷線以及中斷初始化配置************************
      GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource13);//改PC5爲PA13
    EXTI_InitStructure.EXTI_Line=EXTI_Line13;
      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;    
      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿觸發
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);         //根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器
    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;            //使能按鍵所在的外部中斷通道
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;//搶佔優先級6 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;        //子優先級0
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能外部中斷通道
      NVIC_Init(&NVIC_InitStructure); 
}

/**************任務句柄恢復任務2*******************/
extern TaskHandle_t Task2Task_Handler;

void EXTI15_10_IRQHandler(void)                                     //EXTI9_5_IRQHandler改爲EXTI15_10_IRQHandler************************
{    
    BaseType_t YieldRequired;    
    delay_xms(20);                                                //消抖             
    if(KEY0==0)    
    {
        YieldRequired=xTaskResumeFromISR(Task2Task_Handler);        //恢復任務2
        //printf("恢復任務2的運行!\r\n");
        LCD_ShowString(30,40,200,16,16,"Resum Task2\r\n");
        if(YieldRequired==pdTRUE)
        {
            /*如果函數xTaskResumeFromISR()返回值爲pdTRUE,那麼說明要恢復的這個
            任務的任務優先級等於或者高於正在運行的任務(被中斷打斷的任務),所以在
            退出中斷的時候一定要進行上下文切換!*/
            portYIELD_FROM_ISR(YieldRequired);
        }
    }
      EXTI_ClearITPendingBit(EXTI_Line13);                            //清除LINE5上的中斷標誌位  改爲13************************
}
 

*********************************************************************

*********************************************************************

*********************************************************************

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章