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

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

[复制链接]
STMCU小助手 发布时间:2023-1-15 00:07
一、开发板平台简介:3 E( Q# @( i) \) b0 j/ z( j9 A7 M2 }
1、开发板资源简介
: k. c$ b7 T' k( c' y
(1)开发板主芯片型号:STM32L431RCT6+ i, s/ B- P+ z& u
(2)开发板主芯片封装:LQFP-64_10x10x05P
0 ?3 {! l* P& X; s: O; m(3)开发板主芯片内核:ARM® Cortex®-M40 W* L6 g& E  d- w* L
(4)开发板主芯片主频:80MHz. H" m# v( ^6 W) b
(5)开发板主芯片Flash大小:256KB0 G' C: i! g* F' N% B6 p. g& D
(6)开发板主芯片RAM大小:64KB
- z- ], @( [% ^& U% k (7)其他外设:请参考芯片手册
- H" ~1 n2 ~; h8 Y0 Z9 k! O
. v" X4 y# d9 O# B% g
bb91345227434ee7a43a34bf3fe366e6.png
3 B0 a% V* Z: W) l1 a/ g) ?6 f
- |; J, O' F! `( G
929c0cce04aa4115a8623703982bf3e1.png
: i4 W4 X) {4 `! N* R& A: {
8 q9 A( g( J1 z2、串口简介

3 s6 V. O+ I( k5 K8 ]( `         串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。
# f1 M* A; m* W4 k
( k' O( x6 Q: _- [; P% [+ [        (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。
- ~+ j& n' c! B4 `7 e. H# ~8 V
7 V. q4 f7 ?" X- B( o: [        (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
/ V  j* I4 a; j! _  r( c, i0 j8 A$ O

9 n# o& M$ ?: {. ]  二、新建工程
. `' c5 j4 `; B7 ^) i& I1、新建STM32CubeMX基础工程
1 m- T- v& f. M- P0 |0 f- z/ U
(1)打开STM32CubeMX,点击“File”-->"New Project"4 S" i: l" a1 K$ z6 _7 e

# x- q) L' h# }8 Q- c3 f+ F$ b* W
2399170347904e959c855fefd5877f84.png " E# Y+ F6 M' E: e- `8 |7 I

; U. B+ O% o* y2 s(2)等待打开主芯片选项界面(大约1分钟时间)。3 i0 B( a, i5 H1 q& S3 q9 ]

: {) Z8 ~; {- M
d74d2fdc60c9440483e2b7cf8d928e7f.png
# \  o1 _0 o  I( Z/ m7 ^: x
1 \& H0 e( U( B- G# n. u" W

+ r  N- f. o: s1 S(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。
. L2 j( m5 Z1 P9 p
8 H" D: I8 L/ L' L/ m# x
7b80345238d74bea82ce70e1a348f7b4.png
9 H  {) h" G# N, @3 b9 s
3 {& a& o6 s/ b7 p5 N(4)选择时钟源。
6 s9 t# J' q+ f6 ](1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。
3 m* {; `* Y+ B(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。
# k( ?/ F- r9 r0 E4 }! q; B5 J
* t! h5 H  S" B2 |$ H
72119b971f62410fa8344f7f9fb9f389.png - t' i8 }5 [$ p0 `6 @3 l
- c( @; N  l! l) {$ H7 z8 H: k; M# g
2、配置GPIO控制LED

1 }( d2 O% T4 N备注:LED灯用来指示系统是否正常工作。
: I+ _7 h' d+ {, J(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。; i/ N2 w$ ^* |: @) S7 B
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。
; i/ d* \- ^+ v% ?9 S; h# Q8 {" Q
  ?/ W- w9 y' @
492907c1e71149819adbaee4516a2af4.png # u& N9 P" s* a" n$ C7 @

/ f  j# ~) ]# S3 D(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。5 {3 _6 e* g# A6 D' x- ]5 ~( o

& v7 y2 }5 Z& d5 e 38ff4b80e1c5495ba3076a5158fd91fa.png ! W. @# @3 y9 ~  y8 a2 ^5 J* d

- f6 y. R# G8 `3、设置串口1参数. ]1 M" P7 h. F/ N) G, h
1、查原理图得知,串口0使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:+ {/ w3 _: M$ x9 q

9 L2 g3 @' W& W6 K- e, R
497b8ee0243e446784e64a3c31e8a26f.png
2 D/ a3 M8 g* R+ W- g! _
# l2 [& F1 I6 B- A7 x
(1)序号1用来设置串口收发引脚的选择。
6 f: X9 I! G  e% Y4 t7 ~4 ]

* C1 E1 b, ]5 T* G(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。6 I6 H& ^" ]) ]7 S  Z

$ y3 D& Z5 W2 q7 f0 f/ }2、设置NVIC settings 使能接收中断; }$ \* @# |- I
. V4 r* Z7 m, v
f9d7783b08304465815834f4d2095571.png , b( w" @4 h& O8 g0 q" U
  [0 _8 w5 T; ~  L% F' r
4、串口DMA设置
2 P0 Q* _3 I% m7 U2 p0 _5 C  N& I

* i- m3 S; C) e6 L; Q
6d26b13dd9d34039a2b426ca47680f8c.png , K" H* u( E* |  G0 R6 I' p
; L- Z0 y+ d) f
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:
) r+ l7 T3 Z0 I# @点击DMASettings 点击 Add 添加通道
* p$ l: w0 J. d) E/ w- b选择USART_RX USART_TX 传输速率设置为中速- `5 o0 \% e2 i
DMA传输模式为正常模式,即发送一次就结束。
; J; X; Y2 e1 x* TDMA内存地址自增,每次增加一个Byte(字节). _0 M# l* ^  \- |7 G7 W
+ q2 L1 X) I3 y" o, r" L
976712e0494a4482bf65c69fc09fcabd.png
" W- z; ~$ ^) t8 b9 @
( B" y0 d% Y, X' x6 W1 \! O' Z
2 X: A& _! J7 B
(2)DMA相关参数解析
! A7 ~. L# @5 C, d: n) C# p9 W3 S+ T; d
Dirction : DMA传输方向有四类: l; O0 `6 r9 I# U
外设到内存 Peripheral To Memory% y3 j9 D! q2 X8 f, Y6 ?
内存到外设 Memory To Peripheral
! y' u& j% v# F/ W& C$ Y& \, l4 \7 [- o内存到内存 Memory To Memory! i5 }' I3 j  i& I" R7 X' {
外设到外设 Peripheral To Peripheral
  x# ?) U4 Q3 ?
Priority: DMA通信传输速度有四类7 {4 y2 j  J! i( Z: N3 A. H
最高优先级 Very Hight7 C' ]+ T: r) N$ b, s- x; B/ U
高优先级 Hight
6 q# z4 o" D) T+ [) O1 Q中等优先级 Medium
8 n, j& }8 j# S9 }8 i- K低优先级;Low
" K, b) a, ]# I( `# v: G' D& p  l4 G) V" L6 @
Mode:DMA传输模式有两类1 y9 w* j0 n. Q3 k
3 P6 k4 k' q" w) u& {
9021c11fed3e4c1885477e062b846258.png 7 h0 p3 Z6 p* i7 h- j  `
$ S( g+ j$ E# i0 x4 w2 j

2 D1 a; H$ J. d5 p; l. [Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
, F& H' }" `, K1 KCircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
; X  I* y! d6 {% P6 `7 j5 b$ N  ?6 o0 s, b) @  [5 i4 z9 c
Increment Address-DMA指针递增设置:
6 |8 s5 i: L7 c! X
# c7 [5 y: R: }. w2 O8 I3 c; `1 i, C
2b1a952d6514444e9dbb019a9ae88c42.png 1 v, T4 a0 l2 I0 N/ y' z/ k

, c$ X; u# h* S  {3 H

7 r  {8 I3 S! z% h/ n. n  M 5、配置项目工程参数
+ R. C3 S6 x" d% [2 x(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。  E; n/ H7 R1 B/ K3 F1 t6 e
0 G, I0 v6 J# l. V5 {. F9 S
2ce1933c10484d819234682f4abc0228.png 7 B2 ]* {  i0 \1 Z" ]
: n) `8 [  p' w7 q4 `2 o
(2)完成配置工程。
% n4 H. j/ T- g- \# ]: X备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)
* G3 f/ I( S& d* V! d4 l) l) N3 Q1 z* ~5 K
efdb616174f54925b6eac31109f227b5.png
2 \( j6 f5 `+ a: @" D" P: |$ C( O' E' g; @
41c3f2716e4e4eda8f62fa3a1d871322.png
. L: J! k, x( ^, ~& T/ G2 G! q( z1 i3 G& e6 \+ Z% q+ k
(3)生成代码。3 L# I0 L- w$ L. E5 F
0 W+ @% e6 t) e  L5 W* r' Y
8eaa7d0babea40ee93f158481a6ee471.png ' G& e9 I9 V$ }6 o
  F0 k" w3 T0 m1 B# z4 Z. o6 J; B
三、在KEIL 5中编写代码
6 J( n( f% C  c1、使用KEIL 5(MDK)打开项目工程文件

$ q, W' |% I" m; T3 F5 g+ |# y(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。5 K/ A7 w6 L2 b7 W5 U
) r3 l9 ?2 J0 L" V. g
9837b01954cc4d3ba3e25073f31b30b5.png
7 k) Z2 g6 ~3 J, a2 j9 p+ R
, J+ v" @) X, d6 ~* }- G3 `2、添加LED指示灯作为系统提示' Y  m0 B3 J. d2 D
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。
/ @+ Q3 u  Z: d1 A0 X/ Y% b5 d4 K' p" o- n" W+ h+ g
6ab72ceaeb7a41af833842fe5ba6f34d.png " ^2 ~. I! z) C- }! c; L; E9 [1 t3 Y

# u0 x9 N; u7 d3 l) n/ `( L  Z3、添加HAL库UART  DMA 发送函数代码
) R2 I* Y; p1 ]& Z(1)STM32 HAL函数库的串口DMA相关函数如下:$ B& U, {8 I* Z0 h6 K$ ?/ ^
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制
    2 c) I$ v& o% o  u- t1 H
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制$ L0 Q# g9 v. O0 D
  3. HAL_UART_Transmit_IT();串口中断模式发送7 V  o  u$ ^1 r$ ~1 _2 }3 E: k
  4. HAL_UART_Receive_IT();串口中断模式接收) p+ k4 U1 N7 v! o/ f
  5. HAL_UART_Transmit_DMA();串口DMA模式发送
    ; O9 c6 f1 \* }1 ~0 J% H4 [
  6. HAL_UART_Transmit_DMA();串口DMA模式接收1 v2 M/ K. N' e: d' k) K  P/ k) ?
  7. HAL_UART_DMAPause() 暂停串口DMA2 Q- W2 W5 i% V  F5 R- I# G3 h2 {
  8. HAL_UART_DMAResume(); 恢复串口DMA; n0 T- z  e9 z+ s$ m% o
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码
6 p& T: f% h: u. t% `1 {( Z
(2)添加串口DMA发送log代码:
2 N8 W. A$ ^, E7 {7 W3 h. @
  1. /* USER CODE BEGIN WHILE */
    : H% o$ E7 m4 H' `7 h3 h0 k
  2.   while (1)
    : m: T: S( M% J$ f4 {4 _0 E6 l
  3.   {
    8 B4 Q/ k, \: v% c) B$ Q
  4.     /* USER CODE END WHILE */
    9 S' J- i9 m& i, I0 R; V, T

  5. $ |1 E. Q8 p& T. V2 K3 u  l
  6.     /* USER CODE BEGIN 3 */
    ' v3 B5 x7 x+ [  C' c' N
  7.             HAL_Delay(500);
    ( b3 |4 R' R. s: W. q
  8.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
    . d# J8 o2 B" \* e6 ^
  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"));//发送提示  
    . N) K( S/ G9 }4 {! i7 S8 j1 S! ]7 Q
  10.         }: v/ M6 X8 r, y& H
  11.   /* USER CODE END 3 */
复制代码

9 M0 ~" [1 N# X( w, }  x2 w/ i4、添加HAL库UART  DMA 接收函数代码
1 h: A& Z1 Y& g7 Y4 }& B
(1)DMA接收设置前铺垫知识点:: z5 `& y( A8 x* w! P
        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。& b/ V  ]4 Q* T/ z7 s: }! ^
& B1 T4 }, E/ Q% U( ~
(2)初始化中断接收配置:
* W" j; p1 i7 q' x# V: vuart.c添加代码如下:. k+ q- z: x. Q

  1. 2 b3 d. m5 w/ T0 j* U$ k
  2. /* USER CODE BEGIN 0 */2 l3 v% b7 L  O/ U! Q# C. m
  3.   h8 F5 E5 ]$ K. q5 g7 R! B6 }
  4. volatile uint8_t rx_len=0;                        //接收一帧数据的长度
    2 C, y7 I6 [, ^4 A) ^$ Q/ @7 k) i
  5. volatile uint8_t recv_end_flag;            //接收一帧数据结束的标志位+ ^9 x4 X4 ^. j6 g+ A1 N* G$ Z
  6. uint8_t rx_buffer[100]={0};                        //接收一帧数据的数组大小! c7 O6 s8 ]3 ~4 F3 |
  7. /* USER CODE END 0 */
复制代码
  1. /* USART1 init function */
    3 _) \/ D; C% i+ P

  2. " F- a$ A+ E  F& E: V4 o
  3. void MX_USART1_UART_Init(void)
    $ p, t1 v1 f0 a9 d7 K$ ^
  4. {
    , j0 h6 ~. e" c. C( u5 a* H5 y

  5. . R7 W3 o7 w. p5 s7 z9 C
  6.   huart1.Instance = USART1;
    9 f. W# f3 a. z1 ^9 B7 u5 h$ Z
  7.   huart1.Init.BaudRate = 115200;
    ( a* b* B3 h6 @3 V6 d
  8.   huart1.Init.WordLength = UART_WORDLENGTH_8B;' P. C+ O# Q' M2 R* N& w( |
  9.   huart1.Init.StopBits = UART_STOPBITS_1;8 g  P. q% \. `, s( k& E7 ]6 p1 i; @
  10.   huart1.Init.Parity = UART_PARITY_NONE;9 V" o* ~' Y# n. p: n: u
  11.   huart1.Init.Mode = UART_MODE_TX_RX;
    9 k3 J  D2 D7 U/ A" p0 d  e
  12.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;/ N( ?# n% X5 D" |( V" P5 F6 r2 C
  13.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    - v$ f  w# S0 W* g
  14.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    * `: M9 b) h! ^
  15.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    0 E; o! v- \7 e' G7 B$ }8 N: H
  16.   if (HAL_UART_Init(&huart1) != HAL_OK)8 t9 z0 p) t2 i5 n1 `8 b
  17.   {; ^  J8 D8 s( V9 B" u
  18.     Error_Handler();
    : p5 u8 ?7 @% G9 O/ z
  19.   }! N* _7 S! h5 w: F3 z& @
  20.         /* USER CODE BEGIN 2 */: R$ Q0 h+ U# [9 I: s" e3 s3 Z
  21.         $ |  ?8 Y7 Q5 g! A
  22.                 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                     //使能IDLE中断
    4 B/ H# f5 t/ P9 V$ z4 F
  23.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);            //DMA接收函数
    2 F: k" f. g" q8 c3 D

  24. % ]( G1 p* f+ |% X, K. Y
  25.         /* USER CODE END 2 */
    0 _" z/ t; p" ]+ F3 v
  26.         ' j  b. Q9 }' z1 M, q; {) C& h
  27. - u2 g2 @0 E. t9 e  v" d( z" Z
  28. }
