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

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

[复制链接]
STMCU小助手 发布时间:2023-1-15 00:07
一、开发板平台简介:9 {$ L1 C1 r; ~
1、开发板资源简介
; d% W& K6 x4 ~9 Z- K6 @5 ?# |2 N4 |
(1)开发板主芯片型号:STM32L431RCT6$ t: G+ ^. {4 p& e/ F5 s5 r
(2)开发板主芯片封装:LQFP-64_10x10x05P
/ D; b8 Y& S& [1 F! t& D/ {7 V(3)开发板主芯片内核:ARM® Cortex®-M4  C0 F; d% r: z9 j$ e9 a
(4)开发板主芯片主频:80MHz
. x0 @8 U; O9 G(5)开发板主芯片Flash大小:256KB
1 T+ `. N3 R) C- V(6)开发板主芯片RAM大小:64KB
( Y; P1 F  h, U* F; R (7)其他外设:请参考芯片手册
, o" ^, \3 X: d" i
5 t9 |% q# o% B- W* G2 O+ o7 w
bb91345227434ee7a43a34bf3fe366e6.png 7 k& Y8 }/ M7 U4 p1 v* N
9 O9 \& ^$ g. `4 f% E
929c0cce04aa4115a8623703982bf3e1.png
7 K: k) {5 \  y0 z) [8 F( _
( i. l" r/ N  ~. `* L: s. |- j  Z2、串口简介

9 S" f5 M# D; @# a, P) z         串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。/ g4 j% c* u+ Y( S! a
  {# D3 R. ^+ I+ t  J) m. m
        (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。
7 q) E5 [0 [$ [$ u0 O8 {! N/ h4 k+ X: o# u" k# o3 ?8 m
        (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。! \+ `2 |7 n$ c! V; O
" |$ N$ \4 u! Z( K1 Y! H

( y8 H1 f' S$ g( d- o  I- y/ N& e& x  二、新建工程# f, E1 E5 C; V+ B  j
1、新建STM32CubeMX基础工程
% j9 ~  P9 I/ W' I. N
(1)打开STM32CubeMX,点击“File”-->"New Project"
% P, M: ^1 ]6 o5 w# a+ u0 L/ n+ P5 J! ]0 E0 x! K' q7 t3 J1 s
2399170347904e959c855fefd5877f84.png
+ V5 q: D! |4 o! y; k
3 f/ |, R, q% f0 Y0 h
(2)等待打开主芯片选项界面(大约1分钟时间)。0 w' z5 ]2 [; h6 _( M; v

  w: t/ w# b( {' B, [$ c7 J
d74d2fdc60c9440483e2b7cf8d928e7f.png   C1 D' n- j4 ^4 c0 k7 ~

  x% y+ R& P% b# }) g
9 O( b7 {9 f* x5 w& u
(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。
1 x$ H4 m+ `, I% E! ^! P- q$ e; }: U! s" w* Y
7b80345238d74bea82ce70e1a348f7b4.png / N3 a' T$ R% i4 u' ~6 k5 I
3 G; z8 Y! n" z" ~
(4)选择时钟源。* P" ?- u  o4 Q9 W- _( F* [& ?& ~
(1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。2 {$ J# `# v2 o1 X- Z' r- [
(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。5 F" x% C! |7 f, E$ P# v
) M# ^& {7 D4 {0 b' ^. f/ H
72119b971f62410fa8344f7f9fb9f389.png $ ^+ d4 q! I! U/ t( j# ?3 ~
7 F- M$ g+ C6 B
2、配置GPIO控制LED

  s  z1 q0 k1 m: @  Q$ l; z8 m备注:LED灯用来指示系统是否正常工作。% Q* v/ K& C+ o7 ?( V
(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。1 p: i  y8 q% D' n6 l/ N7 x
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。
+ z  f* @! ]- s9 o2 G9 ?/ h* V7 n! \$ d) [% ?5 B2 x3 D7 \* e4 _
492907c1e71149819adbaee4516a2af4.png * k% e  k/ ?9 M! U4 k* S$ |' z5 i

# s( b3 L. v6 m3 U9 A(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。
0 C" x7 d9 E$ r8 E! ^9 t/ V- {( S/ M0 h$ d% y
38ff4b80e1c5495ba3076a5158fd91fa.png
$ a+ E+ m# [" L. ?
: h; O* O! Y- z& x& z* r3、设置串口1参数7 W. N, l) K) X* \2 e& D0 m6 \
1、查原理图得知,串口0使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:
7 L/ o& k, n8 k, `3 z
; ?" a1 ?6 Z3 _% f
497b8ee0243e446784e64a3c31e8a26f.png
5 W% i! V( d% K0 f  W
/ f% _) K* v+ O5 o7 v: p
(1)序号1用来设置串口收发引脚的选择。
0 w- ^& ~6 l5 n8 Y

( M" ]+ b  [: h" p: q9 D, H(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。- n# \/ w- b5 l9 i- M0 e8 c
7 K3 N' X6 Z/ \, {: P
2、设置NVIC settings 使能接收中断6 L5 {/ O$ W" ^$ S* q* O* J

4 O' F$ a1 r9 G2 n8 M7 e+ A
f9d7783b08304465815834f4d2095571.png
3 ?+ M1 R: t0 u4 b9 d* i) m. [" ~4 h# Y  h, y( R- H' Z
4、串口DMA设置
$ {  f) [: p: q& g0 O" u

; Y% f5 ^) @0 I% `* n9 X
6d26b13dd9d34039a2b426ca47680f8c.png 2 v' x3 ^( C/ Q& H( p
5 d7 k8 K; |" p6 K7 y+ o4 Y
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:- B2 z4 Q3 ~, j: }+ a
点击DMASettings 点击 Add 添加通道4 {5 z2 _, l8 d1 e) ~
选择USART_RX USART_TX 传输速率设置为中速  |! ?8 @: C1 m
DMA传输模式为正常模式,即发送一次就结束。
2 f1 w1 J, o9 B! pDMA内存地址自增,每次增加一个Byte(字节), J/ u+ s4 i1 a9 T, e) i

+ i7 R, h1 c5 W
976712e0494a4482bf65c69fc09fcabd.png 0 G1 Z. A3 i2 _2 l6 N$ R# K
# n# u* j: ^1 L( a& K
, [' M! ]# w! w2 b1 {3 }6 o
(2)DMA相关参数解析
: {8 G! l; t9 \" q9 u, W2 U* E
/ A- I0 O) D9 `& @Dirction : DMA传输方向有四类
2 f- d' O4 M- |& X+ p: f( h外设到内存 Peripheral To Memory0 Y3 M& e2 m$ Q/ C
内存到外设 Memory To Peripheral7 S+ h7 @" p" V: i) z) g
内存到内存 Memory To Memory
2 A0 |; _5 |6 `% B$ m) S8 h外设到外设 Peripheral To Peripheral" o& b6 h: I1 f9 T$ @: z$ V# h
Priority: DMA通信传输速度有四类9 I/ G5 [" k6 Q" p) e
最高优先级 Very Hight# B( m3 K' b8 u6 R2 h: _
高优先级 Hight6 u! K8 s, L2 E5 y9 S% l
中等优先级 Medium/ O! T3 `5 K( M* R& c
低优先级;Low
3 a5 ?: m& K1 H0 T6 U! C  a- `4 t
& R# h/ {7 e7 q9 D
Mode:DMA传输模式有两类: \8 l9 q4 B& \6 l7 _

9 ^; x; m0 p, C) }  n
9021c11fed3e4c1885477e062b846258.png . G( g" t# w3 h' I6 w8 q

# I" @% A' ~' [& x( n

) E4 Z" m5 Q  ^4 _# T+ gNormal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。4 F) M: L7 D$ g
Circle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
1 t) r2 p$ }0 q" b
# P7 R3 e. d' F/ E; [( h
Increment Address-DMA指针递增设置:
$ \% v5 @0 |& ?0 s' I! L5 K0 ?, Z& q+ X
2b1a952d6514444e9dbb019a9ae88c42.png
" j  E; \6 u5 Q) E3 Z- J% l' V' u$ S  Y2 m+ B
) t- F' ]; P3 ^0 x: K3 H7 C: S, t
5、配置项目工程参数
4 q, M5 U& ~' I: `& \; a$ \! i* h(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。6 F- O/ c0 }5 }) f9 j

2 E; C+ x0 r9 v( h
2ce1933c10484d819234682f4abc0228.png , a8 F0 x7 _% y) B

/ [( J$ ^! C4 m! ?3 r) G, D3 J(2)完成配置工程。
3 F: y  U5 H  r) Y7 ]( g. ]% s0 l* q备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)
5 n6 _6 x& |( a8 J4 Z5 R
2 {4 }$ L) {" X# F' A8 F! w1 a4 a
efdb616174f54925b6eac31109f227b5.png
' W4 I& \8 u8 X- G' D6 w; Q0 `
41c3f2716e4e4eda8f62fa3a1d871322.png ; z6 ^* @8 D, V2 V) m
4 O( n: D; U  Z1 |) ^  k/ ~
(3)生成代码。5 B- W: {" A( V' y. e& E/ K

+ S" d- n, C  I# H8 b$ [
8eaa7d0babea40ee93f158481a6ee471.png
; H; y& m; G8 s) n7 O3 d
) v* [" a  y6 t, r5 D 三、在KEIL 5中编写代码# X) {, e) ], Y/ G' O
1、使用KEIL 5(MDK)打开项目工程文件

9 _3 [5 c, z6 ]  x- t9 q; x7 F(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。6 Z1 Z  I0 ~( N: s0 I1 d
- p" l. U. u$ B
9837b01954cc4d3ba3e25073f31b30b5.png
" n0 |0 d7 P/ F" F: r* J8 ?5 M4 N6 V9 n3 y: s5 m( l8 T
2、添加LED指示灯作为系统提示2 V) U& |& s. G/ J
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。% p* a* h6 O/ ~. p  `5 J

7 Z$ m& C0 v6 q1 ~1 x* B
6ab72ceaeb7a41af833842fe5ba6f34d.png ! T) e4 a( i: U0 P8 G8 K5 H

" d$ y0 F5 L( ~. R/ Y3、添加HAL库UART  DMA 发送函数代码
6 G% N2 D3 o" c- B# Q(1)STM32 HAL函数库的串口DMA相关函数如下:7 V- p/ B0 y6 N8 n" d2 a1 \
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制7 Q- Z( ^9 s0 }3 v9 c
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制
    9 r1 {  l/ n3 T: {: v8 f
  3. HAL_UART_Transmit_IT();串口中断模式发送
    8 ~- F% Y3 L3 |1 n
  4. HAL_UART_Receive_IT();串口中断模式接收
    ; g8 ?8 q- _' }, v
  5. HAL_UART_Transmit_DMA();串口DMA模式发送
    0 y* J6 k' ?8 ^' |/ y
  6. HAL_UART_Transmit_DMA();串口DMA模式接收' \9 z( O  d( F2 m8 b* Y+ d
  7. HAL_UART_DMAPause() 暂停串口DMA: C5 w6 K4 \  o3 m* M7 }
  8. HAL_UART_DMAResume(); 恢复串口DMA
    4 i  h. f- M7 K; d
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码

4 v7 O0 |# \# x9 C$ W6 O(2)添加串口DMA发送log代码:
! x* P' D8 s0 @7 {6 b# e. e2 W- v2 L
  1. /* USER CODE BEGIN WHILE */& m& S4 M# A! Z/ x% R
  2.   while (1)
    ! _) o! x6 ]) p* [4 Z
  3.   {
    0 N- f1 U' u+ ^- t1 |; ^+ \* N, E
  4.     /* USER CODE END WHILE */
    - d( B' y: b) g$ k" `

  5. ' H+ e% C2 E- D- ~+ E
  6.     /* USER CODE BEGIN 3 */
    / q& C/ p0 C7 m* v; j
  7.             HAL_Delay(500);
    , H( F) T/ {7 T8 B- c
  8.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
    0 `( t, _7 w4 `# @/ I* ]
  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"));//发送提示  
    . _$ e5 v, n; z" `
  10.         }
    5 ^9 i. M1 `, E4 u5 |
  11.   /* USER CODE END 3 */
复制代码
) f5 |+ Z1 i: U0 U8 w% [! Z! A
4、添加HAL库UART  DMA 接收函数代码

' e6 P8 _! i( B: P* H) L3 u(1)DMA接收设置前铺垫知识点:8 @9 D5 x+ L0 T
        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。
: ~* e* w& l4 ?4 `: `4 b+ n: E
; l' t: B8 |9 L: W4 s  w3 V1 S
(2)初始化中断接收配置:' |7 X8 z; X6 x
uart.c添加代码如下:
( m. }* |4 o4 ]$ l( B8 y( ]+ }8 G

  1.   D" a1 @3 _% V1 C% ^! D
  2. /* USER CODE BEGIN 0 */% E0 o$ l- M! S& I

  3. % O* M7 E; J# A9 S$ y5 @
  4. volatile uint8_t rx_len=0;                        //接收一帧数据的长度
    9 z2 }! o% K! Y6 |5 g
  5. volatile uint8_t recv_end_flag;            //接收一帧数据结束的标志位& }& O% p" `. q. Y0 p
  6. uint8_t rx_buffer[100]={0};                        //接收一帧数据的数组大小
    . l' B' L1 U; f: [0 ^
  7. /* USER CODE END 0 */
复制代码
  1. /* USART1 init function */2 x6 ]3 N. B( h3 z0 k$ c- @
  2. ; [2 ^/ J/ R5 ^! O% O$ R0 O
  3. void MX_USART1_UART_Init(void)8 F" P$ j' @9 w# I' Y
  4. {0 Y1 ?( j8 z" B6 i
  5. % @8 }6 m7 t& ~& ?( j
  6.   huart1.Instance = USART1;- X5 i/ a5 y. L3 Z: H+ ~
  7.   huart1.Init.BaudRate = 115200;: N% h+ \0 i% A" Z, Q
  8.   huart1.Init.WordLength = UART_WORDLENGTH_8B;5 h! r5 O; Y0 v
  9.   huart1.Init.StopBits = UART_STOPBITS_1;
    9 ~% p) R, A' S% J  Q# `# r- o
  10.   huart1.Init.Parity = UART_PARITY_NONE;7 Y4 @) o6 T4 M7 F2 b2 Y
  11.   huart1.Init.Mode = UART_MODE_TX_RX;
    * ^3 G# W# |  N' r
  12.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    2 t( B5 p8 k$ u2 U* y  u9 h
  13.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    : a4 P  \0 t# U
  14.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;& a0 r7 O. l: |$ U
  15.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;0 V0 H" W* v1 f3 }( {% q8 Y1 ~6 z
  16.   if (HAL_UART_Init(&huart1) != HAL_OK)
    # W+ ^! b$ f9 S. k  O
  17.   {
    7 }. N* f& q" ^  m  S( X1 X# Q
  18.     Error_Handler();
    . G) `6 }, U6 @6 a# @( O0 r
  19.   }
    4 `' @% ]4 {& L( s+ m# C. P& W2 o
  20.         /* USER CODE BEGIN 2 */2 }6 z5 ?6 b. G; ]4 G
  21.        
    6 H: s$ V7 c: m0 n+ l
  22.                 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                     //使能IDLE中断0 ]7 {' v6 [. R: S
  23.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);            //DMA接收函数1 _# g* Q& g, o$ c8 N; h

  24. , |8 h# m# V! D0 x4 g
  25.         /* USER CODE END 2 */6 G, m* n4 \( a6 ^
  26.        
    - k4 s7 b3 M0 y" s- y) `
  27. 4 h6 a* q* ~( X& \
  28. }
复制代码

( y1 s& l; g8 kuart.h添加代码如下:
) D- j3 w  a0 R
  1. /* USER CODE BEGIN Private defines */) h  I  y$ \: O2 ]& }0 f
  2. extern UART_HandleTypeDef huart1;* c/ ~% u2 P1 L) D) a2 H2 O0 u
  3. extern DMA_HandleTypeDef hdma_usart1_rx;& R3 }0 _2 ]4 u5 k" o# \$ T; Z
  4. extern DMA_HandleTypeDef hdma_usart1_tx;
    9 H1 k+ Y8 R$ h* p

  5. ' m6 f& ?3 e9 Q
  6. #define BUFFER_SIZE  100  & C9 S9 G( `, K4 d  F
  7. extern  volatile uint8_t rx_len ;                                  //接收数据的长度
    1 K( U' y) v7 f9 t7 _
  8. extern volatile uint8_t recv_end_flag;                     //接收数据完成标志位( Y- r8 @/ f( E* L  _  X9 H; [
  9. extern uint8_t rx_buffer[100];                                  //接收数据存放数组
    , W% \2 |0 x1 ]5 N% P; f
  10. - K2 K7 g0 N) F+ W. e* _1 w1 a8 I
  11. /* USER CODE END Private defines */
