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

【实测教程】STM32CubeMX-STM32L4之研究串口通信(DMA)

[复制链接]
STMCU小助手 发布时间:2023-1-15 00:07
一、开发板平台简介:
( `4 C- K' C; Z  P% M1、开发板资源简介

: Z( s% \; D% v( |& k  q/ X(1)开发板主芯片型号:STM32L431RCT6
4 q% j* u$ L/ H8 Y3 X5 \+ A7 c0 G(2)开发板主芯片封装:LQFP-64_10x10x05P. f( k$ `3 ~0 k  W% l
(3)开发板主芯片内核:ARM® Cortex®-M4
! [' S3 N' r. ^(4)开发板主芯片主频:80MHz' O! @7 R  f. ?8 W' O: s0 E+ q+ t
(5)开发板主芯片Flash大小:256KB
% \' G, b1 k6 U5 t% u(6)开发板主芯片RAM大小:64KB
" }, N8 Q8 b( t" X! }+ r. r (7)其他外设:请参考芯片手册
; h9 M' R7 ^, `( O, b) D4 S* [; g! x8 ]1 \1 G* O* Z- N6 X  F! G
bb91345227434ee7a43a34bf3fe366e6.png 2 ]% K, T  j6 V5 R& L
4 \/ i" D6 L1 m8 T4 b& u
929c0cce04aa4115a8623703982bf3e1.png
5 g5 b, t+ P# s; F
7 b* g2 v5 N; L" F0 w+ q2、串口简介
, F5 d) {1 y  ^7 Q. G: i
         串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。8 N( t! e1 X( S: M% x7 Q

" B  B, G% C2 j( n        (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。
: K8 y5 `7 `$ i: m- ~3 v- Q7 w) i( g5 E; Y3 r
        (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
! x# a* T( a- j: ~/ K
) F6 E7 e3 B# @" D+ W1 @
+ M2 A; S1 W5 n5 _  P
  二、新建工程
2 a! T- Y8 D1 q' K1、新建STM32CubeMX基础工程
0 ]# R, D5 V4 F( ?0 g1 c
(1)打开STM32CubeMX,点击“File”-->"New Project"
& n2 g: J8 `  k0 T, u$ j$ R) W/ d4 ~6 O
2399170347904e959c855fefd5877f84.png
: R' Q! \. c7 Y! s  ~" Q0 V

7 k. t" I/ F% G! X(2)等待打开主芯片选项界面(大约1分钟时间)。
$ B0 y5 H. u2 `9 X* U7 i' P# o0 K1 L* \8 g" ^, L* F8 t5 s  N
d74d2fdc60c9440483e2b7cf8d928e7f.png 0 P7 `) L9 m' ]: O! a; n- N
! o* f5 v: N4 G1 Q5 g' P7 s

0 i3 L+ j( J- q# f" Z; C6 i(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。
1 m. b6 W" R3 C9 W* _+ G: S! M' d* I8 e# h
7b80345238d74bea82ce70e1a348f7b4.png
. `' ~( }: G) \. V4 l$ s9 e3 N: }5 u! ~, V. E8 G; D0 j
(4)选择时钟源。
8 E' g) Q3 X$ |. T% z(1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。7 X0 Y7 @3 T7 y# n/ f$ J
(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。
8 G6 Y3 }: N4 \  E. B8 j! W+ T1 a+ d1 b% ?5 e
72119b971f62410fa8344f7f9fb9f389.png
" O, J& ]" p3 p( l0 m

5 ^8 u: K; p- l: M' p2、配置GPIO控制LED

# m: x1 X* E/ [! U+ l备注:LED灯用来指示系统是否正常工作。
+ O" o5 H9 m+ }, G, Q(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。
: N. A% X) U9 {鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。
. w! y1 C4 D7 ^4 V  Q$ Z" _& s% m; W9 P, J: N% M% k+ }* i
492907c1e71149819adbaee4516a2af4.png
+ B$ A% B' H2 D" b: B
& u9 I; k- s# Y( q+ x" X(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。% G. U7 V/ ~6 I0 U9 H" Y2 q/ C* q

) C  H" k5 q5 o( {4 I0 a 38ff4b80e1c5495ba3076a5158fd91fa.png 6 b. v# i) |' i3 a# O
& H5 C- b7 T2 [' N+ W
3、设置串口1参数: c, j. I1 o- ^! c! G* R' B. V
1、查原理图得知,串口0使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:" v) U* f  K5 M! H# ~0 _
1 {6 I, L3 Y, S( d1 ^
497b8ee0243e446784e64a3c31e8a26f.png
3 w; t& T1 }. s+ B8 j8 c6 S

$ R) L6 D) V3 Y1 m% W8 E (1)序号1用来设置串口收发引脚的选择。/ d' u6 p, G% ]# e3 t* I

$ R4 S1 c0 i! Z5 R(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。
( R% o: ^5 H9 j" E/ C

% g% A4 c/ e/ z- j$ o! C# S4 Y2、设置NVIC settings 使能接收中断4 Q' w5 p) O& {( O: ?, v: f
' D) C  y3 ~; k* q
f9d7783b08304465815834f4d2095571.png
  }( x. b6 u: H* p9 T1 X1 ~# l7 o
' J+ D" T  q2 u4 q+ O4 C- \4、串口DMA设置

9 `1 N3 T, y) V9 B* N( O
0 z' J- {  R- B2 o( x! l+ ?
6d26b13dd9d34039a2b426ca47680f8c.png
7 s  h, v' N, J; }/ W2 L
6 v2 y$ m1 E, E3 y, n (1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:  C$ J, u. I% D" f7 Z9 s
点击DMASettings 点击 Add 添加通道
: Q1 I- \1 D% G选择USART_RX USART_TX 传输速率设置为中速
5 z# N4 s/ L5 h2 d3 T4 s3 EDMA传输模式为正常模式,即发送一次就结束。
6 x! Y- f9 G! I5 Y& u' w6 d5 }DMA内存地址自增,每次增加一个Byte(字节)# d: @1 J+ @' u

! n& n* {* f8 w- @0 k
976712e0494a4482bf65c69fc09fcabd.png % O8 Z. D. C: D  t. B8 m5 x
* {- N* O# T% H8 V  U/ I
4 y( Q4 t, R$ k& c: T
(2)DMA相关参数解析3 J' O( I6 z: [1 N
$ b6 `# d( x- D! r
Dirction : DMA传输方向有四类
& t  M5 k8 `7 ?6 V外设到内存 Peripheral To Memory
3 f! G& ]) L* O) K6 s内存到外设 Memory To Peripheral
3 D" X& V! Q2 x9 S8 F  g' z内存到内存 Memory To Memory8 B1 l1 |2 o/ q' X4 ]2 [8 G$ d( O
外设到外设 Peripheral To Peripheral
. ?3 @8 @/ W; M1 h: S4 _* l+ f
Priority: DMA通信传输速度有四类) f: o* A" {  G, p* o" X
最高优先级 Very Hight
) G6 |/ D) {$ G高优先级 Hight
  Z6 a( h% e; i, M5 u中等优先级 Medium) ~0 J' s$ c$ U/ s. @# y
低优先级;Low
- J9 k) l; j& S' g, @4 e& F  C4 ]. D* c/ s
Mode:DMA传输模式有两类2 _' n. p- S3 ~. @, z
$ T4 \5 L* n: @2 o; I
9021c11fed3e4c1885477e062b846258.png 4 _( W1 T. v, \/ i7 E# i

1 j3 H; x! R; F1 |& e3 z9 L  \( B
( K) [- ^4 m, u  {! h: I
Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。7 @8 p; f1 Q5 c9 _
Circle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。7 {" A; D; p3 @

- A3 q3 v, K9 `6 D3 ]+ t( r
Increment Address-DMA指针递增设置:
# a8 x5 d& A) x) r+ Z4 O
( M0 P" D. n& j0 L* g# ?' O
2b1a952d6514444e9dbb019a9ae88c42.png
) S" o% T( X0 m7 a5 Y  x; X
+ p% z; K6 v8 r+ f6 ^/ i
7 ?1 H8 a) X! \4 ^# i
5、配置项目工程参数
+ t0 M9 I% f- ?- i& P/ y(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。
: }8 O( b" E/ I( l9 r- u
5 n; n6 v% |2 W$ ]0 A4 _" I
2ce1933c10484d819234682f4abc0228.png
* j$ r+ u* q( ]/ F8 f& P3 ~% n8 k3 X. Y" _& u- K- J
(2)完成配置工程。4 k6 Q2 r0 r* H2 h" o  F+ s) ~; X
备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)
/ O* V' _" y/ ?( C
/ s+ j' X* U: v/ i3 W* c
efdb616174f54925b6eac31109f227b5.png
6 L8 l/ g% F8 v1 n" |8 ]
- D% m/ X4 M5 f# V
41c3f2716e4e4eda8f62fa3a1d871322.png 8 Q- ^0 r2 }3 q$ ^/ z, o+ B- _

/ Z+ o8 V! u  I5 m5 H(3)生成代码。- w4 E- H7 y8 Q+ y

7 l5 ^! s3 V9 o, Y
8eaa7d0babea40ee93f158481a6ee471.png
# ?. X' N' \4 C& e8 b  M
0 K: Q! {  k7 G+ I2 G  c# g# L- V 三、在KEIL 5中编写代码
2 i3 y& Y0 O  `. n# m% x. O1 y6 X1、使用KEIL 5(MDK)打开项目工程文件

; n8 `) k4 X' d! L9 \: u+ ^(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。
2 o9 }- q: `; C" X! v; ?; h+ A- m( J
& Y7 O# j1 S* K6 l
9837b01954cc4d3ba3e25073f31b30b5.png
; {" S' e7 e: \, i8 n4 n9 R
! P- G/ B. u& K  z2、添加LED指示灯作为系统提示8 H4 @& L# x# H5 o& i$ ~
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。/ y! i, w2 ^3 N$ E4 h3 R# m
8 q( v$ D9 d+ S+ _" c3 f  _1 k# p
6ab72ceaeb7a41af833842fe5ba6f34d.png
) `: |" B2 y* z5 q1 c+ o# M
: x6 z, y1 I; Q' B! b# ^9 I3、添加HAL库UART  DMA 发送函数代码
' ~0 X$ W! ?/ o0 ^5 R$ P# t(1)STM32 HAL函数库的串口DMA相关函数如下:
9 `6 x9 t8 t1 k) G3 Z2 c
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制
    / D7 E/ r/ x, b% A7 E$ X: C
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制6 H; R# p3 C4 p4 t, U
  3. HAL_UART_Transmit_IT();串口中断模式发送
    $ I$ u4 f/ Q  X3 N+ l* v( W0 B
  4. HAL_UART_Receive_IT();串口中断模式接收. F) J4 }& g7 T3 }9 Q/ f' v
  5. HAL_UART_Transmit_DMA();串口DMA模式发送
    0 |: g  E/ L. F* d" z1 z
  6. HAL_UART_Transmit_DMA();串口DMA模式接收
    . b7 p3 _5 R, W
  7. HAL_UART_DMAPause() 暂停串口DMA5 F3 O1 Q; a4 i- O
  8. HAL_UART_DMAResume(); 恢复串口DMA
    8 [: R) @/ J+ ^5 ~" `
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码

