“STM32F103VET6<_>FreeRTOS”

1、项目功能实现

1)LED灯定时闪烁

2)KEY按键检测

3)FreeRTOS任务创建

4)串口输出程序运行状态

2、软件代码实现

1)LED灯初始化代码

 1  1 #ifndef __BSP_LED_H
 2  2 #define __BSP_LED_H
 3  3 
 4  4 /*---------------------------宏定义-----------------------------*/
 5  5 
 6  6 #define  LED1_GPIO_PORT      GPIOB
 7  7 #define  LED1_GPIO_CLK       RCC_APB2Periph_GPIOB
 8  8 #define  LED1_GPIO_PIN       GPIO_Pin_5
 9  9 
10 10 #define  LED2_GPIO_PORT      GPIOB
11 11 #define  LED2_GPIO_CLK       RCC_APB2Periph_GPIOB
12 12 #define  LED2_GPIO_PIN       GPIO_Pin_0
13 13 
14 14 #define  LED3_GPIO_PORT      GPIOB
15 15 #define  LED3_GPIO_CLK       RCC_APB2Periph_GPIOB
16 16 #define  LED3_GPIO_PIN       GPIO_Pin_1
17 17 
18 18 #define ON  0
19 19 #define OFF 1
20 20 
21 21 #define LED1_ON  GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)
22 22 #define LED1_OFF GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)
23 23 
24 24 #define LED2_ON  GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN)
25 25 #define LED2_OFF GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN)
26 26 
27 27 #define LED3_ON  GPIO_ResetBits(LED3_GPIO_PORT,LED3_GPIO_PIN)
28 28 #define LED3_OFF GPIO_SetBits(LED3_GPIO_PORT,LED3_GPIO_PIN)
29 29 
30 30 /*-------------------------------函数声明---------------------------*/
31 31 
32 32 void LED_Init(void);        /* 初始化GPIO端口状态 */
33 33 void LED_GPIO_Config(void); /* 配置外设GPIO端口   */
34 34 
35 35 #endif

bsp_LED.h

 1  1 #include "stm32f10x.h"
 2  2 #include "bsp_LED.h"
 3  3 
 4  4 void LED_GPIO_Config(void)
 5  5 {
 6  6     GPIO_InitTypeDef GPIO_InitStructure;
 7  7     RCC_APB2PeriphClockCmd(LED1_GPIO_CLK|LED1_GPIO_CLK|LED1_GPIO_CLK,ENABLE);
 8  8     
 9  9     /* 初始化结构体参数,并配置寄存器 */
10 10     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
11 11     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
12 12     
13 13     GPIO_InitStructure.GPIO_Pin   = LED1_GPIO_PIN;
14 14     GPIO_Init(LED1_GPIO_PORT,&GPIO_InitStructure);
15 15     
16 16     GPIO_InitStructure.GPIO_Pin   = LED2_GPIO_PIN;
17 17     GPIO_Init(LED2_GPIO_PORT,&GPIO_InitStructure);
18 18     
19 19     GPIO_InitStructure.GPIO_Pin   = LED3_GPIO_PIN;
20 20     GPIO_Init(LED3_GPIO_PORT,&GPIO_InitStructure);
21 21 }
22 22 
23 23 void LED_Init(void)
24 24 {
25 25     LED_GPIO_Config();
26 26     
27 27     /* 关闭LED灯 */
28 28     LED1_OFF;     
29 29     LED2_OFF;
30 30     LED3_OFF;
31 31 }

bsp_LED.c

2)KEY按键初始化代码

 1 #ifndef __BSP_KEY_H
 2 #define __BSP_KEY_H
 3 #include "stm32f10x.h"
 4 
 5 /* GPIO端口宏定义 */
 6 
 7 #define KEY1_GPIO_PORT   GPIOA
 8 #define KYE1_GPIO_CLK    RCC_APB2Periph_GPIOA
 9 #define KEY1_GPIO_PIN    GPIO_Pin_0
10 
11 #define KEY2_GPIO_PORT   GPIOC
12 #define KYE2_GPIO_CLK    RCC_APB2Periph_GPIOC
13 #define KEY2_GPIO_PIN    GPIO_Pin_13
14 
15 #define KEY_ON  1
16 #define KEY_OFF 0
17 
18 /* 函数声明 */
19 void KEY_Init(void);
20 uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
21 
22 #endif

