你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【实测教程】STM32L43之串口DMA收发实验

[复制链接]
STMCU小助手 发布时间:2023-1-13 20:00
一、开发板平台简介:) [& L0 Z( L+ Y% H. c& i2 Z0 I. T
1、开发板资源简介
8 ~2 U( q  u3 [( ^0 h% u- q1 C& Q
(1)开发板主芯片型号:STM32L431RCT6
" Q/ `& E# _# [4 W7 O(2)开发板主芯片封装:LQFP-64_10x10x05P
5 M4 U' |/ e% U) [8 K3 Z  c(3)开发板主芯片内核:ARM® Cortex®-M4
) E/ O" U: Q/ J(4)开发板主芯片主频:80MHz
; |+ g5 a# e* M(5)开发板主芯片Flash大小:256KB# u, S% Z: Y: i1 U5 n
(6)开发板主芯片RAM大小:64KB! ^: Q7 ]& n% J, V1 ]
: X* n4 E  `; b+ T' H
bb91345227434ee7a43a34bf3fe366e6.png
. n9 |+ S2 u/ E6 _$ |' @6 ]# T- E( G5 R7 m0 C
929c0cce04aa4115a8623703982bf3e1.png
: B5 n% x7 }5 Y1 G8 c

8 d+ |. N7 c! M- N8 q2、LED灯资源$ b1 Z0 f, W- Y* I: l
(1) STM32L431RCT6开发板共5个LED灯资源,其中一个红色LED为系统指示灯,指示开发板供电系统是否正常,如供电系统正常,红色LED为上电常亮状态,硬件原理图如下图所示:0 q! j8 f3 G1 u- l9 T

. |: t8 s" V1 b- _7 s% v; x0 h
0f177691c5814f16a508bcfa747f87ac.png
$ K2 y/ y; n6 z! ^9 w+ Q/ G. T* S% F7 A* u" E0 ~+ s* z& q8 f
' S  [+ }  m9 N6 t
(2)其他四个LED灯为黄绿色可控LED,高电平点亮、低电平熄灭,计划用LED常亮验证看门狗的作用,硬件原理图如下图所示:
# B& V( |& _7 }- {9 @+ ?$ }7 A# a. B$ P
e923ad767b8448b7ac37c4ed693724bd.png
: o* E  V9 e/ b7 e' |& @. u
$ c$ i; i& `. C- p5 G, v' `​3、串口DMA收发工作原理
! {; X& R: ?& ?8 h1 M( f/ t6 R 串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。' h1 E: K$ R7 {0 {# D
# p# z6 M: \' @) c1 H# o
     (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也可使用该串口作为debug串口。
* [2 `/ ]1 l- y* U6 j0 }0 B

, I0 q* h  H0 g- y' `; `, `     (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
$ c+ s, R" l& A5 }, T2 c6 i* u+ m+ @8 _: T" g7 {0 [
TTL转CH340串口,硬件原理图如下所示:! |$ Y: A3 P* G

! l$ q8 F! r& _. B
4df1b489cb944c26b55013001061675d.png 0 O1 l4 r9 x( r6 s0 H

+ |0 Y. e% |$ R3 [DMA(Direct Memory Access) :直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数据,但是不需要占用 CPU,即在传输数据的时候, CPU 可以干其他的事情,好像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM 或者是 FLASH。& w6 r6 t3 C& M
# ~2 ^7 u& p" r1 S7 {
DMA 控制器包含了 DMA1 和 DMA2,其中 DMA1 有 7 个通道, DMA2 有 5 个通道,这里的通道可以理解为传输数据的一种管道。要注意的是 DMA2 只存在于大容量的单片机中。3 H" a0 l4 R- Y9 ]8 y

# S# K9 e" i% {2 a! P' Z/ z
354955ecc6b140049ec57af71fe199f1.png
5 i1 O4 ]1 e) v
1 n0 Z' L! N$ S4 W! Q/ M  二、串口DMA收发实验过程
+ o! Q8 ]; k* W- d9 R! f1、新建STM32CubeMX基础工程
/ U; I0 N+ h: l+ z' i1 ]
(1)打开STM32CubeMX,点击“File”-->"New Project"
* ^9 _) k7 m- c1 f0 I& b7 v' P1 N7 J% t- }
2399170347904e959c855fefd5877f84.png / x! a- c2 O8 G. x2 e" d6 R4 C0 K: u

7 T, P  D# O$ d! q( j% E(2)等待打开主芯片选项界面(大约1分钟时间)。
2 i3 g8 x" O! z8 X
- a. ?. L" E0 t- I
d74d2fdc60c9440483e2b7cf8d928e7f.png
& R; D7 O* z: j1 o7 A
% o7 j/ z( u' r9 k( @5 N(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处选择STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。. F) r. D, j' S' X& D8 `+ g
; X1 T9 x$ ~; F+ s; Z* a- m
7b80345238d74bea82ce70e1a348f7b4.png , X/ p% C/ J  B, g$ m& J3 p, H

7 {5 k/ ?. }2 I/ ?4 @. [(4)选择时钟源。
, A& d  F: C1 E! ]6 p( @" ?( w
        因为开发板上有8M外部时钟,硬件原理图如下所示,所以此处选择使用外部高速时钟(HSE)。2 u0 x2 m3 I$ J8 ?' G
' ?) w" l' H% ]! l$ o
3f65707eca104663a3dede6d25dfa961.png
; E: E) R; |: e! n8 q' s* T8 m) f) n2 J9 f% o) i  I
" j$ C, X4 n" E; r( {; v% M
        因为我们没有用到外部低速时钟(LSE),此处不做处理,如下图所示。1 z; l6 r6 Q6 O$ k5 J0 e! Z* M, ]2 ]

+ p3 q# U5 K; {0 ?/ k) u
72119b971f62410fa8344f7f9fb9f389.png ; |" X$ d6 D$ a, g3 c: x/ z6 W7 J

8 B0 r, H5 d- e/ I2 w2、配置GPIO控制LED" _2 p" G" l5 O" z) d
(1)查开发板原理图得,LED1、LED2、LED3、LED4的控制引脚分别为:
8 a: t" X- t$ C. o# r" }& f: h* PLED1——PC0
. n8 [. X1 c3 j2 Q+ x4 sLED2——PC1
1 O( @* S. L1 C# J6 F4 `# b. ULED3——PC2
1 j# V* n9 {- {. {LED4——PC35 @. n. k- o( G& F; _
1 z6 [$ Y0 i/ W" f! u
(2)配置LED的控制引脚为输出,输出频率、输出方式默认即可。
5 i& e/ O: B/ `/ n& Y; V) h- g( V6 D& b  s0 ^& ^
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式
3 S: ~, R9 m6 Y# G" ~4 u& s鼠标左键点击PC1,选择“GPIO_Output”,表示设置该引脚为输出模式。
) \% Y4 c& m7 a9 s; Q$ j鼠标左键点击PC2,选择“GPIO_Output”,表示设置该引脚为输出模式。6 R4 a$ b! V3 ~2 v: u* a
鼠标左键点击PC3,选择“GPIO_Output”,表示设置该引脚为输出模式。( Z4 \+ b, P# @/ c% o

& E& ^) t$ H0 R) G: r9 w
492907c1e71149819adbaee4516a2af4.png % [& ^! c" t; ]3 h1 \

( A; K; e; v8 j. ?& s
c75d3f10ba2e427d9c1a10fad9bf5471.png * ]8 a7 U! P7 \5 c' X3 c

9 z5 D0 F5 i2 x+ o) O(3)也根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。2 r0 ^! _: y* S  E; Z7 o. t8 m
2 h' z  M& c' Z8 Z( u
38ff4b80e1c5495ba3076a5158fd91fa.png
/ j4 ?( K" [: `7 t" f! B# J# l# {4 D- K7 j
​​3、配置PA9、PA10为串口) i+ U: t0 _7 W6 j* }2 I: h2 q
(1)查原理图得知,串口1使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:% ~5 S& T% s4 \% C* U7 h) \6 \3 A

5 x# M7 |/ b0 v7 |0 H
497b8ee0243e446784e64a3c31e8a26f.png % G$ a9 Q$ r- [3 i" I' m  h& L
$ L( n  c% N' F+ S( |
序号1用来设置串口收发引脚的选择。
1 a* P4 D7 x5 J! d' G序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。. }3 y9 F/ S( t0 {
# Y- _% F) ]* \% Q6 B8 A8 T
(2)设置NVIC settings 使能接收中断
( E, K9 B$ g9 }7 H/ b* S
! k& e' c( U) ?7 [9 M% j
f9d7783b08304465815834f4d2095571.png
  J1 |# ]- f/ U  ^4 o/ b" o3 I6 f" A3 {
3、串口DMA设置 9 }. W% k' H4 o) A/ u
! j, F+ _; T3 }3 Y+ o
6d26b13dd9d34039a2b426ca47680f8c.png
; [* C$ J, j: Y" Z7 y' J. W% n+ u$ K
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:) n# N( |& X3 |; d- A
点击DMASettings 点击 Add 添加通道! y. [& I* S% {' J7 w+ `
选择USART_RX USART_TX 传输速率设置为中速! s9 d, e. X' t3 n. X
DMA传输模式为正常模式,即发送一次就结束。* a! @6 d3 k- \
DMA内存地址自增,每次增加一个Byte(字节), d/ b+ {- Z0 L
. {+ B* t' h3 e  ~  l
976712e0494a4482bf65c69fc09fcabd.png
7 o0 z2 s+ h, q* M+ J& q" f' P$ J5 L# C; [/ S
(2)DMA相关参数解析6 E/ V  a0 [0 @7 [& g' f( E1 G
Dirction : DMA传输方向有四类; m) `; J* F6 v. B
外设到内存 Peripheral To Memory1 @+ s$ e8 J* r: y8 x9 n( c
内存到外设 Memory To Peripheral8 H. f! B% j, S% M0 f9 V' J% o: u
内存到内存 Memory To Memory6 n' A9 q9 ^( \( _  L& f, F
外设到外设 Peripheral To Peripheral
2 O& n/ i6 ^) W7 |3 n  @- z
" P% p" X, D0 v1 T2 \0 H0 g
Priority: DMA通信传输速度有四类) p& k; k  \. k
最高优先级 Very Hight3 X0 g; S) {8 S" ~+ L
高优先级 Hight
; Z+ [: \% P( v# S3 S中等优先级 Medium
2 `6 T  y6 A  s9 _' j0 @低优先级;Low" Z8 H2 M! ?1 ^3 S% a3 B  G

! Y8 S1 A5 t" y" O9 a+ T
Mode:DMA传输模式有两类/ ?( b% s& u1 J, v' z. {# Q
, a) K, C; K9 T$ E
9021c11fed3e4c1885477e062b846258.png 8 u; u: n* x$ F7 [- S1 J
0 L: x9 T* V- T  e  C1 d* {. [2 \$ X1 d
Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
8 X% {" V9 s( V1 T* k4 L: RCircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
: H0 a' z; Y8 g& u0 c/ r9 }) a
4 Y+ J, G0 y' L& q$ C$ e
Increment Address-DMA指针递增设置:
, C- ?. R. q% _+ b) k' c, e4 W  y7 c+ e* u0 j& v3 c4 ?
2b1a952d6514444e9dbb019a9ae88c42.png
0 `6 U& `! h0 K; }; l7 I8 b& {0 S4 k6 c9 L1 h/ |( F( I

% E; y0 n" ?) V% w4、配置项目工程参数* C( r+ i/ W1 `5 F
(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。
8 S8 C# F% a9 J8 W, Y" Z! L8 p4 ~7 V- J, z% X6 _' ^
f3ecedd9323f4463b69539906b3c1199.png
* {1 ^! O$ {2 X9 v/ z" E7 b
% P( U. v8 v  b* t" [* M: a' i(2)完成配置工程。
) x; b0 D4 ^% z# v7 g. i- ~备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。): o" S  P: D* |- R! _/ \  o8 ^. Y

5 k$ K( g! j. U* w3 P1 \: m. k
efdb616174f54925b6eac31109f227b5.png
7 z5 ^7 v3 ^! t$ z: B# {; O8 h1 I9 W+ }1 X: G/ s
41c3f2716e4e4eda8f62fa3a1d871322.png
4 w+ ]0 T* b% I( O
2 {; Z1 r: d; R5 a  R# n(3)生成代码。
7 l4 U0 [) |! l! L; G  u8 \# G) `- x
备注:使用Generate CODE生成工程代码前,请确保文件路径无中文,否则会生成项目失败。
! i+ f- I4 n& O" u: r, ~
3 x  o) @4 c, e! ]
8eaa7d0babea40ee93f158481a6ee471.png
7 i/ t. _: q) w$ q* g4 M" D, g/ Z) I% ^$ \( u, N$ d
(4)工程代码生成成功。0 Y5 M1 r% G. G0 G
9 l. V& W) k: _; W; O7 z
e8f46d59a1fb4af589feb613fdff17b4.png
/ m) y9 S8 e3 s9 m% h, k1 g0 P( z7 D0 J) V
三、在KEIL 5中编写代码
" |" g) {- V+ f; W2 W# \1、使用KEIL 5(MDK)打开项目工程文件0 m+ H4 Y* E) ^3 q0 {. j% F
源码使用说明:使用前必须把项目工程复制到无中文路径的文件夹下使用。
" k( _9 [4 l, `4 b& T' I(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程.uvprojx。6 z2 u- h) z0 |7 v  P8 r% ~4 s
  [# Q: {+ m) X/ s
a2198e7b52e642bdb05a708c7fb8061a.png
) r' h; P8 f) ]( j
; N& c% }7 v5 f2、添加LED指示灯作为系统提示
; z+ c/ `" B  j8 F- Y8 y* f添加每隔100ms,LED1、LED2、LED3、LED4闪烁一次的系统提示,用于提示程序运行正常。+ a) T. U. t4 l& _0 F' k& M
/ S; u5 q7 X! R% L/ N1 d
2af9ef3cfaab45988c810d94d801fc34.png
& C2 a  p) V8 w2 ?* E: h( S0 l
7 I6 q: H; `, K) O' k3、添加HAL库UART  DMA 发送函数代码
( N0 f0 U0 Q* a: R( U(1)STM32 HAL函数库的串口DMA相关函数如下:/ ?) C$ Y3 O( _3 C+ z: X
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制
    ; q* N, n0 F3 B) X# `4 u1 p
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制4 D" F& W& A/ d6 C
  3. HAL_UART_Transmit_IT();串口中断模式发送
    " I# F. g2 K9 x; L6 a9 {
  4. HAL_UART_Receive_IT();串口中断模式接收
    ) @, D. e) A* p8 B
  5. HAL_UART_Transmit_DMA();串口DMA模式发送3 ^8 H5 _' r2 a1 B. a
  6. HAL_UART_Transmit_DMA();串口DMA模式接收% X4 b, a- X" t
  7. HAL_UART_DMAPause() 暂停串口DMA' ~+ o1 J2 C$ p1 M- l
  8. HAL_UART_DMAResume(); 恢复串口DMA& Z( v' i! h6 n/ v3 s; S
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码
4 Q% V" O5 K. e3 g" n# t6 W# R, m
(2)main.c添加串口DMA发送函数相关代码:
2 Q- F1 x+ i2 X$ E- D# n- {; V
  1. /* Private user code ---------------------------------------------------------*/
    5 N3 a" I! o! B% H  U$ o# v! K
  2. /* USER CODE BEGIN 0 */1 `) f* T: R; t) T" h  u
  3. uart_rx_struct uart_rx_struct_t={0};                                //串口接收数组+ S7 q+ n6 b. _( a, T- |' m% E
  4. /* USER CODE END 0 */
复制代码
  1. int main(void)
    4 B6 `* i; s& l2 P3 S
  2. {
    ' J4 \9 f% p2 c" H+ Y! v8 }
  3.     /* USER CODE BEGIN 1 */
    ! \# U  P, j: `  @
  4.     uint8_t transmit_str[50]= {"hello world,this is uart dma function!\r\n"};6 i, g! l; p/ t4 b( R8 E9 A( h: F
  5.     /* USER CODE END 1 */
    " Z9 f' X8 j, W8 V

  6. % n4 Q8 _/ i% ~4 Y
  7.     /* MCU Configuration--------------------------------------------------------*/
    , v1 C9 v/ j+ d& u7 L! G6 `  K

  8. & M9 ]8 R  Z9 d3 d9 s- O+ p, v
  9.     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */8 l0 o% h5 H  T* x
  10.     HAL_Init();8 D" L; t  S% n  B

  11. " [4 f) b: Z4 v- q  l
  12.     /* USER CODE BEGIN Init */. C" ^/ ]8 }4 R0 G6 \5 j* L
  13. ) h  |; B5 I4 B0 A& r( s% p2 U
  14.     /* USER CODE END Init */- [$ S) R3 @9 `& y5 r  i9 {% l
  15. 9 e6 K6 H2 j% o' y. l; q
  16.     /* Configure the system clock */  ]9 E* @8 ?/ Y+ V8 m
  17.     SystemClock_Config();  _+ l$ L: H+ s" z  ~5 X9 w% B
  18. ' o! ~( I7 Y" O. s* ?7 z9 i: C
  19.     /* USER CODE BEGIN SysInit */
    - Y9 K  u$ i0 H% C% j" b

  20. 2 R' l. x% Z/ R8 I; D% ?& X
  21.     /* USER CODE END SysInit */2 a  y5 H8 X# \& I
  22. # O$ a, U4 }8 w+ r% ~9 C$ P
  23.     /* Initialize all configured peripherals */. V- e* B" O% k
  24.     MX_GPIO_Init();
    + J! q; W; D$ f0 r  Z" N% x9 t
  25.     MX_DMA_Init();
    + N: f, |" W# M4 w
  26.     MX_USART1_UART_Init();
    # P' C" x" h3 E* l8 D. c
  27.     /* USER CODE BEGIN 2 */0 w. s% U$ J* f" E$ E  L  ?0 V
  28.     HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);                                                                //初始化LED灯,默认点亮
    & l8 I; I$ p% l
  29.     HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);                                                                //初始化LED灯,默认点亮8 X% i' ]: O+ n' M" S5 V$ q7 a) L# ^
  30.     HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);                                                                //初始化LED灯,默认点亮
    9 I/ [) ]- B+ {
  31.     HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_SET);                                                                //初始化LED灯,默认点亮
      ]3 l( a2 B& Z: H6 v6 p
  32.     HAL_UART_Transmit_DMA(&huart1, (uint8_t*)transmit_str, sizeof(transmit_str));    //
    , ^( [& h, V" V9 a/ H2 F3 l' v+ r
  33.     HAL_Delay(5);  P! A9 b, S2 y2 |' j& D# q7 V. M
  34.     HAL_UART_Receive_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, UART_RX_LEN);         // 启动DMA接收
    ) y- u9 v1 D# p
  35.     __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                                      // 使能空闲中断- Y; F& V- m2 |5 L2 w. Z; c

  36. ; w* ^& c2 ]# R! n
  37.     /* USER CODE END 2 */
    5 S! U& i1 ~- E. U, w4 C% H

  38. " l3 j4 @* C* {0 k) U6 I
  39.     /* Infinite loop */0 f3 o/ D9 y, E1 _( o
  40.     /* USER CODE BEGIN WHILE */
    2 J* A) z, F% N
  41.     while (1); m- p! N+ \* @$ q) U' v
  42.     {
    : Y* G$ V1 B3 W5 w2 ]1 ]7 f; r
  43.         /* USER CODE END WHILE */% q. d- z' J* y' B1 c
  44. . e4 h# y$ V/ C' M# k$ ]* w4 b
  45.         /* USER CODE BEGIN 3 */
    3 Q8 o. U8 t! E$ B/ Y
  46.         HAL_Delay(100);7 _7 S. u" T$ t* r' B3 \
  47.         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                                                                        //反转LED点亮熄灭切换3 e6 B" ^7 I8 y; ~; S
  48.         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1);                                                                        //反转LED点亮熄灭切换
    . F8 D% Y, b+ X
  49.         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);                                                                        //反转LED点亮熄灭切换% O! I, u; G: ?4 a6 M
  50.         HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_3);                                                                        //反转LED点亮熄灭切换
    9 X9 C* p$ j% {0 L( Y
  51.         if(uart_rx_struct_t.uart_rx_flag & 0X80)                                //DMA接收完成
    4 f. u; F3 X; G
  52.         {
    ) k' K6 L' h3 Y( O' e& ]& v6 D5 v
  53.             HAL_UART_Transmit_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, uart_rx_struct_t.uart_len);    // 将接收到的数据发送回去) S! z8 z& r- a2 G( ?" u" M' r; t
  54.             uart_rx_struct_t.uart_rx_flag = 0;
    8 }# B" b( c# C5 k6 H2 |2 F9 C
  55.         }
    * \: Z; @& ]3 @6 z0 _% G2 u" K

  56. ! W3 ]: P! n  {) }8 @2 K
  57.     }/ V+ {5 H9 p8 h* m" a4 l
  58.     /* USER CODE END 3 */
    # d% h- }) I: U
  59. }
复制代码

: V( f' ?4 D& L; I(3)main.h相关变量声明: D; ?) ~% g* d5 |- ~$ @3 H
  1. /* USER CODE BEGIN ET */
    / z, I) U8 b$ j& v
  2. #define UART_RX_LEN 1024                // 一次最大接收的数据量, n( f$ c  z4 d
  3. typedef struct
    - Q9 D1 Y* @6 w$ }; f- e' ^
  4. {
    " R3 y4 `# _" w% S( U1 y" @7 A0 {1 I3 g
  5.     uint8_t uart_rx_buf[UART_RX_LEN];  // DMA数据接收缓存数组: q$ J2 _! ^$ [9 N
  6.     uint16_t uart_len;                 //DMA数据接收长度* [2 F, K- `" [  N$ u
  7.     uint8_t uart_rx_flag;              //接收完成标志位8 \9 Q0 }; i5 h. A
  8. }uart_rx_struct;
    5 X: l5 Y8 P" @. E* C4 H
  9. extern uart_rx_struct uart_rx_struct_t;  
    0 M; g% l6 ~" v4 e, B
  10. " T+ `6 z3 `- ^% \, w1 l
  11. /* USER CODE END ET */
复制代码
7 q; A# _3 e4 y- Y
4、添加HAL库UART  DMA 接收函数代码
- s4 o" G$ A9 T! k% V1 }(1)DMA接收设置前铺垫知识点:1 L( U4 p3 c4 k" Y; B, ~' S
        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。& B# n4 O5 i; n

1 p& G4 U6 `# O8 T; }4 ]: r, o(2)添加DMA接收处理代码3 \4 g2 [% \* G' e2 _2 Z' F& u
) y# P% }; W, T1 D
stm32f1xx_it.c中添加代码如下:$ J- i/ |! Q. d* c$ E# a: {6 k. u
  1. void USART1_IRQHandler(void)
    1 c* Z" g& z4 c4 U: e3 m/ l
  2. {
    ! M; T4 _- B5 d. I- A6 E# [
  3.     /* USER CODE BEGIN USART1_IRQn 0 */
    1 b2 T2 R0 V, e% _3 x
  4.     if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)       // 空闲中断标记被置位; l6 W3 B4 `: S$ D+ u
  5.     {
    , M) m; I* n' M; T" l
  6.         __HAL_UART_CLEAR_IDLEFLAG(&huart1);                         // 清除中断标记
    / b7 ?7 S, O( d9 S# z1 _
  7.         HAL_UART_DMAStop(&huart1);                                  // 停止DMA接收
    7 u- k9 u% Z: N5 c
  8.         uart_rx_struct_t.uart_len = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx);  // 总数据量减去未接收到的数据量为已经接收到的数据量2 u. z4 E* p8 n: u2 a
  9.         uart_rx_struct_t.uart_rx_buf[uart_rx_struct_t.uart_len] = 0;                    // 添加结束符6 M* x7 I$ m$ b. c2 _7 R
  10.         uart_rx_struct_t.uart_rx_flag |= 0x80;                                       // 标记接收结束
    - `5 y1 d0 P* g4 W. z
  11.         HAL_UART_Receive_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, UART_RX_LEN);    // 重新启动DMA接收, O9 n0 A) ]7 S+ O, F7 Y
  12.     }7 }# W4 V5 b  |+ k& b1 O
  13.     /* USER CODE END USART1_IRQn 0 */7 w( J) O! M/ w' ^3 j4 C
  14.     HAL_UART_IRQHandler(&huart1);! ^' S6 {4 K# t- r$ w$ b# N8 V; [
  15.     /* USER CODE BEGIN USART1_IRQn 1 */
    ) s4 w. n- f4 I0 `9 P8 e0 K- H7 C9 J

  16. * b: l% F- ]+ j
  17.     /* USER CODE END USART1_IRQn 1 */0 _: R/ T, Q* Z$ J6 z
  18. }