复制代码
7 ?  a$ G" B3 p; S  @
main.c添加代码如下:
% ]7 d+ a$ j5 E
  1. /* Private includes ----------------------------------------------------------*/4 i9 l0 ?  g3 Z
  2. /* USER CODE BEGIN Includes */1 \' R& D4 ^* \- [2 q0 o" q1 L
  3. #include<string.h>                        //添加字符串头文件, x6 G: T# u" `; b! n9 z
  4. /* USER CODE END Includes */
    8 N. w4 a# O  Y! v- h
  5. /* USER CODE BEGIN 0 */) ~; V& A5 e, I6 a' Z2 g
  6. /*******************************************, z. H* c# R( i
  7. *函数名:DMA_Usart_Send2 O; O7 O5 m( s, N6 x6 {$ x
  8. *功能说明: 串口发送功能函数
    - C! r7 l0 l# z
  9. *形  参: buf,len/ X% S% L" r, Z
  10. *返 回 值: 无
    - P! _/ r; }  H; m4 `5 A2 ^% y7 a
  11. ********************************************/8 m& [. X1 o  ]2 ]
  12. void DMA_Usart_Send(uint8_t *buf,uint8_t len)        # `; R' K( w! ^$ m9 z& q: X  d
  13. {8 C9 y$ R0 g9 D, m2 ^- q/ d3 k
  14. if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
    1 _* u0 T% b+ ]3 I+ y1 F
  15.   {
    " T5 v# ~5 x& `, l. X( Y0 w/ [- ]! ~
  16.                         Error_Handler();                                                                                                                                //异常提醒3 z3 P, c' l. K  X' k
  17.   }& F1 I3 x: i( j9 V7 k5 J
  18. }7 T4 j1 e* H+ s' u9 ?# `+ _
  19. /*******************************************
      m% B& |4 R* i4 r1 m0 w. y
  20. * 函 数 名: DMA_Usart1_Read
    / H$ c4 J8 A# x9 b# \2 K3 t
  21. * 功能说明: 串口接收功能函数
    , d! H7 C& Y8 c; h( K: o; d
  22. * 形  参: Data,len
    : p& [; Y$ {2 r9 k/ @
  23. * 返 回 值: 无8 d7 ^/ R+ }, I5 r* X
  24. ********************************************/
    $ E' R0 J6 Q+ l$ p- n
  25. void DMA_Usart1_Read(uint8_t *Data,uint8_t len)
    & G* x8 u3 W$ M: E
  26. {% W, j5 p9 o5 T9 d! f
  27.                 HAL_UART_Receive_DMA(&huart1,Data,len);                                 //重新打开DMA接收4 R" R6 |6 t5 M& \
  28. }; l: C. s# J4 F0 b9 {1 ?3 t
  29. /* USER CODE END 0 */
