ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

FreeRTOS任务挂起和恢复实验-库函数版本

2020-02-06 16:41:10  阅读:256  来源: 互联网

标签:task FreeRTOS 16 void LCD 任务 版本 EXTI 库函数


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

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

******************************主函数*******************************

#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************************
}
*********************************************************************

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

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

czhaii 发布了24 篇原创文章 · 获赞 8 · 访问量 2万+ 私信 关注

标签:task,FreeRTOS,16,void,LCD,任务,版本,EXTI,库函数
来源: https://blog.csdn.net/czhaii/article/details/104198140

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有