复制代码

, x/ a5 o" o. Q3 k" }) ~(3)至此,串口DMA收发数据需要添加的代码已经完成。( a5 f( I7 f# E
( [4 d6 |) A1 k! r- ]) y
5、设置编程仿真下载模式
% N! Q7 z4 c+ G6 l' |9 o) y$ p/ ](1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
* m7 F) r- B$ b- w3 i7 K6 }+ n* q" c& h1 `
9f8aa1a4e8f04041bcf5cb183facd100.png
0 B, t4 d3 z7 p/ J) z7 |) \) h9 ^: W/ v, G
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。" Z% g* Y) n$ }: a1 k
; g& U" m! R5 d- d$ k& [2 i7 U
e0b7e3e353b345a7987fe5f821de2dda.png
$ F0 u. n1 @$ P4 V2 {: d, E% X1 w3 D4 n& o) r6 h. j% j
(3)点击Download(或者快捷键F8),即可下载程序。3 ]' R  K' x, t: |' D& k* S
% F( H, Z: @1 p* J# G0 J8 c; o& U% s
eb3f250f19e44862a7df80c2492fcd01.png
. w' I2 c9 o1 I* L: G+ J​​9 d# d* o2 s. @. Q3 g" @

- `% d- O0 G, m; d% H. k, U(4) 如果下载程序后,没有看到LED1、LED2、LED3、LED4闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。
6 ?/ B- Z  m7 E5 P  }8 |2 r% n2 t7 r: b: m" m

. v# i6 j  M3 V4 D6 ^) N' Y ​​; q! y( b$ d" m
6、串口DMA收发实验效果展示
+ @( ?) t) H* ~% Z, K: Z6 I3 O; z
        程序烧录到开发板后,即可看到LED1、LED2、LED3、LED4初始化后每隔100ms闪烁一次,并且打开串口助手后(串口参数:波特率115200、N、8、1),通过串口助手可以看到,开发板接收到发送的数据转发出来。  W/ j; S$ T. r2 M6 C+ R
1 y1 T: Q  |3 P* L9 j' m" _
2a8f9f6486b04eeb8747ce0b09a6352c.png ! x% g4 [8 I( D! L4 l& u$ K& o
# M! u/ L# ~. ?1 \2 O
————————————————
( j: X* A1 f" q7 R* P& V. E0 @版权声明:智能小屋ZYXC
4 d  M( Y4 e! F: {, D8 `( Y% v9 v) r, u1 p
. w8 h. ~, E5 D  y9 i" }
edefb6b9a2a14be3b1221ad6d5c7a8a2.png
收藏 评论0 发布时间:2023-1-13 20:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版