"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
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 }
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
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 }
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
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 }
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 */
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 }
6)按下KEY1掛起任務,按下KEY2恢復任務,串列埠輸出資訊如下: