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); 
}


//任务句柄
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");
        if(YieldRequired==pdTRUE)
        {
            /*如果函数xTaskResumeFromISR()返回值为pdTRUE,那么说明要恢复的这个
            任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),所以在
            退出中断的时候一定要进行上下文切换!*/
            portYIELD_FROM_ISR(YieldRequired);
        }
    }
      EXTI_ClearITPendingBit(EXTI_Line13);                            //清除LINE5上的中断标志位  改为13************************
}
*********************************************************************

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

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

FreeRTOS任务挂起和恢复实验-库函数版本FreeRTOS任务挂起和恢复实验-库函数版本 czhaii 发布了24 篇原创文章 · 获赞 8 · 访问量 2万+ 私信 关注
上一篇:蓝桥基础之硬件配置(三)——LCD函数使用


下一篇:嵌入式Linux开发9——RGBLCD显示