' o. S9 A+ L$ K) a+ h6 C' q(2)添加串口DMA发送log代码:+ x# ^9 o" z9 N8 P8 ]: I
  1. /* USER CODE BEGIN WHILE */
    3 O; |2 K# j8 U$ }: ?7 k
  2.   while (1)8 P  E/ f- Y) E' T' j; o& t
  3.   {
    7 g6 ^1 Z. a6 Y2 I
  4.     /* USER CODE END WHILE */
    % ~0 h. ?$ R% t% Y2 l, }

  5. 3 t! a; f' ?0 I5 Q
  6.     /* USER CODE BEGIN 3 */
    ! B. g' \) d( Y$ r8 c6 L) }
  7.             HAL_Delay(500);+ m* d8 y0 V* i' w
  8.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
    : ^1 S5 n/ O5 _' ^- m
  9.                 HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"hello world,this is usart dma send and receive...\r\n", sizeof("hello world,this is usart dma send and receive...\r\n"));//发送提示  & V/ a) J2 H& q6 t  }  f
  10.         }
    ; Y. ]1 q. n7 t0 L' Z6 `
  11.   /* USER CODE END 3 */
复制代码
  J* I/ W7 K; }" e! x7 |
4、添加HAL库UART  DMA 接收函数代码

/ `  b( v8 R8 ?# I  d(1)DMA接收设置前铺垫知识点:: B! n$ U- P& M, e; p6 `
        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。+ B1 q. N! P6 `+ J- s
3 E: ^# h6 t: `6 O3 j
(2)初始化中断接收配置:# O5 h, ^4 K: G6 V1 ]
uart.c添加代码如下:! J7 M! F  `8 p0 E

  1. & u% F( U1 R/ B6 O' j8 d8 f
  2. /* USER CODE BEGIN 0 */! k' G) v+ }- U2 U. [8 A) {3 y
  3. $ E( H* b' c, f& A/ x/ j$ a
  4. volatile uint8_t rx_len=0;                        //接收一帧数据的长度$ M2 E5 a& l% S  m+ C
  5. volatile uint8_t recv_end_flag;            //接收一帧数据结束的标志位
    & J6 y+ l: x# o
  6. uint8_t rx_buffer[100]={0};                        //接收一帧数据的数组大小
    + _& l) r1 A) l0 I/ N, R4 v8 `$ P, _
  7. /* USER CODE END 0 */
