生成例程7 C# p! \/ C1 \; z
使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板
. W' w3 H6 H% E. H3 g G3 e5 q: n% |$ V: z! k5 J
1 [$ p; C/ y. O
: _' M( E# e7 S2 z- A3 E: j查看原理图,PA2和PA3设置为开发板的串口。# |9 B) H) Z( u5 s1 G" y
( _4 V5 I! P ?$ R* P( e
. }4 F, \7 @: E7 o% H6 A: ^
! ?0 Y7 e) x4 @- ]6 i
配置串口。
$ j8 H5 p$ r# x" ^" Z, \ E- Q1 x/ n, R; A- w$ |- O
7 J: Y( j9 x8 E t* @) r$ ?
6 l& ^/ N! V* f+ ]; ~5 M) L: O
开启中断。
& r0 f! ^! i( o5 q. W
+ O R. o& A0 u; o x
; {5 G7 P' _7 \, N7 R( i/ d' S) Y
开启DMA读取和接收。# l5 ]9 m" t6 e' b6 I
其中Word = 32bit,Half word = 16bit,Byte = 8bit
% X+ K- _: V9 \. W$ C! S7 @1 g& G
6 t( j$ W4 f. d
+ z; o- _' b1 P1 T
]0 [$ S+ j0 H! R$ d
STM32CUBEIDE配置, y9 m: \: x2 T$ O# R: ?* d
/ }' g: b9 }5 i
# I. w# b% }4 n3 W" v: n% b
( c& H1 u) Y- ~. X若需要打印浮点型,需要勾选下面的选项。- p( L) r Z) u; Y9 q, z3 l. V
, H; r0 N$ S; w( w' o/ a0 w
8 L( N5 I. G$ ?, W. }/ T9 M/ M0 F1 y I4 V# {. s+ R) f
串口重定向
' y7 b0 \- P) }5 Z% H y在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。- ^# L& p1 U3 r
# J5 R4 |6 U# i6 A; B" } s
- /* USER CODE BEGIN Includes */
0 {! ]! K& x0 Y/ C* U. L' c: D - #include "stdio.h"
0 B$ o. ]9 q0 S4 g- ] - /* USER CODE END Includes */
复制代码 ( O4 @) o9 U/ [' S) j
函数声明和串口重定向:
- Q0 r% {8 |% B0 F+ R: ^2 b/ P5 }; X0 d& R: e+ v
- /* USER CODE BEGIN PFP */$ V" p7 H5 U+ y3 A0 {" P0 \
- #ifdef __GNUC__ //串口重定向& l1 q' m- t t, |# `
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)- d7 Y: e+ @1 T. f! s
- #else
% M& x2 {! G8 ` - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
6 E! b6 @" K3 Z - #endif / I) u; Z) }/ p f% X! x e
- PUTCHAR_PROTOTYPE
; j8 {# Z0 n+ F) u4 E4 i - {
' |0 D, N/ @3 G7 [ b9 Q" l! F - HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);
q4 g) M3 j8 Q - return ch;) ~, d0 q1 }2 N# ~5 N
- }
( o5 B! C1 |& { - /* USER CODE END PFP */
复制代码 3 m/ R. ?' R! U: U* N
串口发送接收函数
% g' A2 z: i- k9 b& B. _3 Q一般情况下,串口发送接收函数有如下所示。7 k6 D2 @8 A7 g" r) C2 \' ~2 j& ^" Y
● HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制。% o+ K5 j K" |) `" i
● HAL_UART_Receive();串口轮询模式接收,使用超时管理机制。
+ d4 F4 X0 B4 o! c9 y$ m: H6 \● HAL_UART_Transmit_IT();串口中断模式发送
1 l5 b6 h$ r. {; A) ~● HAL_UART_Receive_IT();串口中断模式接收4 ~; y' h$ L6 e9 [
● HAL_UART_Transmit_DMA();串口DMA模式发送* o# l6 @8 J. @3 E
● HAL_UART_Receive_DMA();串口DMA模式接收; S0 S7 w, ^5 e' }: F: r: ]
* J ^. T0 s& n0 h
HAL_UART_Transmit_DMA()发送: K+ q$ ?! W* @6 V1 T
测试代码如下。
% p# E' `, b1 S H" d% u6 v定义需要发送的数据。" J8 |! M9 n# r# i2 F5 V
1 B, B* R" @7 Q3 {. x2 Z
- /* USER CODE BEGIN PV */; {" H6 [( s6 m5 o
- uint8_t TxData[] = "\r\n**** Hello,World!' ***\r\n";" H2 b* ^# ?) o h: Z; ^6 u
- /* USER CODE END PV */
复制代码 $ Y ^8 `& f- l9 F( p/ h: f T
HAL_UART_Transmit_DMA()发送代码。- /* USER CODE BEGIN WHILE */8 v0 X2 E( Y4 x
- while (1)8 {2 L3 G& U( {/ Y) _; {. T
- {
; l" C; ^* k, x) R) J( M - /* USER CODE END WHILE */& j% o) [8 T3 w% Y& E8 `
- 2 X5 }" H) c; Y9 D7 |4 U4 S) ~
- /* USER CODE BEGIN 3 */
2 I/ E" B/ E0 W8 ~& |2 v* D$ I! I - HAL_UART_Transmit_DMA(&huart2, (uint8_t *)TxData, sizeof(TxData)-1);- j! L( Y* ], g# P6 k% F
- HAL_Delay(1000);
3 {5 `" n2 L( C% w+ M - }
' R J' T5 }# c1 Q+ v# i' R - /* USER CODE END 3 */
复制代码
. y' y# f2 ]3 {( ?/ W' |DMA有normal和circular两种模式。
$ w) G3 V5 L0 RNormal表单次传输,传输一次后终止传输,所以需要传输几次就需要开启几次,Circular表示循环传输,传输完成后又重新开始继续传输,开启一次后会一直传输。
8 ]. f# b- G" ]1 i/ r0 [. fnormal传输打印如下所示,传输完成就关闭。
3 }7 y/ {$ x# C6 M Z; x, @' N8 Q9 X0 e6 `. d
% [, g( Q6 r8 ~7 M/ y: W
$ ^" ]9 f9 J) V( _
circular传输打印如下所示,一直传输,不会停止。, m @9 D) j( R$ _5 c) r
/ E7 U+ e9 G" K! ^* w/ [2 V, D5 Q3 }
: E: A- @' M" t! [
, O. c: H$ K2 \) @HAL_UART_Receive_DMA()发送* c9 W1 L3 b' p+ ]/ D1 h' C
测试代码如下。0 N" v7 {: \& E- K8 y; ~
定义需要接受存放数组。
& R- ]1 G2 ~" r$ J( B8 Y3 M i* Z$ n! F# N
- /* USER CODE BEGIN PV */5 S: P$ w$ a2 z% q6 {- c% D
- uint8_t RxData[255];
1 }; P, S* Y% b# Q! Y - /* USER CODE END PV */
复制代码
- H8 T9 `! h- H9 N n& F/ G开启HAL_UART_Receive_DMA()接受代码。
1 V2 b* L! U' Z* l8 P- W0 a ]
) U# v- G4 u/ ^9 Y7 H- /* USER CODE BEGIN 2 */
0 v6 K/ |) E& G5 t4 j% [ - HAL_UART_Receive_DMA(&huart2, RxData, 10); // 这里加这个函数,接收数据
8 z' x* U8 ~3 ~ g0 [% ^ - /* USER CODE END 2 */
复制代码
( y& l, Q) I' R3 A, y8 C5 b重写读取回调函数,将接受的数据发送出去在开启接收。
6 ^) A6 u: r& U
- {, V; B9 F n+ Q7 _- /* USER CODE BEGIN 4 */ A# r C! t/ N
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+ x% e% s1 d) \1 v2 D: |. A5 V - {
5 H v9 a& E2 C! S( |7 y/ I - " ^. V! Q% |; B8 e; _( _
- HAL_UART_Transmit(&huart2, (uint8_t *)"text:", 5,0xffff);//轮询发送,不然可能发送不出去
; @2 g5 F/ {7 ^9 \ - HAL_UART_Transmit_DMA(&huart2, (uint8_t *)RxData, 10);//发送接受的数据
' S& p3 U1 p1 ?- c2 x5 C - HAL_UART_Receive_DMA(&huart2, RxData, 10); // 这里加这个函数,接收数据% |0 c0 v$ g" ^ L6 e
- }
4 \$ V/ e8 c- w6 T' l8 m( i - 3 J6 W3 [$ C% G
- /* USER CODE END 4 */
复制代码
6 e! T' y+ x# B2 aDMA有normal和circular两种模式。' U2 l2 a& }" B
Normal表单次接收,接收一次后终止接收,所以需要接收几次就需要开启几次,Circular表示循环接收,接收完成后又重新头开始继续接收,开启一次后会一直接收。
. s# U, N( r! E% `! J/ t ynormal传输打印如下所示,传输完成就关闭。
/ y7 D4 `$ L+ O2 J$ V) P: |演示效果如下所示。# z% r2 ^! B% \* `
/ [) W. Q: u9 d
$ F# X: R# Q& e5 y1 C4 G
U+ o! s4 c& g3 I+ c9 t% c% g" bcircular接收打印如下所示,当发送数据大于接收长度时候,会进行循环接收。9 _$ i9 q" j b# c! T! Z5 ?
* ^( |- V3 y; S2 m5 x" w
* ?! V9 V9 X7 Y" R; b; I
4 f# U) ~7 w8 c" g1 Z————————————————
`0 M2 K- U6 C m8 |2 b( s版权声明:记帖
6 l J; u2 h9 W4 n& ]6 N- x
( a2 a& l) T( K9 D
4 P) i- G; ]' \! a. v) `& p0 A0 V |