复制代码

8 s; v7 p2 Z1 k$ `: {uart.h添加代码如下:  W! q4 r# a0 j; S! P0 |
  1. /* USER CODE BEGIN Private defines */
    9 E: m" o: Q( Y
  2. extern UART_HandleTypeDef huart1;
    - V2 e. ~) U+ Z% i1 U/ J: [
  3. extern DMA_HandleTypeDef hdma_usart1_rx;: W& _, y' f& P" |6 o/ C
  4. extern DMA_HandleTypeDef hdma_usart1_tx;
    5 M( m, K9 U7 |) K5 O8 H

  5. - ?$ g/ U& f4 f% A
  6. #define BUFFER_SIZE  100  
    ) {- q2 V$ m) y' ~0 ]8 X
  7. extern  volatile uint8_t rx_len ;                                  //接收数据的长度& J+ \9 u; k% a  ]2 m' [5 N
  8. extern volatile uint8_t recv_end_flag;                     //接收数据完成标志位% }5 D! q) {2 m, {1 F5 j+ o
  9. extern uint8_t rx_buffer[100];                                  //接收数据存放数组
      a7 W" }8 R7 O$ T

  10. 9 s' L% H- V0 \2 `7 \: h! i
  11. /* USER CODE END Private defines */
复制代码