bsp_KEY.h

 1 #include "bsp_KEY.h"
 2 
 3 void KEY_Init(void)
 4 {
 5     GPIO_InitTypeDef GPIO_InitStructure;
 6     
 7     RCC_APB2PeriphClockCmd(KYE1_GPIO_CLK|KYE2_GPIO_CLK,ENABLE);
 8     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 9     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
10     
11     GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;
12     GPIO_Init(KEY1_GPIO_PORT,&GPIO_InitStructure);
13     
14     GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;
15     GPIO_Init(KEY2_GPIO_PORT,&GPIO_InitStructure);    
16 }
17 uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
18 {
19     if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON)
20     {
21         while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);
22         return KEY_ON;
23     }
24     else
25     {
26         KEY_OFF;
27     }
28 }

bsp_KEY.c

3)USART串口初始化

 1 #ifndef __BSP_USART_H
 2 #define __BSP_USART_H
 3 
 4 #include "stm32f10x.h"
 5 
 6 /* USART串口宏定义 */
 7 #define USARTx           USART1
 8 #define USARTx_CLK       RCC_APB2Periph_USART1
 9 #define USARTx_ClockCmd  RCC_APB2PeriphClockCmd
10 #define USARTx_BaudRate  115200
11 
12 /* 中断NVIC宏定义 */
13 #define NVIC_PriorityGroup_x NVIC_PriorityGroup_2
14 #define USARTx_IRQn          USART1_IRQn
15 
16 /* GPIO端口宏定义 */
17 #define USART_RX_GPIO_PORT   GPIOA
18 #define USART_RX_GPIO_CLK    RCC_APB2Periph_GPIOA
19 #define USART_RX_GPIO_PIN    GPIO_Pin_10
20 
21 #define USART_TX_GPIO_PORT   GPIOA
22 #define USART_TX_GPIO_CLK    RCC_APB2Periph_GPIOA
23 #define USART_TX_GPIO_PIN    GPIO_Pin_9
24 
25 /* 函数声明 */
26 void USART_x_Init(void);
27 static void NVIC_Config(void);
28 void USART_Send_Byte(USART_TypeDef* pUSARTx,uint8_t ch);
29 void USART_Send_String(USART_TypeDef* pUSARTx,char *str);
30 
31 #endif

bsp_USART.h

 1 #include "bsp_USART.h"
 2 #include "stdio.h"
 3 
 4 void USART_x_Init(void)
 5 {
 6     GPIO_InitTypeDef  GPIO_InitStructure;
 7   USART_InitTypeDef USART_InitStructure;
 8     
 9     /* 使能GPIO端口时钟,初始化GPIO结构体,并配置寄存器参数 */
10     USARTx_ClockCmd(USART_RX_GPIO_CLK|USART_TX_GPIO_CLK,ENABLE);
11     
12     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13     
14     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;       /* 复用推挽输出 */
15     GPIO_InitStructure.GPIO_Pin   = USART_TX_GPIO_PIN;
16     GPIO_Init(USART_TX_GPIO_PORT,&GPIO_InitStructure);
17     
18     GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING; /* 浮空输入 */
19     GPIO_InitStructure.GPIO_Pin   = USART_RX_GPIO_PIN;
20     GPIO_Init(USART_RX_GPIO_PORT,&GPIO_InitStructure);
21     
22     /* 初始化USART结构体,并配置寄存器 */
23     USARTx_ClockCmd(USARTx_CLK,ENABLE);
24     
25     USART_InitStructure.USART_BaudRate = USARTx_BaudRate;                          /* 设置波特率 */
26     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;/* 配置硬件控制流 */
27     USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;                  /* 配置工作模式,一般配置成收发一起 */
28     USART_InitStructure.USART_Parity = USART_Parity_No;                            /* 配置效验位,普通情况下设置成无效验位 */
29     USART_InitStructure.USART_StopBits = USART_StopBits_1;                         /* 配置停止位,一般设置成1位 */
30     USART_InitStructure.USART_WordLength = USART_WordLength_8b;                    /* 配置帧数据字长,如果有校验位则设置成9位,否则设置成8位即可 */
31     
32     USART_Init(USARTx,&USART_InitStructure);
33 
34     NVIC_Config();                               /* 串口中断配置 */
35     USART_ITConfig(USARTx,USART_IT_RXNE,ENABLE); /* 配置串口接收中断 */
36     USART_Cmd(USARTx,ENABLE);                    /* 使能串口 */
37 }
38 static void NVIC_Config(void)
39 {
40     NVIC_InitTypeDef  NVIC_InitStructure;
41     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_x);
42     
43     NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;         /* 配置中断源 */
44     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 设置抢断优先级 */
45     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        /* 设置子优先级 */
46     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           /* 使能中断 */
47     
48     NVIC_Init(&NVIC_InitStructure);
49 }
50 void USART_Send_Byte(USART_TypeDef* pUSARTx,uint8_t ch) /* 发送一个字节数据 */
51 {
52     
53     USART_SendData(pUSARTx,ch);/* 发送一个字节的数据 */
54     
55     while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);/* 等待发送寄存器为空 */
56 }
57 void USART_Send_String(USART_TypeDef* pUSARTx,char *str) /* 发送一个字符串 */
58 {
59     unsigned int i=0;
60     do
61     {
62         USART_Send_Byte(pUSARTx,*(str+i));
63     }while(*(str+i)!='\0');
64     while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET); /* 等待发送寄存器为空 */
65 }
66 /* 重定向c库函数printf到串口,重定向后可使用printf函数 */
67 int fputc(int ch, FILE *f)
68 {
69         USART_SendData(USARTx, (uint8_t) ch);/* 发送一个字节数据到串口 */
70         while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);    /* 等待发送完毕 */    
71         return (ch);
72 }
73 /* 重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数 */
74 int fgetc(FILE *f)
75 {
76         while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);/* 等待串口输入数据 */
77         return (int)USART_ReceiveData(USARTx);
78 }