复制代码
  1. /* USART1 init function */
    # _7 y8 R: Z6 R- [$ \% P1 A5 d
  2. 3 t7 O. ]- Z% c' x
  3. void MX_USART1_UART_Init(void)
    # B' q/ C0 ~& M: `
  4. {
    7 e4 l9 d# M4 x/ E
  5. 4 J# A( R- Y. \7 ]9 s8 U
  6.   huart1.Instance = USART1;
    6 q5 d5 t: O5 Y. _
  7.   huart1.Init.BaudRate = 115200;
    6 K3 m2 E/ i, V, w# f3 z
  8.   huart1.Init.WordLength = UART_WORDLENGTH_8B;  K. s! K; J: _4 h) W  g' v
  9.   huart1.Init.StopBits = UART_STOPBITS_1;3 e4 B6 h  B7 g6 P
  10.   huart1.Init.Parity = UART_PARITY_NONE;( B, _  b+ a& J( S$ k
  11.   huart1.Init.Mode = UART_MODE_TX_RX;
    ( c; `1 r. J9 T  @  v. v
  12.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    . [0 _  k# t3 f) ^
  13.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;9 @* {8 ?" {" U: F& h
  14.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    ' _7 u4 R, c  g2 C& E& j7 d
  15.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;' ?, {( L! l1 j2 \
  16.   if (HAL_UART_Init(&huart1) != HAL_OK)# P6 |; k. V, L# X* D* x
  17.   {
    * L; B& h, ?& M. `; l! Z! P# H
  18.     Error_Handler();
    / W5 ?' W1 m/ H# Q% b) z
  19.   }; l6 j3 I9 l+ O. z6 x$ E( v1 [
  20.         /* USER CODE BEGIN 2 */
    6 _. o: y4 H. H! V) A% W7 W/ B
  21.        
    , f2 g; \, k5 v4 F9 f2 V* k; G3 O
  22.                 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                     //使能IDLE中断
    - Y2 l8 _6 v7 ?. D0 U
  23.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);            //DMA接收函数
    2 Y% I6 H- Q" B; A# Q

  24. 8 Z  @. f( D7 c/ \) f8 ]! u: A2 E
  25.         /* USER CODE END 2 */3 \$ p& l7 x, |1 c& Z
  26.        
    5 w7 n+ u3 i1 Z7 a8 g; n5 F- j! n

  27. 9 o, T  L6 e) P) P: V+ b+ H
  28. }