, d! p* b4 b- `6 ?) ^0 xmain.c添加代码如下:
% N! ~4 ^4 f) E8 p( \
  1. /* Private includes ----------------------------------------------------------*/) `+ n3 ^! _9 _9 u- {/ L* S5 M( @
  2. /* USER CODE BEGIN Includes */
    5 m; q$ I$ K+ U1 W7 P" J) i4 v# P
  3. #include<string.h>                        //添加字符串头文件
    0 q0 ^7 B- |& T3 |, O
  4. /* USER CODE END Includes */3 q! i2 k; n7 X# O0 o2 P
  5. /* USER CODE BEGIN 0 */; C, g4 Q/ b6 l8 |, X% u
  6. /*******************************************8 y2 D( F# {) F# t" M0 L$ t. Q
  7. *函数名:DMA_Usart_Send
    . j; R5 I7 o1 y: c$ w% O
  8. *功能说明: 串口发送功能函数
    + {( F& o4 K# g8 K% H6 `4 a1 X
  9. *形  参: buf,len
    ; ~. I  Y3 z3 K9 V6 i
  10. *返 回 值: 无
    - c* H* M' [/ x5 H; ^
  11. ********************************************/- x5 Q  X  `$ y, D" K0 `
  12. void DMA_Usart_Send(uint8_t *buf,uint8_t len)       
    * Y; u% u( D6 t* X4 D; `8 F
  13. {
      W4 p4 k3 A6 |/ A
  14. if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
    ) ^3 S$ l: N; i7 O5 \, c2 C
  15.   {
    5 |- G3 i" Y, {% q) |8 Y! h
  16.                         Error_Handler();                                                                                                                                //异常提醒
    * G/ S" t+ f0 S2 X5 u* q% r
  17.   }
    ) u+ {4 K( @$ O. ~+ [8 T2 q
  18. }6 u& W; M0 R0 p: l2 L3 i/ D3 }
  19. /*******************************************
    9 |4 t8 R1 ?7 a2 z
  20. * 函 数 名: DMA_Usart1_Read- S3 c% x, J6 E; n$ H7 g
  21. * 功能说明: 串口接收功能函数
    9 q% I7 ~8 P% c! h; \3 c% }/ k. x7 p
  22. * 形  参: Data,len
    3 S: k, ^, _! ]# B7 |2 H
  23. * 返 回 值: 无
    1 |" w. t8 l' f6 x# q
  24. ********************************************/
    8 t9 \1 E- X# q( Q5 H, d% j, D. u! U
  25. void DMA_Usart1_Read(uint8_t *Data,uint8_t len)+ h# x; C! ]1 ^
  26. {6 W8 Z4 P# a% h* i) }
  27.                 HAL_UART_Receive_DMA(&huart1,Data,len);                                 //重新打开DMA接收3 O0 r% {" `1 Y( \/ E# d4 K9 J
  28. }
    ( i- I8 ?: {3 g( h/ i
  29. /* USER CODE END 0 */
复制代码

/ Y* d) q# M5 V7 {( qmain.c  while(1)循环中添加代码如下:
% Z( |7 W% y/ d6 b  d
  1. /* Infinite loop */
      R4 n' B9 Z2 N' t2 U+ P
  2.   /* USER CODE BEGIN WHILE */" U8 C4 S$ K; M/ E3 b1 q7 W
  3.   while (1)
    / [+ R# ]% U% I" \' j) L: u
  4.   {
    1 v( n/ W: t8 M5 w6 d
  5.     /* USER CODE END WHILE */
    7 E' o- e$ C# P. A# g% i+ W( ^7 P$ l

  6. 2 G0 t+ o6 @! H* E6 g( [
  7.     /* USER CODE BEGIN 3 */  V# |9 Y0 z6 N
  8.                        
    3 d) R3 |6 ^( t! ~4 V" X+ j/ O
  9.         if(recv_end_flag == 1)                          //接收完成标志,如果串口有数据接收,则执行该部分
    3 |( g! L* z% U% V( m) S
  10.         {+ K" m, \7 T: `" y! H% P2 E
  11.                 DMA_Usart_Send(rx_buffer, rx_len);4 Q9 i2 m+ @& Q* F! [
  12.                 HAL_Delay(200);
    ( U) |( d( K5 k
  13.                 DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));        / R* g" N- }, ~4 e) G2 Q5 W1 `9 s. g4 x
  14.                 rx_len = 0;                                                 //清除计数
    / p: J! }" A1 p$ x. q. P3 Z1 o& l
  15.                 recv_end_flag = 0;                                //清除接收结束标志位
    5 O" N: }( `; y3 ^) b# q8 I8 z1 C) n
  16.                 memset(rx_buffer,0,rx_len);7 R8 ^1 b1 d0 a7 g) ~: p4 X# s) w
  17.         }
    * A  o3 j5 L. `+ e$ s5 W/ h8 I
  18.         else                                                                //如果外部没有数据,则执行该部分5 N% }* c/ t. b3 Q
  19.         {
    % D" U6 [9 o) g/ K2 s$ x
  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"));
    - V% m" c. H3 h/ T/ N5 j9 m! S' e' e
  21.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                //控制LED1闪烁
    5 |# _" f6 d% s3 g  N$ @% h; r
  22.                 HAL_Delay(500);1 T7 ?* F; ?2 C: d- P
  23.         }. ?1 h# {! |& \4 n# c
  24.         HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);       //重新打开DMA接收                                5 I1 W, m- p8 H
  25.   }" W2 w: Y7 J& R- F+ W4 m) _! j
  26.   /* USER CODE END 3 */
复制代码

1 M3 B) q% x( H2 N4 wstm32f1xx_it.c中添加代码如下:+ m% f2 l' m7 L+ u0 _) f4 x4 k
  1. /* Private typedef -----------------------------------------------------------*/4 V6 X# j* l# L5 T6 J' {3 S
  2. /* USER CODE BEGIN TD */! Q" T" A; ?) [
  3. #include "usart.h"
    9 B. w9 f- V4 |6 K( C
  4. /* USER CODE END TD */; v. O1 s- N9 x- I/ @  c
  5. % A9 h; W2 c4 |3 ?; D8 D& L& q0 U
  6. /**
    + t, U  l5 B; F1 R; d+ R
  7.   * @brief This function handles USART1 global interrupt.
    3 c8 O5 g+ v6 I8 [2 \5 y
  8.   */
    ' C; g$ \: [; K% i2 x6 h
  9. void USART1_IRQHandler(void)5 A2 F  N  w3 z7 ]) r. c/ B& l+ P
  10. {
    5 X' n$ u6 U% B; k
  11.   /* USER CODE BEGIN USART1_IRQn 0 */, @) C/ j$ `' E. H1 X
  12.         uint32_t tmp_flag = 0;
    + J- d3 g  P6 e  i' y+ t
  13.         uint32_t temp;% {9 s8 N4 K5 n- Y6 ?0 K
  14.         tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位" y; G, A. e' k& C
  15.         if((tmp_flag != RESET))                                //idle标志被置位
    / g6 F' F* i/ ^5 B8 ^8 G
  16.         { 6 o, g4 [4 p% ~9 m
  17.                 __HAL_UART_CLEAR_IDLEFLAG(&huart1);                //清除标志位& x  y& E1 u, |- c6 ?
  18.                 HAL_UART_DMAStop(&huart1);     / S$ R* ?9 t- r: b; f
  19.                 temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);   // 获取DMA中未传输的数据个数   
    , f7 q7 G4 A; V* _
  20.                 rx_len =  BUFFER_SIZE - temp;    //总计数减去未传输的数据个数,得到已经接收的数据个数
    0 ?& M1 y' \3 g9 Q& e
  21.                 recv_end_flag = 1;                                       // 接受完成标志位置1       
    + M% x  q4 [  e7 _+ B$ P. H
  22.          }
    # m" u) V, h* S& h2 f
  23.   /* USER CODE END USART1_IRQn 0 */
    6 y# \6 Q* A/ n2 a( ^5 p
  24.   HAL_UART_IRQHandler(&huart1);* C# r, Q* C6 M3 e! c4 G! R
  25.   /* USER CODE BEGIN USART1_IRQn 1 */
    " |4 ^+ h/ `( R2 n& s
  26. 2 q* W, k3 ]- N
  27.   /* USER CODE END USART1_IRQn 1 */, G- v* R; ^3 q
  28. }
复制代码
% g1 F# D# \& C: X) {. x5 ^
(3)至此,串口DMA收发数据需要添加的代码已经完成。
5 X- P, ~/ O0 ~; B

# S' h+ j1 G' ^) n& k% ]2 o" ` 5、设置编程仿真下载模式  c" X$ Q7 r- d8 F  c7 x
(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
0 @  A1 U5 O1 F
3 R* S* u; P. _  L
edefb6b9a2a14be3b1221ad6d5c7a8a2.png - Q5 v2 T% _+ N$ @' F; c/ U, p
/ g2 }1 V8 @% Y1 J) u
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
0 |8 {) X9 ~$ t) Q7 g) r7 n& A1 k5 N* K. m& s
f0ed816a3ed14487bf9e857c317fc99b.png
8 T. l! K2 Q/ x# C! x
8 k/ A( @: e  |! b2 t5 d5 N! w' @% |) V* I(3)点击Download(或者快捷键F8),即可下载程序。2 s$ \  A7 h  E# R% r
& Y/ q- \# W( D0 l
ba221842d5db40808aa129dd83c593d0.png
4 Z( g$ o8 N% u) t* X% F' E# E
4 C  w, A5 ?* d8 [) K2 ]9 w(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。' Y5 @2 d4 w1 B, W  L! Y
& n: |7 ^0 t1 h, q' ~9 z9 @, }
9f8aa1a4e8f04041bcf5cb183facd100.png 4 j, \; B) e) i6 Y

, y2 a) `5 z0 B/ p3 t1 l# f% T/ Z4、查看串口发送函数打印log效果
$ [, n7 C$ k) ]" r7 j(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。
% J' n2 l2 Y9 Y% s9 ?  [0 L: A
& n' T8 U( [$ W( U5 M(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。
7 W+ ~" k# q) |  `6 I' f
7 s& D6 [# y: f0 ^(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。! {, X; C5 @$ d1 n; N
/ W7 Y1 P6 l5 L* ?
16cd1063057845399adc6f45e25a20c7.png
. U, Y7 ~) t- ?' Y, w: e' e( M/ Q. p; V% {  \
————————————————
) l# L0 b& e( R5 e5 y版权声明:智能小屋ZYXC1 D; i3 ?& r' [

( }) P7 }1 r' P+ A  g: }  e+ n4 o- m3 a$ v
收藏 评论0 发布时间:2023-1-15 00:07

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版