bsp_USART.c

4)FreeRTOS配置文件(根据项目功能修改配置参数)

  1 /*
  2     FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
  3     All rights reserved
  4 
  5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
  6 
  7     This file is part of the FreeRTOS distribution.
  8 
  9     FreeRTOS is free software; you can redistribute it and/or modify it under
 10     the terms of the GNU General Public License (version 2) as published by the
 11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
 12 
 13     ***************************************************************************
 14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 15     >>!   distribute a combined work that includes FreeRTOS without being   !<<
 16     >>!   obliged to provide the source code for proprietary components     !<<
 17     >>!   outside of the FreeRTOS kernel.                                   !<<
 18     ***************************************************************************
 19 
 20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 23     link: http://www.freertos.org/a00114.html
 24 
 25     ***************************************************************************
 26      *                                                                       *
 27      *    FreeRTOS provides completely free yet professionally developed,    *
 28      *    robust, strictly quality controlled, supported, and cross          *
 29      *    platform software that is more than just the market leader, it     *
 30      *    is the industry's de facto standard.                               *
 31      *                                                                       *
 32      *    Help yourself get started quickly while simultaneously helping     *
 33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *
 34      *    tutorial book, reference manual, or both:                          *
 35      *    http://www.FreeRTOS.org/Documentation                              *
 36      *                                                                       *
 37     ***************************************************************************
 38 
 39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
 40     the FAQ page "My application does not run, what could be wrong?".  Have you
 41     defined configASSERT()?
 42 
 43     http://www.FreeRTOS.org/support - In return for receiving this top quality
 44     embedded software for free we request you assist our global community by
 45     participating in the support forum.
 46 
 47     http://www.FreeRTOS.org/training - Investing in training allows your team to
 48     be as productive as possible as early as possible.  Now you can receive
 49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
 50     Ltd, and the world's leading authority on the world's leading RTOS.
 51 
 52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 54     compatible FAT file system, and our tiny thread aware UDP/IP stack.
 55 
 56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
 57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
 58 
 59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
 60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
 61     licenses offer ticketed support, indemnification and commercial middleware.
 62 
 63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 64     engineered and independently SIL3 certified version for use in safety and
 65     mission critical applications that require provable dependability.
 66 
 67 */
 68 
 69 
 70 #ifndef FREERTOS_CONFIG_H
 71 #define FREERTOS_CONFIG_H
 72 
 73 #include "stm32f10x.h"
 74 #include "bsp_usart.h"
 75 
 76 
 77 //针对不同的编译器调用不同的stdint.h文件
 78 #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
 79     #include <stdint.h>
 80     extern uint32_t SystemCoreClock;
 81 #endif
 82 
 83 //断言
 84 #define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
 85 #define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)
 86 
 87 /************************************************************************
 88  *               FreeRTOS基础配置配置选项 
 89  *********************************************************************/
 90 /* 置1:RTOS使用抢占式调度器;置0:RTOS使用协作式调度器(时间片)
 91  * 
 92  * 注:在多任务管理机制上,操作系统可以分为抢占式和协作式两种。
 93  * 协作式操作系统是任务主动释放CPU后,切换到下一个任务。
 94  * 任务切换的时机完全取决于正在运行的任务。
 95  */
 96 #define configUSE_PREEMPTION                      1
 97 
 98 //1使能时间片调度(默认式使能的)
 99 #define configUSE_TIME_SLICING                    1        
