STM32CubeMX的设置变化
+ T* E( r6 i0 R1 ?2 F: S9 y4 ~4 k- t1.Pinout 中使能 FreeRTOS
9 T* S, c" Z+ X* E- B, T, e# I0 I' }/ c* s
7 D- T. v, h$ a6 _, N, K
5 ?5 ?8 ~# N2 y- ?( E! ~
2.Configuration 中配置 FreeRTOS( @8 t9 }# p5 h3 X4 f) J% o6 Y
3 x4 d, {# B3 l" c X
9 N9 Y" b/ t4 X8 c5 L9 A
3.添加任务
6 p' D0 Y6 d3 G0 c5 U. y# B h1 t- J$ h5 X: }
' }4 n0 X E5 I, a; k
. }+ I( r3 m/ `4.生成代码
) Z+ n* j" z u, l3 P; f' y* L F# t3 M, G! Q5 r& p
a5 a# Z6 u) y5 b9 [$ c: b7 ^+ qKeil5 中编辑代码5 ^0 x( P) }1 J9 e" m& f' [: }
main 函数
1 _; W7 Y# z4 Y4 }7 g0 W2 P- r- _- int main(void)9 K; c3 E. t B( j4 D" w
- {! G4 f* g; c5 }0 `" e7 X( R
- /* USER CODE BEGIN 1 */
( \3 k6 C2 T, i
: `' v* G2 j/ }* E3 Q4 ^4 i- /* USER CODE END 1 */
6 m9 ]3 n6 {/ F - / w. k% R" b( R% k1 o
- /* MCU Configuration----------------------------------------------------------*/
2 @& |- o& m# q4 \
& D# p* W& v6 `/ \- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
! x/ }. [) n \) E) c - HAL_Init(); /* 硬件抽象层 */
$ D- Q5 k! b( H2 I4 E - 8 m% W: Z( r$ r* k9 [# J
- /* USER CODE BEGIN Init */
6 Z5 \$ w5 O7 j9 k% y* h
" @" b. o p; q; r* ~: @- /* USER CODE END Init */0 b$ A6 X. M2 p3 v
* M! e1 t, D) Z- /* Configure the system clock */' z. l P. U7 _* X/ J! g
- SystemClock_Config(); /* 时钟 */
4 _' ?& y1 N6 d8 `' g - 0 P- Q8 b$ N/ a# @- b. K" T
- /* USER CODE BEGIN SysInit */) X* ~ _ _# A& A. O
8 o9 G, Y4 O* l+ L' N/ ~8 ?/ Y: N- /* USER CODE END SysInit */. p9 ]* y8 V7 f, i9 j1 n7 e: D
- /* Initialize all configured peripherals */
3 @; W( i* }/ S7 r1 f - MX_GPIO_Init(); /* STM32CubeMX生成的GPIO初始化函数 */3 _5 s a3 f5 O/ s9 A
- MX_USART1_UART_Init(); /* STM32CubeMX生成的USART1初始化函数 */) M b) @* U/ }4 b
- MX_USART2_UART_Init(); /* STM32CubeMX生成的USART2初始化函数 */* Q# e) ~" ~2 Z; p; _
- /* USER CODE BEGIN 2 */
( C' W5 u. X+ r) V- A - printf("\n\r Creating Task1 \n\r"); /* 我添加的语句。在串口初始化结束后从串口输出的字符。*/
; ]( Z" P" e% V$ u4 J' c1 e9 n - /* USER CODE END 2 */, T- s* v( n6 r; u2 |
- & S( @2 l6 J6 Y. E( h' i
- /* Call init function for freertos objects (in freertos.c) */& i1 ], R! ]1 ]# U6 J- \
- MX_FREERTOS_Init(); /* STM32CubeMX生成的操作系统内核初始化函数 */1 m- S8 _( S9 n l2 Z
2 {9 F. I1 e" Y, Y3 S2 L* N- /* Start scheduler */. ^# `# _ A& u; F$ z1 @
- osKernelStart(); /* 启动调度器 , 由调度器控制任务执行。下面的 while() 语句是走不到了*/
* g4 f1 |) B( g, n& j8 M6 g# q
g6 V7 [! m. I% v& P3 L' Z- /* We should never get here as control is now taken by the scheduler */, f2 x& i! |( \& V
5 S$ _% I- F# X+ t* p! n' Q- u- /* Infinite loop */7 ?+ m3 s/ [4 y% g( M/ o2 ]& C8 Y- ^
- /* USER CODE BEGIN WHILE */( T8 L! d+ h/ |/ ?& x& h7 ^
- while (1)
& {% p& s3 |1 R3 A3 Z - {
: d% f; N Z8 Z& d: | - + u1 I9 m, }& \/ D# A
- /* USER CODE END WHILE */% X8 M, y; n' V% R5 G: B' b9 _! K
- - X% G* n5 O# d
- /* USER CODE BEGIN 3 */0 F p; i3 B4 n2 z6 w7 O5 W9 O* I) v% b
- / c7 i3 N' B; i$ y
- }# z% z; K* n u( I# z3 X/ b
- /* USER CODE END 3 */# B8 j+ [$ _3 g4 m9 r
- 7 \. j. E2 J& G5 n7 i' q+ F( L. A
- }
复制代码 0 F) a3 w% ^4 `7 R2 H: v
freertos.c. m+ o" J" N0 g) y7 S8 q, B- A
增加包含头文件$ ]0 D# h( B0 m6 k+ I3 N6 A
- /* Private includes ----------------------------------------------------------*/
4 ?8 c1 b3 `" Q4 v$ k* t - /* USER CODE BEGIN Includes */
4 f$ ^" T& W/ |( y" E) v" D - #include "stm32f0xx_hal.h" /* 我增加的,否则不认识 printf */
! q8 r3 I- U. `# [5 m; h: r - . s- S! P# f, r" n1 T
- /* USER CODE END Includes */
复制代码
- ?7 U* Z* F/ m, mSTM32CubeMX 定义的任务句柄
1 ?7 ? l+ w G# y- osThreadId defaultTaskHandle; /* 缺省的空闲任务句柄 */$ `' U* h6 ]( t$ n' g- i! K5 f& O1 t
- osThreadId myTask1Handle; /* 我需要的 myTask 1 任务句柄 */
复制代码
S: n5 }8 d% A3 l' G6 {( X- ISTM32CubeMX 声明的任务函数原型! p! z9 Q' n0 [9 S1 }
- void StartDefaultTask(void const * argument);
3 `! z4 f* c4 ?* M; Z - void StartTask1(void const * argument);
复制代码
( J" D+ E2 q/ J4 [9 z% ~. cSTM32CubeMX 定义和创建的任务
4 K: F$ ?) }( f4 j+ ?' S! @$ @- /* definition and creation of defaultTask */
. i& x [4 u. z' Z* P - osThreadDef(defaultTask, StartDefaultTask, osPriorityIdle, 0, 128); : ]$ H! S7 r9 o9 N' [! F
- defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
' p( W4 m7 z5 v* R2 G
% T; y# M$ A* ^+ [% f- /* definition and creation of myTask1 */* r2 G' s7 ^: T5 q' d" z
- osThreadDef(myTask1, StartTask1, osPriorityNormal, 0, 128); Y: B9 K6 {6 y& H$ T* j5 E3 _
- myTask1Handle = osThreadCreate(osThread(myTask1), NULL);! {* c, ]7 V+ z2 B5 w
复制代码 2 {) Q; R( \) @9 {* t- o. ^4 N
空闲任务啥也没干
! I$ A3 n/ _0 i- void StartDefaultTask(void const * argument)
! ?) \9 W& a9 ~ - {
3 z" U- |" \4 k, m* j
' g) A$ U" u2 _ B. |- /* USER CODE BEGIN StartDefaultTask */
& r4 a V0 B7 F4 a2 P3 Z) Y0 N- |8 \ - + O" g" D6 g+ c( H. E3 W- m- ]: |
- /* Infinite loop */
8 c2 B2 {, p! {% v: x2 A - for(;;)
# p& M# u6 a: x# f - {
: y/ S6 x$ G# H! y -
{' z' F+ X& `0 b - osDelay(1);
0 s4 \: h. W; x+ o+ } - }
) h2 T! H3 b& C2 @! d; X - /* USER CODE END StartDefaultTask */, L9 P/ X5 C8 E+ v# {! \& w
- }
复制代码
K& S0 M) {2 X; A1 x( u任务1输出字符串
5 Y+ C5 `; i9 Z+ l' B3 ?. c/ p" R- void StartTask1(void const * argument)- J3 [4 r# e6 K# g: E+ Q- u/ S( Y
- {
: z" ?. f, M5 f9 P! O/ I0 J( T* T: Z - /* USER CODE BEGIN StartTask1 */
4 l# \. M2 P$ g+ J- e( [ - /* Infinite loop */
* @8 I* C/ I7 F1 e8 i - for(;;)
# P, a5 ^0 P& J- u$ R8 H - {+ f5 e* ?6 {( H
- printf("Task 1 is runing \r\n"); /* 已经重定向printf到USART2,参见《用STM32Cube+Keil5对STM32F0编程之通过USART发送数据》](<a href="https://blog.csdn.net/aLife2P6/article/details/82918298" target="_blank">https://blog.csdn.net/aLife2P6/article/details/82918298</a>) */
" y! i2 N% q6 u% j. f/ n - osDelay(3000); /* 延时3s */1 ]/ I6 N% }# o$ Y. u
- }
8 l* n0 U/ R0 P& ^ - /* USER CODE END StartTask1 */
9 ~5 v: y, v7 I& X6 i X - }
复制代码 + j+ A) Q3 P j* b) ~ {1 d
编译链接 Project/Build Target5 Q3 o f3 v, p
7 R3 B( X1 L6 r% Y V# h# A8 |/ J9 z, I y3 v, E
5 G& P, c( {: \# E- _5 e烧录程序 Flash/Download
/ `- n# b* p# Q$ {$ o+ Y( H# \, r3 f3 o; @( S
0 l9 K" R! d: P4 {" L! C7 g. A; z
- g) p. H4 S: v4 w h" Q3 @运行效果) d) A' _( y1 N* m9 ?: x
0 [/ w7 e' h1 H0 t# z5 ^* b& c3 g/ E: i2 {2 M1 {- _
$ }9 w, R* [5 j# E3 i! W& l
; ]! v$ D. b7 H+ z# `/ P |