复制代码

$ X+ q! w- G' }, U. K6 fuart.h添加代码如下:
- u* D3 I( d' E/ P5 E
  1. /* USER CODE BEGIN Private defines */
    4 z3 a/ }! g: r% |+ L9 h$ l" E
  2. extern UART_HandleTypeDef huart1;
    . F# }$ q( R. v3 V  s& X
  3. extern DMA_HandleTypeDef hdma_usart1_rx;- k; i6 J9 `4 C' `! P' Y2 V( y
  4. extern DMA_HandleTypeDef hdma_usart1_tx;7 p) W' E8 ^) R$ D4 S

  5. * A: m2 l( l/ y% g. T9 P1 t- y) r
  6. #define BUFFER_SIZE  100  
    ( G, q& S6 C% G+ i5 L) T
  7. extern  volatile uint8_t rx_len ;                                  //接收数据的长度% H9 G( A+ U* n$ L
  8. extern volatile uint8_t recv_end_flag;                     //接收数据完成标志位4 z( [0 G4 c+ E! G( N1 b: L9 W
  9. extern uint8_t rx_buffer[100];                                  //接收数据存放数组+ V/ O" ^0 T! m6 b" n& M
  10. & R" Y" y( W, \0 }
  11. /* USER CODE END Private defines */