100 
101 /* 某些运行FreeRTOS的硬件有两种方法选择下一个要执行的任务:
102  * 通用方法和特定于硬件的方法(以下简称“特殊方法”)。
103  * 
104  * 通用方法:
105  *      1.configUSE_PORT_OPTIMISED_TASK_SELECTION 为 0 或者硬件不支持这种特殊方法。
106  *      2.可以用于所有FreeRTOS支持的硬件
107  *      3.完全用C实现,效率略低于特殊方法。
108  *      4.不强制要求限制最大可用优先级数目
109  * 特殊方法:
110  *      1.必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。
111  *      2.依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。
112  *      3.比通用方法更高效
113  *      4.一般强制限定最大可用优先级数目为32
114  * 一般是硬件计算前导零指令,如果所使用的,MCU没有这些硬件指令的话此宏应该设置为0!
115  */
116 #define configUSE_PORT_OPTIMISED_TASK_SELECTION            1                       
117                                                                         
118 /* 置1:使能低功耗tickless模式;置0:保持系统节拍(tick)中断一直运行
119  * 假设开启低功耗的话可能会导致下载出现问题,因为程序在睡眠中,可用以下办法解决
120  * 
121  * 下载方法:
122  *      1.将开发版正常连接好
123  *      2.按住复位按键,点击下载瞬间松开复位按键
124  *     
125  *      1.通过跳线帽将 BOOT 0 接高电平(3.3V)
126  *      2.重新上电,下载
127  *    
128  *             1.使用FlyMcu擦除一下芯片,然后进行下载
129  *            STMISP -> 清除芯片(z)
130  */
131 #define configUSE_TICKLESS_IDLE                                                    0   
132 
133 /*
134  * 写入实际的CPU内核时钟频率,也就是CPU指令执行频率,通常称为Fclk
135  * Fclk为供给CPU内核的时钟信号,我们所说的cpu主频为 XX MHz,
136  * 就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期;
137  */
138 #define configCPU_CLOCK_HZ                          (SystemCoreClock)
139 
140 //RTOS系统节拍中断的频率。即一秒中断的次数,每次中断RTOS都会进行任务调度
141 #define configTICK_RATE_HZ                          (( TickType_t )1000)
142 
143 //可使用的最大优先级
144 #define configMAX_PRIORITIES                      (32)
145 
146 //空闲任务使用的堆栈大小
147 #define configMINIMAL_STACK_SIZE                ((unsigned short)128)
148   
149 //任务名字字符串长度
150 #define configMAX_TASK_NAME_LEN                    (16)
151 
152  //系统节拍计数器变量数据类型,1表示为16位无符号整形,0表示为32位无符号整形
153 #define configUSE_16_BIT_TICKS                    0                      
154 
155 //空闲任务放弃CPU使用权给其他同优先级的用户任务
156 #define configIDLE_SHOULD_YIELD                    1           
157 
158 //启用队列
159 #define configUSE_QUEUE_SETS                      0    
160 
161 //开启任务通知功能,默认开启
162 #define configUSE_TASK_NOTIFICATIONS    1   
163 
164 //使用互斥信号量
165 #define configUSE_MUTEXES                            0    
166 
167 //使用递归互斥信号量                                            
168 #define configUSE_RECURSIVE_MUTEXES            0   
169 
170 //为1时使用计数信号量
171 #define configUSE_COUNTING_SEMAPHORES        0
172 
173 /* 设置可以注册的信号量和消息队列个数 */
174 #define configQUEUE_REGISTRY_SIZE                10                                 
175                                                                        
176 #define configUSE_APPLICATION_TASK_TAG          0                       
177                       
178 
179 /*****************************************************************
180               FreeRTOS与内存申请有关配置选项                                               
181 *****************************************************************/
182 //支持动态内存申请
183 #define configSUPPORT_DYNAMIC_ALLOCATION        1    
184 //支持静态内存
185 #define configSUPPORT_STATIC_ALLOCATION                    0                    
186 //系统所有总的堆大小
187 #define configTOTAL_HEAP_SIZE                    ((size_t)(36*1024))    
188 
189 
190 /***************************************************************
191              FreeRTOS与钩子函数有关的配置选项                                            
192 **************************************************************/
193 /* 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子
194  * 
195  * 空闲任务钩子是一个函数,这个函数由用户来实现,
196  * FreeRTOS规定了函数的名字和参数:void vApplicationIdleHook(void ),
197  * 这个函数在每个空闲任务周期都会被调用
198  * 对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。
199  * 因此必须保证空闲任务可以被CPU执行
200  * 使用空闲钩子函数设置CPU进入省电模式是很常见的
201  * 不可以调用会引起空闲任务阻塞的API函数
202  */
203 #define configUSE_IDLE_HOOK                        0      
204 
205 /* 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子
206  * 
207  * 
208  * 时间片钩子是一个函数,这个函数由用户来实现,
209  * FreeRTOS规定了函数的名字和参数:void vApplicationTickHook(void )
210  * 时间片中断可以周期性的调用
211  * 函数必须非常短小,不能大量使用堆栈,
212  * 不能调用以”FromISR" 或 "FROM_ISR”结尾的API函数
213  */
214  /*xTaskIncrementTick函数是在xPortSysTickHandler中断函数中被调用的。因此,vApplicationTickHook()函数执行的时间必须很短才行*/
215 #define configUSE_TICK_HOOK                        0           
216 
217 //使用内存申请失败钩子函数
218 #define configUSE_MALLOC_FAILED_HOOK            0 
219 
220 /*
221  * 大于0时启用堆栈溢出检测功能,如果使用此功能 
222  * 用户必须提供一个栈溢出钩子函数,如果使用的话
223  * 此值可以为1或者2,因为有两种栈溢出检测方法 */
224 #define configCHECK_FOR_STACK_OVERFLOW            0   
225 
226 
227 /********************************************************************
228           FreeRTOS与运行时间和任务状态收集有关的配置选项   
229 **********************************************************************/
230 //启用运行时间统计功能
231 #define configGENERATE_RUN_TIME_STATS            0             
232  //启用可视化跟踪调试
233 #define configUSE_TRACE_FACILITY                      0    
234 /* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
235  * prvWriteNameToBuffer()
236  * vTaskList(),
237  * vTaskGetRunTimeStats()
238 */
239 #define configUSE_STATS_FORMATTING_FUNCTIONS    1                       
240                                                                         
241                                                                         
242 /********************************************************************
243                 FreeRTOS与协程有关的配置选项                                                
244 *********************************************************************/
245 //启用协程,启用协程以后必须添加文件croutine.c
246 #define configUSE_CO_ROUTINES                       0                 
247 //协程的有效优先级数目
248 #define configMAX_CO_ROUTINE_PRIORITIES       ( 2 )                   
249 
250 
251 /***********************************************************************
252                 FreeRTOS与软件定时器有关的配置选项      
253 **********************************************************************/
254  //启用软件定时器
255 #define configUSE_TIMERS                            0                              
256 //软件定时器优先级
257 #define configTIMER_TASK_PRIORITY                (configMAX_PRIORITIES-1)        
258 //软件定时器队列长度
259 #define configTIMER_QUEUE_LENGTH                10                               
260 //软件定时器任务堆栈大小
261 #define configTIMER_TASK_STACK_DEPTH          (configMINIMAL_STACK_SIZE*2)    
262 
263 /************************************************************
264             FreeRTOS可选函数配置选项                                                     
265 ************************************************************/
266 #define INCLUDE_xTaskGetSchedulerState       1                       
267 #define INCLUDE_vTaskPrioritySet                 1
268 #define INCLUDE_uxTaskPriorityGet                 1
269 #define INCLUDE_vTaskDelete                           1
270 #define INCLUDE_vTaskCleanUpResources           1
271 #define INCLUDE_vTaskSuspend                       1
272 #define INCLUDE_vTaskDelayUntil                     1
273 #define INCLUDE_vTaskDelay                           1
274 #define INCLUDE_eTaskGetState                       1
275 #define INCLUDE_xTimerPendFunctionCall         0
276 //#define INCLUDE_xTaskGetCurrentTaskHandle       1
277 //#define INCLUDE_uxTaskGetStackHighWaterMark     0
278 //#define INCLUDE_xTaskGetIdleTaskHandle          0
279 
280 
281 /******************************************************************
282             FreeRTOS与中断有关的配置选项                                                 
283 ******************************************************************/
284 #ifdef __NVIC_PRIO_BITS
285     #define configPRIO_BITS               __NVIC_PRIO_BITS
286 #else
287     #define configPRIO_BITS               4                  
288 #endif
289 //中断最低优先级
290 #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15     
291 
292 //系统可管理的最高中断优先级
293 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5 
294 
295 #define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )    /* 240 */
296 
297 #define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
298 
299 
300 /****************************************************************
301             FreeRTOS与中断服务函数有关的配置选项                         
302 ****************************************************************/
303 #define xPortPendSVHandler     PendSV_Handler
304 #define vPortSVCHandler     SVC_Handler
305 
306 
307 /* 以下为使用Percepio Tracealyzer需要的东西,不需要时将 configUSE_TRACE_FACILITY 定义为 0 */
308 #if ( configUSE_TRACE_FACILITY == 1 )
309 #include "trcRecorder.h"
310 #define INCLUDE_xTaskGetCurrentTaskHandle       1   // 启用一个可选函数(该函数被 Trace源码使用,默认该值为0 表示不用)
311 #endif
312 
313 
314 #endif /* FREERTOS_CONFIG_H */