复制代码
# T9 g6 g/ ~% d* t' @0 [! W
main.c  while(1)循环中添加代码如下:
. D- H% g1 g& T& b
  1. /* Infinite loop */! B. y7 x& Q/ L
  2.   /* USER CODE BEGIN WHILE */: W  C" Y; s' @7 `
  3.   while (1)4 q% s& e  x7 D, p! v
  4.   {9 G. L# F- G$ R( v% q; o2 N. s
  5.     /* USER CODE END WHILE */* c$ P$ [9 d$ w" ?4 m# R
  6. 5 i+ n& H* v: v0 D& d
  7.     /* USER CODE BEGIN 3 */
    9 {0 D. r/ p6 t, {. C3 a
  8.                        
    0 V  H, _) e+ t
  9.         if(recv_end_flag == 1)                          //接收完成标志,如果串口有数据接收,则执行该部分
    % f$ P  ^9 w4 f5 l  M8 g
  10.         {
    # x. G5 F+ J, Y; Q6 a$ H
  11.                 DMA_Usart_Send(rx_buffer, rx_len);5 A) d1 S8 P) A; ?7 |
  12.                 HAL_Delay(200);$ ?% a+ w) f: Y3 p# P- c  o
  13.                 DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));        # [9 c( T2 }; L, {7 F* _7 z
  14.                 rx_len = 0;                                                 //清除计数
    3 G/ K# Z& ^. Y. R
  15.                 recv_end_flag = 0;                                //清除接收结束标志位
    : n( N& L* A% A9 p$ C5 G- {2 c
  16.                 memset(rx_buffer,0,rx_len);& D( F- \- G2 ^# Z2 U) e: U% Z
  17.         }5 b: I% x( Z$ [- c3 }& m4 o
  18.         else                                                                //如果外部没有数据,则执行该部分1 P* F+ o0 F1 B/ u" l
  19.         {0 l) ?; V% U2 q: l( Z6 Y) X; b# l
  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"));
    / x1 x6 G* m, u8 q5 e' c7 u) w6 J
  21.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                //控制LED1闪烁
    + e& S) W3 V& g! e1 n
  22.                 HAL_Delay(500);  K  x0 l9 `, ~7 P* q
  23.         }3 M1 s* \* U8 F; Q- p! \5 g+ @
  24.         HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);       //重新打开DMA接收                               
    1 M* N% {5 I6 k
  25.   }
    , {" J; S, _9 t1 ]% Z. a) ?& ~
  26.   /* USER CODE END 3 */
复制代码
- l# U# @5 C" M$ `* |7 L
stm32f1xx_it.c中添加代码如下:  A9 g( T. ?, b2 s" s
  1. /* Private typedef -----------------------------------------------------------*/
      c; b( s- D6 f$ c4 \
  2. /* USER CODE BEGIN TD */
    - ^6 H4 K  c  n" y
  3. #include "usart.h"* n  U& ]6 Q4 H; p, |5 Q2 C
  4. /* USER CODE END TD */; r% u) I7 S) V* y  |% y" V

  5. 6 t  t: Y- J3 ]
  6. /**1 z' v" M! _% y) B* B
  7.   * @brief This function handles USART1 global interrupt.- J* e! b% A! P8 a% S
  8.   */
    & f& A9 K5 m$ _1 ?) S9 j
  9. void USART1_IRQHandler(void)
    $ t9 N% E( S: a' u6 D7 T, }
  10. {$ C6 k" z2 F! r' c% `
  11.   /* USER CODE BEGIN USART1_IRQn 0 */
    8 L4 p  H$ z& Q7 V3 }7 }& p
  12.         uint32_t tmp_flag = 0;; E! N6 L0 N$ E8 L7 c, V9 D7 A
  13.         uint32_t temp;7 p- r2 O( t4 ^3 ]9 e: L/ M6 j) V4 b8 ^
  14.         tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
    ( Y# _- }! s! m
  15.         if((tmp_flag != RESET))                                //idle标志被置位  l( B+ P( i, [  M& B* d
  16.         { ) _  o$ L; `3 d' b+ U
  17.                 __HAL_UART_CLEAR_IDLEFLAG(&huart1);                //清除标志位. u" w9 |1 b$ l5 X* a
  18.                 HAL_UART_DMAStop(&huart1);     
    * o# i7 P6 U' n7 L' o
  19.                 temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);   // 获取DMA中未传输的数据个数   
    & q( |3 r- y6 X
  20.                 rx_len =  BUFFER_SIZE - temp;    //总计数减去未传输的数据个数,得到已经接收的数据个数: |! {. v5 E5 \6 |& m! [; p
  21.                 recv_end_flag = 1;                                       // 接受完成标志位置1        # y7 @& P. W! v) |
  22.          }- ^1 O4 L' Z; y8 s
  23.   /* USER CODE END USART1_IRQn 0 */
    . A" _( L+ W" n2 G1 ]* x+ R
  24.   HAL_UART_IRQHandler(&huart1);: D% T8 b* E$ N
  25.   /* USER CODE BEGIN USART1_IRQn 1 */$ f3 i( {' R6 t# W! Q5 l! v
  26. 1 ~' y: C$ u4 R6 E5 y1 R- l7 V
  27.   /* USER CODE END USART1_IRQn 1 */
    # c6 c* H' [; t5 Q  @
  28. }
复制代码

. w  m7 b. w. z7 \" @) J# W& P! f(3)至此,串口DMA收发数据需要添加的代码已经完成。1 }8 m# j* m9 Z' ^9 N! ~2 f: R+ _

3 ^0 D9 J1 Z# W2 u  P# } 5、设置编程仿真下载模式
" m3 Z0 [, Q: @  V(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。1 W8 v; ?/ D. m2 J$ A
. C2 Q7 i$ w3 k7 e2 f$ R7 j
edefb6b9a2a14be3b1221ad6d5c7a8a2.png * }. p. F' V/ N% O: w# Z* |4 h) g" y

2 `+ l! C# e9 ^(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
& d' s  r9 _! s) {2 u8 T4 ~4 A1 r! S3 r6 \9 b: ]2 F
f0ed816a3ed14487bf9e857c317fc99b.png ' ?4 a  s( P+ L$ ~
. {) |; i7 \! ]) ~" T' i" k
(3)点击Download(或者快捷键F8),即可下载程序。
+ B! P6 n5 C8 a! |8 S
0 |/ M) R( D8 L3 j( r
ba221842d5db40808aa129dd83c593d0.png
) s& a% S$ `/ J5 p: L. T4 u1 K% I1 |
(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。
0 R6 Q) Z8 M* c* r% Y- q5 b& P* b
9f8aa1a4e8f04041bcf5cb183facd100.png
, |! c8 A' u; y0 l1 ~0 `- ^
8 O3 S* c2 t8 K0 Y1 D! E4、查看串口发送函数打印log效果
' I0 Y( I$ b& O  h' Z. n; o(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。
, o, ~1 q5 }6 `0 f# h% ?* H! n2 D% q& p& D5 b+ @
(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。& _# o! `: V( k) U' ~) K! b; y

4 P; h3 ~5 p+ ^4 ~. l; C$ |(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。9 \% B- v( n6 k& c

  d: M& N+ e/ ~1 m
16cd1063057845399adc6f45e25a20c7.png ; d0 @: G3 \# Y! {
  [3 u" q0 L+ P8 t  P$ S
————————————————: v4 B7 a2 x. b/ @
版权声明:智能小屋ZYXC
, x+ @" S+ D* F! E6 h8 z" N! A
* X0 m! a4 H0 N6 n) X8 N5 w
- h9 e2 X. l% o5 A- V7 u- q/ o
收藏 评论0 发布时间:2023-1-15 00:07

举报

0个回答

所属标签

相似分享

官网相关资源

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