复制代码

5 V+ G5 x4 ~8 A5 amain.c添加代码如下:% x1 ^. V- L1 [5 c# C3 Q1 Q% Q
  1. /* Private includes ----------------------------------------------------------*/
    $ H3 N9 I: `1 m, ^* M3 s0 O2 K8 |
  2. /* USER CODE BEGIN Includes */
    3 o, D3 d4 n' n' z- N
  3. #include<string.h>                        //添加字符串头文件
    * ~" _! G5 U% F/ [, Y
  4. /* USER CODE END Includes */
    9 k; A' l0 @) C" ^2 u  s
  5. /* USER CODE BEGIN 0 */6 l+ U- c5 q. u; U5 [
  6. /*******************************************
    7 r, i+ Z' U3 `; f2 U. A$ r
  7. *函数名:DMA_Usart_Send
    9 s0 N- |" j5 t
  8. *功能说明: 串口发送功能函数
    $ W) ?6 s, O1 o) V
  9. *形  参: buf,len" w; o$ R4 g5 b
  10. *返 回 值: 无
    4 ~8 V. i  W, J) _
  11. ********************************************/
    2 S9 Q" t* T" Y' Y( W( m
  12. void DMA_Usart_Send(uint8_t *buf,uint8_t len)        0 s, P- j7 D# V. c* L
  13. {: Y$ _  b2 p' u( y7 h; C
  14. if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数: `- t* V& e! w. ?6 @* Y
  15.   {6 @! O; x( i2 R; A
  16.                         Error_Handler();                                                                                                                                //异常提醒
    9 y. r% e! `% M; J
  17.   }
    : E7 d/ j/ m7 ?* n  c: H/ V9 w
  18. }
    $ T9 r* l* ~" u; F" C$ y
  19. /*******************************************
    % q! @1 M. [) m  c
  20. * 函 数 名: DMA_Usart1_Read, J" b6 |; S7 w
  21. * 功能说明: 串口接收功能函数7 F3 h/ [0 r3 r- ~1 |9 k9 O
  22. * 形  参: Data,len" E5 D9 d5 K0 {( w- w* B
  23. * 返 回 值: 无
    7 x& s$ g) k; d# O* I) r  Y
  24. ********************************************/* l1 S$ m% t( A) g2 M5 Y4 s# D' s
  25. void DMA_Usart1_Read(uint8_t *Data,uint8_t len)1 Y, g' x) h( z4 @' F
  26. {- L; R- d, W. p& Z
  27.                 HAL_UART_Receive_DMA(&huart1,Data,len);                                 //重新打开DMA接收
    ! \2 n: T7 ]/ i& a: w: b9 Y
  28. }
    . i! C( W$ i9 E) ?7 A
  29. /* USER CODE END 0 */
复制代码

