概述
7 h" f$ W1 S1 o: o6 Q" e* y. e本章STM32CUBEMX配置STM32F103,并且在GD32F303中进行开发,同时通过GD32303C_START开发板内进行验证。# ^& u [4 c- z% a& I8 o
本章主要配置串口进行DMA收发。% W) P7 l! G* k
需要GD样片的可以加Q_QUN申请:6_15061293。5 Q' s. d5 j' e/ ]
2 q7 p+ A4 B( [7 U4 u$ `查阅手册可以得知,PA9、PA10为串口0的输出和输入口。
. C0 [# c8 V+ r, L e
( t- J& f5 b# c8 g( u$ D* ~
# W$ p% d, z! }* P" m( M' s' D7 q1 @: L; L- Z, N
硬件准备, g+ U# l9 L7 U/ P6 Y
这里准备了GD32303C_START开发板进行验证。
6 S7 a' i/ k( d. [0 K6 G$ ^: l. U9 y' S/ F" |
( _6 C, }" `& d& U9 N
5 A3 x2 o" T7 l: M6 z# \* ^STM32CUBEMX配置
, Z9 c: S7 [7 z$ E; R T2 X+ U3 x
1 ?# L7 c0 W/ _- i' }0 l/ X3 Y% x+ {
3 v( f" D$ R4 L$ ~7 _& ^2 x5 i
' f+ Q8 s- y. u% H勾选中断。
. t$ Y$ v1 `& p$ {. A* ~+ |- x
: r( s! }9 e0 E: h& Z' n
! x+ M9 S! T$ ]1 w3 a; @( P( f. h
开启DMA读取和接收。
: ^3 |9 i: ~* C其中Word = 32bit,Half word = 16bit,Byte = 8bit# w) I, y, c, R; x* W2 Y
" i3 w0 n" Z4 ]
3 Q! D T7 P% D7 y5 x8 o$ P; X) }( {" m/ A+ d' f$ } v: W
0 n: V( H0 f: k% F) J* p0 |) g* t
|" ~0 v- S/ [! V V0 U8 L; [
g" ?, R8 t* Q( }keil配置* J% V; h5 J# P) P- k
microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,如果要使用printf(),必须开启。
4 Q" a1 E( D% C" R7 j3 j) u9 q6 v7 S- |' B1 S/ g1 n3 h
. c" U, Z! Z0 k6 M
( S/ G0 a/ l& ^: W串口重定向9 t, ^/ A) o) |+ \8 i* Z
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。" H* K) z& t, X! U
# N# F0 L$ z( J( b
- /* USER CODE BEGIN Includes */4 Q" q! ]$ }# ^" m. p/ _# Y
- #include "stdio.h"
" ?; |% L8 ~; |5 y$ a1 F. d4 s - /* USER CODE END Includes */
复制代码 3 p" H c& X( j0 A
函数声明和串口重定向:4 F+ P0 _! g5 {- O3 o0 e5 p5 j
, y+ |- |+ ]: R. A; `3 i8 W
- /* USER CODE BEGIN PFP */
/ b3 ?" e2 c* c: ~ - #ifdef __GNUC__ //串口重定向
0 Y9 U/ v; w3 q1 Q" \. I0 D' q - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
8 P0 F, a& u' p5 A% b8 r" Z8 Z, R) }& K% d - #else! d) ]- }& C# j: l
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
' {- q* c+ P9 D2 v - #endif 1 v. ~6 f- ^1 q; o }
- PUTCHAR_PROTOTYPE
. Q0 u% ?# J6 N+ P) l - {+ `; q" s$ C( Y" o, F) y! w
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
0 v5 M8 U! r- J: `' W - return ch;
, u% c& R; C C) L/ \ - }8 O; A* I" F( L+ o
- /* USER CODE END PFP */
复制代码 4 g/ H. S. ~6 Z0 Z
串口接收发送函数
5 |7 y0 g7 _9 Y- C& u2 t. ` S一般情况下,串口接收发送函数有如下所示。
m4 |3 V+ A+ ~● HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制。& o- h, S i# [5 U2 X2 v. ]
● HAL_UART_Receive();串口轮询模式发送,使用超时管理机制。
6 e6 H5 j/ L6 g: y& \7 A; t● HAL_UART_Transmit_IT();串口中断模式发送, n( u7 q+ @: Q* O
● HAL_UART_Receive_IT();串口中断模式接收
7 ^7 [( L8 k! K$ i" ]4 o3 p- o/ j( [● HAL_UART_Transmit_DMA();串口DMA模式发送
& y$ V2 v% d6 R3 `8 l; a4 @# C2 L● HAL_UART_Receive_DMA();串口DMA模式接收
+ @ e" T6 n; Q8 }8 T/ N4 T! Y( d' T) T* a3 }
HAL_UART_Transmit_DMA()发送6 ~ n( q. k0 u2 l- c& I
测试代码如下。
; M& |7 Q) [" O( r/ Q定义需要发送的数据。. }- Z. t: D7 h
( q3 q6 j1 Q- a, j. |- /* USER CODE BEGIN PV */# e) d, ~* h& O5 u; a
- uint8_t TxData[] = "\r\n**** Hello,World!' ***\r\n";6 u$ w( Z( }& P! {
- /* USER CODE END PV */
复制代码
$ ]# ?1 ?2 ?* {) E* ^) h" ~HAL_UART_Transmit_DMA()发送代码。
5 H8 K4 l: O5 h9 X4 l5 Q) s2 s1 m V. q8 ?7 H* ~" E
- /* USER CODE BEGIN WHILE */
?+ u% z" u5 n6 D2 g$ ]$ S1 m9 V - while (1)
+ e6 i) f: o$ D- ?5 Q9 h. f2 r2 P/ N - {
! o$ [! W! ]3 A; A- | - /* USER CODE END WHILE */+ ]% {" Y4 d' ]5 Z* q: P( G1 n
- - s7 D$ \. C: X1 J' C, O' m
- /* USER CODE BEGIN 3 */1 C" @( y( X( S
- HAL_UART_Transmit_DMA(&huart1, (uint8_t *)TxData, sizeof(TxData)-1);1 t5 D- }) o8 K
- HAL_Delay(1000);. C( |" u g3 a
- }
0 p: \- [( F; o t9 U - /* USER CODE END 3 */
复制代码
3 b( d1 u8 L. n# IDMA有normal和circular两种模式。
* f# N6 W7 v# e" }Normal表单次传输,传输一次后终止传输,所以需要传输几次就需要开启几次,Circular表示循环传输,传输完成后又重新开始继续传输,开启一次后会一直传输。1 I* X# f2 f! Q' v3 W
normal传输打印如下所示,传输完成就关闭。: q {+ c% r4 L& n: E/ ]& X9 o- N
& B3 t* Z' w( ]3 H5 }7 L
+ [+ r6 v# x3 i& o
, b8 f/ s- u8 p4 ?) kcircular传输打印如下所示,一直传输,不会停止。8 d4 p( u* d! G0 H
# ~; o3 `, ?' W" g0 `5 W9 p
4 Z6 }) p! y6 |+ ?6 r m
$ W' `2 v3 O1 M* l6 c; [) C; Y
HAL_UART_Receive_DMA()发送/ D8 W. k C, l' Y( q# W, I8 {
测试代码如下。% H- o9 r9 } z6 O
定义需要接受存放数组。- ^/ n( ^# s$ H; l) o' _
( Y2 V! L. s4 M* r9 E' \( J- /* USER CODE BEGIN PV */
; J$ T( S7 G- d - uint8_t RxData[255];: }% a0 U; Q( q7 O
- /* USER CODE END PV */: H2 u& X; V( v; V- Z
复制代码
- r5 W4 u' ^0 Z1 n v. E3 e+ K6 \开启HAL_UART_Receive_DMA()接受代码。
0 b( s# [# c7 H3 v. B7 Z4 G
! W5 q# K: U# U; l$ s# l M' \. g- /* USER CODE BEGIN 2 */4 z5 q7 M2 Y1 E$ s$ N
- HAL_UART_Receive_DMA(&huart1, RxData, 10); // 这里加这个函数,接收数据
, Q2 e8 N% d0 P" a8 P: n9 t6 g - /* USER CODE END 2 */
复制代码 $ z1 p: U" K' p8 v# j; N0 w. N
重写读取回调函数,将接受的数据发送出去在开启接收。* |; G6 f9 z. ~+ d+ H6 a# `8 I
: r' W# W3 z2 w4 X0 r
- /* USER CODE BEGIN 4 */6 e4 J# {! e2 O# p- Q
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)5 [- \9 O& ]- F6 w
- {
8 w I( y$ W" I! @
6 ?; T; ~5 ^0 `% `7 h0 C$ w- HAL_UART_Transmit(&huart1, (uint8_t *)"text:", 5,0xffff);//轮询发送,不然可能发送不出去
; j& f5 ]# _4 K4 u' K - HAL_UART_Transmit_DMA(&huart1, (uint8_t *)RxData, 10);//发送接受的数据
) m+ S6 B8 B; Q; \' V2 b - HAL_UART_Receive_DMA(&huart1, RxData, 10); // 这里加这个函数,接收数据
5 L6 `" C% {* f1 }6 m3 {+ L4 | - } S4 g; R( p% y. s% M
- ; B6 J/ [( n2 ?" b
- /* USER CODE END 4 */
复制代码
' Q) E/ Z0 H/ XDMA有normal和circular两种模式。% t0 a6 |9 C7 C& m; X1 i
Normal表单次接收,接收一次后终止接收,所以需要接收几次就需要开启几次,Circular表示循环接收,接收完成后又重新头开始继续接收,开启一次后会一直接收。, l+ Y6 v8 x1 W; S3 x, Z
normal传输打印如下所示,传输完成就关闭。1 U1 @. L/ T- k w/ ]4 Q
演示效果如下所示。" Y0 x7 D7 y4 f- a
' T2 {- E5 ]" Z
; Y4 f) K0 C/ ?2 o, j8 i0 f
- Y; W$ R1 I: {2 I9 J& [1 gcircular接收打印如下所示,当发送数据大于接收长度时候,会进行循环接收。
: F4 q" L- v! q6 W# \+ H/ q( x8 A9 O8 N. v
1 ~ T" ]! v7 a! M1 _1 L7 V( W
————————————————! {. V2 h/ }# e
版权声明:记帖+ `: l) x+ W, H
7 I2 K( g/ s& e* `1 t3 p- `; [# s7 P a
|