FreeRTOSConfig.h

5)主函数程序文件

  1 #include "stm32f10x.h"
  2 
  3 //FreeRTOS相关头文件
  4 #include "FreeRTOS.h"
  5 #include "task.h"
  6 
  7 //bsp硬件外设头文件
  8 #include "bsp_LED.h"
  9 #include "bsp_KEY.h"
 10 #include "bsp_USART.h"
 11 #include "stdio.h"
 12 
 13 //任务句柄---------------------------------------------------------------------------------------
 14 static TaskHandle_t AppTaskCreate_Handle = NULL ;  /*创建任务句柄*/
 15 static TaskHandle_t LED1_Task_Handle = NULL ;      /* 创建LED任务句柄 */
 16 static TaskHandle_t KYE_Task_Handle = NULL ;       /* 创建KEY任务句柄 */
 17 //全局变量---------------------------------------------------------------------------------------
 18 //函数声明---------------------------------------------------------------------------------------
 19 static void AppTaskCreate(void);                  /* 用于创建任务的函数 */
 20 static void LED1_Task(void* pvParameters);        /* LED1_Task任务的实现 */
 21 static void KEY_Task(void* pvParameters);         /* KEY_Task任务的实现 */
 22 static void BSP_Init(void);                       /* 初始化硬件外设 */
 23 
 24 int main(void)
 25 {
 26     BaseType_t xReturn = pdPASS; /* 定义一个创建信息返回值,默认为 pdPASS */
 27     BSP_Init();
 28     printf("这是一个FreeRTOS-多任务创建实验!\r\n");
 29     /* 创建 AppTaskCreate 任务 */
 30     xReturn = xTaskCreate((TaskFunction_t ) AppTaskCreate,          /* 任务入口函数 */
 31                         (const char*    ) "AppTaskCreate",        /* 任务名字 */
 32                         (uint16_t       ) 512,                    /* 任务栈大小 */
 33                         (void*          ) NULL,                   /* 任务入口函数参数 */
 34                         (UBaseType_t    ) 1,                      /* 任务的优先级 */
 35                         (TaskHandle_t*  ) &AppTaskCreate_Handle); /* 任务控制块指针 */
 36     /* 启动任务调度 */
 37     if (xReturn == pdPASS)
 38     {
 39         vTaskStartScheduler();/* 启动任务,开启调度 ,自动创建一个空闲任务 */
 40     }        
 41     else
 42     {
 43         return -1;
 44     }
 45     while(1); /* 正常不会执行到这里 */
 46 }
 47 /***********************************************************************
 48   * @ 函数名  : BSP_Init
 49   * @ 功能说明: 为了方便管理,所有的硬件初始化函数都放在BSP_Init中
 50   * @ 参数    : 无  
 51   * @ 返回值  : 无
 52   **********************************************************************/
 53 static void BSP_Init(void)
 54 {
 55     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); /* STM32中断优先级分为4,则用4bit来表示抢占优先级,范围为0-15 */
 56     LED_Init();                                     /* 初始化LED */
 57     KEY_Init();                                     /* 初始化KEY */   
 58     USART_x_Init();                                 /* 初始化串口*/
 59 }
 60 
 61 /***********************************************************************
 62   * @ 函数名  : AppTaskCreate
 63   * @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
 64   * @ 参数    : 无  
 65   * @ 返回值  : 无
 66   **********************************************************************/
 67 static void AppTaskCreate(void)
 68 { 
 69   BaseType_t xReturn = pdPASS;     /* 定义一个创建信息返回值,默认为 pdPASS */
 70     taskENTER_CRITICAL();            /* 进入临界区 */
 71     /* 创建任务1 */
 72   xReturn = xTaskCreate((TaskFunction_t )LED1_Task,          /* 任务入口函数 */
 73                         (const char* )"LED1_Task",           /* 任务名字 */
 74                         (uint16_t )512,                      /* 任务栈大小 */
 75                         (void* )NULL,                        /* 任务入口函数参数 */
 76                         (UBaseType_t )2,                     /* 任务的优先级 */
 77                         (TaskHandle_t* )&LED1_Task_Handle);  /* 任务控制块指针 */
 78   if (pdPASS == xReturn)
 79     {
 80         printf("创建 LED1_Task 任务成功!\r\n");
 81     }
 82     /* 创建任务2 */
 83     xReturn = xTaskCreate((TaskFunction_t )KEY_Task,           /* 任务入口函数 */
 84                         (const char* )"KEY_Task",            /* 任务名字 */
 85                         (uint16_t )512,                      /* 任务栈大小 */
 86                         (void* )NULL,                        /* 任务入口函数参数 */
 87                         (UBaseType_t )3,                     /* 任务的优先级 */
 88                         (TaskHandle_t* )&KYE_Task_Handle);   /* 任务控制块指针 */
 89   if (pdPASS == xReturn)
 90     {
 91         printf("创建 KEY_Task 任务成功!\r\n");
 92     }
 93     vTaskDelete(AppTaskCreate_Handle); /* 删除 AppTaskCreate 任务 */
 94     taskEXIT_CRITICAL();               /* 退出临界区 */
 95 }
 96 /**********************************************************************
 97   * @ 函数名  : LED1_Task
 98   * @ 功能说明: 实现LED灯的定时闪烁
 99   * @ 参数    :   
100   * @ 返回值  : 无
101   ********************************************************************/
102 static void LED1_Task(void* pvParameters)
103 {
104     while(1)
105     {
106         LED2_ON;
107         vTaskDelay(500);/* 延时500个tick */
108         LED2_OFF;
109         vTaskDelay(500);
110     }
111 }
112 /***********************************************************************
113   * @ 函数名  : KEY_Task
114   * @ 功能说明: 实现了按键的检测,实现任务的挂起和恢复
115   * @ 参数    : 无  
116   * @ 返回值  : 无
117   **********************************************************************/
118 static void KEY_Task(void* pvParameters)
119 {
120     while(1)
121     {
122         if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON)
123         {
124             printf("挂起LED任务\n");
125             vTaskSuspend(LED1_Task_Handle);/* 挂起 LED 任务 */
126         }
127         if(Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON)
128         {
129             printf("恢复LED任务\n");
130             vTaskResume(LED1_Task_Handle);/* 恢复 LED 任务! */
131         }
132         vTaskDelay(20);
133     }
134 }

main.c

6)按下KEY1挂起任务,按下KEY2恢复任务,串口输出信息如下:

版权声明:本文为pathfinder-world原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/pathfinder-world/p/13921895.html