, M+ m0 J5 }; v' R' Tmain.c  while(1)循环中添加代码如下:

) P; ]. c+ S( G$ O+ E# ]
  1. /* Infinite loop */* r$ j" }& W: U4 P4 |: x
  2.   /* USER CODE BEGIN WHILE */) f9 S6 @2 ?8 Z9 N: u' h$ x4 f
  3.   while (1)
    1 s$ R5 \! ?7 e
  4.   {
    : Y1 P# O. C$ k8 i3 G' c- t8 X
  5.     /* USER CODE END WHILE */) U9 L/ i' a/ [! s6 _2 L
  6. & Y! P5 h: x. x1 d" Q9 a
  7.     /* USER CODE BEGIN 3 */
    4 d* W9 c$ F6 V/ }% J; p4 u1 Z
  8.                         0 Z; L2 `+ c4 q* U0 t* j, u
  9.         if(recv_end_flag == 1)                          //接收完成标志,如果串口有数据接收,则执行该部分1 I6 s: R6 ^1 x! N/ z
  10.         {+ |1 A! Y  A+ j! Y) m
  11.                 DMA_Usart_Send(rx_buffer, rx_len);9 [9 d( ?" F6 L7 r' r! b& ?9 a
  12.                 HAL_Delay(200);
    $ C% @3 Q7 t( z, w# M
  13.                 DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));        ! L5 t6 D. _6 i# S
  14.                 rx_len = 0;                                                 //清除计数
      }+ S$ \5 c* s. v4 Q- F
  15.                 recv_end_flag = 0;                                //清除接收结束标志位9 u; |5 J, h5 j, v* j
  16.                 memset(rx_buffer,0,rx_len);* e9 O& j' I2 q) R
  17.         }7 k" \: d+ U! t. T+ ]' C1 M" I
  18.         else                                                                //如果外部没有数据,则执行该部分! k9 |2 ]& k' {" Z* L( B$ d
  19.         {& X0 h1 c$ H7 P: s
  20.                 HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"hello world,this is usart dma send and receive...\r\n", sizeof("hello world,this is usart dma send and receive...\r\n"));
    - T/ h2 o1 N' R+ H/ @$ i) G7 X
  21.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                //控制LED1闪烁% l& c8 g8 c2 n/ N
  22.                 HAL_Delay(500);
    * b2 u; \3 f8 |5 Z/ x0 @4 i) o
  23.         }! T, x' ?- E. A$ P. S
  24.         HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);       //重新打开DMA接收                               
    , F* Y2 }# H2 X' K+ [6 V5 o: D8 o
  25.   }& K' p% A% L" D8 j4 q& [
  26.   /* USER CODE END 3 */
复制代码
2 ^2 `  O0 y' s: L' i. F; B
stm32f1xx_it.c中添加代码如下:
9 D' ]  a( b+ D, R1 n3 l5 i
  1. /* Private typedef -----------------------------------------------------------*/$ \2 G& ?# L9 X8 X/ ]$ Q  z* Q
  2. /* USER CODE BEGIN TD */7 F) M1 ?9 G3 l2 u
  3. #include "usart.h"( m3 l; @5 P3 B- I2 G8 k
  4. /* USER CODE END TD */
    # h/ I$ p4 k2 n; ]9 ]) `
  5. 4 C7 Z; }2 p- u3 \7 H! f1 ~
  6. /**7 B# I  w! ^$ x
  7.   * @brief This function handles USART1 global interrupt.
    ( t& V/ r4 c) |: F2 r5 C
  8.   */9 s) h) c" W2 E: g0 O- {- V
  9. void USART1_IRQHandler(void)9 [9 ?. x) {' ]4 G
  10. {
    $ q9 h$ o0 S* T, y: @" s' }0 ~
  11.   /* USER CODE BEGIN USART1_IRQn 0 */
    1 @1 C4 Z7 \7 P' D! D* B* s. V9 h4 G+ p8 e
  12.         uint32_t tmp_flag = 0;$ U: ]0 Q' F0 f& i6 U  ?
  13.         uint32_t temp;
    3 |, W8 ^% J  ?' z  M3 s
  14.         tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
    ; J4 l- z& W" E- T& c
  15.         if((tmp_flag != RESET))                                //idle标志被置位
    0 _4 f9 b: z6 E, d0 u# S" A
  16.         {
    9 i6 c5 i& c2 K
  17.                 __HAL_UART_CLEAR_IDLEFLAG(&huart1);                //清除标志位
    : \9 i' M  Q6 n# ]3 ]) _  _& t9 ~3 V
  18.                 HAL_UART_DMAStop(&huart1);     * |* F* E3 i: U. K
  19.                 temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);   // 获取DMA中未传输的数据个数   % K9 w9 T* _* s8 @2 p3 T
  20.                 rx_len =  BUFFER_SIZE - temp;    //总计数减去未传输的数据个数,得到已经接收的数据个数6 V0 V" T$ v* @
  21.                 recv_end_flag = 1;                                       // 接受完成标志位置1        0 ^, r+ U' n; w/ K+ D3 T1 o3 _- h
  22.          }
    4 {7 z4 T  B3 ?' d
  23.   /* USER CODE END USART1_IRQn 0 */
    % {+ x, l* b7 u3 [+ i- |4 X1 k+ L. Z
  24.   HAL_UART_IRQHandler(&huart1);: p1 c# J/ y; G/ N
  25.   /* USER CODE BEGIN USART1_IRQn 1 */
    8 f! B& D+ q+ u: b
  26. , v# v0 }: f/ v# r" ~- e
  27.   /* USER CODE END USART1_IRQn 1 */
    + W3 a2 m) L( {( \  m
  28. }
复制代码

: e! }. f% Z* X# g+ r(3)至此,串口DMA收发数据需要添加的代码已经完成。: m. e3 B, D4 I( z9 Z) B

1 e+ K; \! e  d' l% ~ 5、设置编程仿真下载模式
9 [% F' ^3 O& Q, K# l(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。; `. Y- m9 t! C0 _
( ]- b: z, d% _/ ]0 K& L) y1 ^
edefb6b9a2a14be3b1221ad6d5c7a8a2.png ' J- b  V& K- ?' L% b* r
+ G0 ^3 r( y% R0 j! ]) U
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
7 f4 C/ I9 g+ [  c" B# n- o1 g7 x5 T, E- V0 `: b5 g
f0ed816a3ed14487bf9e857c317fc99b.png 7 Y  j5 z" k* b% w& M+ L

/ \# c; O+ h& r8 H0 E; e(3)点击Download(或者快捷键F8),即可下载程序。
$ O7 @+ C8 a+ m) r% `- N" I1 U
. l6 [* q1 z- |: d+ ?; x% z
ba221842d5db40808aa129dd83c593d0.png
0 e" F1 u1 A+ q+ C* n) H
. v4 _" I, J! B& W(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。
. w( h2 [5 T) l% M- H# }
- ]. b" y0 Y2 |* |/ E4 X8 B
9f8aa1a4e8f04041bcf5cb183facd100.png 1 X6 X/ _9 d% S& T& v( s+ W& ?

% k2 l* V2 J0 l6 g0 @; ?! n4、查看串口发送函数打印log效果
0 G" }3 X& n0 v" k; I7 X(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。: z9 I8 i5 f# B
8 v0 H! ]# I9 f. E( A% C6 R2 H
(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。9 i2 ]5 c6 Y6 f6 x/ `+ }
+ T, l% w3 A" ]  u7 Z1 d
(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。
& p- m/ E, C7 B; D+ F3 N6 F: h; e9 w3 ]: O' f  Q
16cd1063057845399adc6f45e25a20c7.png 8 m& x+ J; B, X; C
% u% i1 X, ]1 J
————————————————
; m. l, S9 r$ G1 ^3 c3 \$ |版权声明:智能小屋ZYXC
% C. y" d0 r% K( F, b+ T, ]2 P3 H
$ C; a% M# x8 r4 ~' [
& Q( P  I: r# H
收藏 评论0 发布时间:2023-1-15 00:07

举报

0个回答

所属标签

相似分享

官网相关资源

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