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

【实测教程】STM32CubeMX研究串口通信(RS485)

[复制链接]
STMCU小助手 发布时间:2023-1-14 17:49
一、开发板平台简介:
, M7 P' W: f% A/ ?1、开发板资源简介
& k, ~" ~, ?) ~1 B9 [, F( S$ ]
(1)开发板主芯片型号:STM32L431RCT6
4 m) a) z( T/ z1 x! Y(2)开发板主芯片封装:LQFP-64_10x10x05P
0 y6 T$ d& _% d9 J% N(3)开发板主芯片内核:ARM® Cortex®-M4  l( M9 r& @6 c3 f( g6 N
(4)开发板主芯片主频:80MHz% Q( [0 w7 h: A4 o
(5)开发板主芯片Flash大小:256KB! E5 H  t& z! m, j/ G1 o# }
(6)开发板主芯片RAM大小:64KB1 m- I5 O& I8 T$ Y/ q& O! N5 Y
(7)其他外设:请参考芯片手册3 N% I9 w/ o( ~) P$ L/ I

8 @) @: V5 p$ F
bb91345227434ee7a43a34bf3fe366e6.png % {4 R- M. Z6 _
) h7 u6 j( n* [8 b8 x
929c0cce04aa4115a8623703982bf3e1.png
: b$ ^8 l) J: O& M3 Q: x' H
( |7 x, c2 w0 F: R4 T+ {' {6 x
2、串口简介. J5 L" Q( q0 s
         串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。: v7 V& h/ v3 y: ^
% m* {% z' |% j; {/ p0 m& [& c) v% Y
        (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。) m# w& H: q4 }  U2 j
  I! z! w+ o) a& I, ?( v6 J
        (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
8 m/ }6 d6 H/ e3 k8 G5 p$ x6 P2 E5 z

0 `- r$ K/ O' B: w9 {  二、新建工程
. k; r! m1 N/ n0 s# d1、新建STM32CubeMX基础工程
) S, G& _2 M5 k& v1 ^
(1)打开STM32CubeMX,点击“File”-->"New Project"​6 Z5 V0 W6 I% t4 v
) e- f6 G  A1 o$ A0 Q
2399170347904e959c855fefd5877f84.png
0 ~% c; S. u1 r/ b6 K1 y
, \$ h1 ]& M) }(2)等待打开主芯片选项界面(大约1分钟时间)。
1 c: K; m0 h$ J. }  g7 D
: \: X) y4 B# v+ E* B1 o1 j1 w
d74d2fdc60c9440483e2b7cf8d928e7f.png 6 [, F5 X* N/ [  p4 x4 Y2 \; R9 l2 Y

8 g8 G2 U0 B: i2 `9 T7 |7 N: G/ Y(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。' V5 t$ z8 i/ W( c; Q/ ]% ^

. I& ~) {, U* A9 K" g
7b80345238d74bea82ce70e1a348f7b4.png
  o1 \( n' k0 V. n! }) G. D; u
' h8 B% c. i/ e9 i4 e% [' _: x3 `(4)选择时钟源。; Q2 m% y7 N2 y. @( }. R
(1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。; F% H6 b3 ?, ^' k3 ~+ A

* ]' [) H& F; S" p! ]0 U(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。- n% [; b; G  O0 m3 d0 V
8 }) b7 Q+ U- f2 K& p
72119b971f62410fa8344f7f9fb9f389.png
1 b; p( m2 [- D. x6 c; e8 P2 `
5 h3 R# ~* W5 F$ ?1 H9 `' @0 @2、配置GPIO控制LED% i5 U& Y$ ]  F9 R5 V3 [  n8 l! U
备注:LED灯用来指示系统是否正常工作。5 y3 r7 }: f- K9 g5 |8 l
(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。% f4 o4 o( m- Z
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。$ V0 R+ b2 J  r9 v
  U. ~, O+ `/ F( S0 o. E) d
492907c1e71149819adbaee4516a2af4.png
/ I8 u8 v2 _) N$ L
4 D9 R+ S: N$ }; {7 @+ }9 F(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。​1 b# t! U" V4 n. T1 J; d- _
# O. {# f& Y! [) e2 t/ ~! M' j1 I
38ff4b80e1c5495ba3076a5158fd91fa.png 3 c/ A3 q% w. H5 H" _

' c% |4 J3 ?! E0 R9 v3、设置串口1参数. {- t7 \* E( j1 I- C
1、查原理图得知,串口2使用STM32L431RCT6引脚为PA2-USART2_TX,PA3-USART2_RX,引脚设置如下:
7 z, a& x0 t+ }8 n (1)序号1用来设置串口收发引脚的选择。9 b- K7 m$ M1 J  U4 y6 V
(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。- _9 G4 f: l  L( O, G
( l1 B- v% ]. E- @8 M* A
2、设置NVIC settings 使能接收中断$ n, ^! k$ _" w' ?% f

" K" [# R6 J9 `3 [
f9d7783b08304465815834f4d2095571.png 2 k$ y/ C4 |2 U
) H" d  m1 j# d
4、串口DMA设置
; |; ~' x9 C# e# Z: Q

, a8 T( B& n$ q5 `, _' A( D! ? 6d26b13dd9d34039a2b426ca47680f8c.png
' C5 A4 }" e0 Y( k

, e/ }' A3 A# c# U7 K (1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:
5 G8 E+ N, h! B; q# H点击DMASettings 点击 Add 添加通道3 c8 \- R1 ~# W# K+ c  b3 D
选择USART_RX USART_TX 传输速率设置为中速0 B2 z/ D6 C9 M! s" X) K7 p# u# ]; s
DMA传输模式为正常模式,即发送一次就结束。
% C5 w# }% F* E; M+ H4 f: DDMA内存地址自增,每次增加一个Byte(字节)
* y1 L+ L+ S9 m# @& q& a4 |
% ]& ?3 Q) M, g4 q 976712e0494a4482bf65c69fc09fcabd.png
% x$ r& `9 w  B% @4 J5 \  A' ^
5 l" y; o: w8 Z6 t. o/ @( M
(2)DMA相关参数解析2 Y5 Y! U/ k, C, c

9 @+ V% l  T: W, F6 L" H" lDirction : DMA传输方向有四类
: G3 P( ]3 y+ i外设到内存 Peripheral To Memory/ C, N  N! |" z
内存到外设 Memory To Peripheral7 P$ t4 p* l5 `( T; v
内存到内存 Memory To Memory
: H, p# u" ?& H外设到外设 Peripheral To Peripheral
9 l( t4 R- R- c
Priority: DMA通信传输速度有四类
1 @: p- b; v/ E: X, d# m' L
最高优先级 Very Hight
6 Y6 {1 ?- m- `9 d高优先级 Hight
9 n: K- z! |/ H5 J/ Q中等优先级 Medium
7 @4 ^/ Y% r# Z8 O! @7 [6 }低优先级;Low
& h' q0 k9 G; A1 d$ t$ M& Y+ f0 ~$ A
% O$ |6 Q7 _) f
Mode:DMA传输模式有两类
; L; N, f% E( W; z% w
9 ]5 `' H2 x; q* [; y1 _; A
9021c11fed3e4c1885477e062b846258.png / I2 T7 C  W/ J) `2 X, o
4 L2 v0 r. H# w- k- b( {2 a& G' `
Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
0 W3 j* p/ y# d+ g1 e5 @  ACircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。, g; Y6 B& i$ c# i% t. y

, i) ?' n: D( V; g% f) W( H
Increment Address-DMA指针递增设置:5 B1 u9 _5 I5 F6 u$ p! r. `# }
5 q% ^6 t8 A  \4 v
2b1a952d6514444e9dbb019a9ae88c42.png 0 _% e0 r  D" B, F! Z0 z5 q* t# Q

1 F' o; A) R5 q 5、配置项目工程参数
7 s( _3 I: [9 B" ^(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。2 c) m) y5 l0 B6 d! M
% k4 ~8 z: R* R( I( t
2ce1933c10484d819234682f4abc0228.png ; X# V$ ~7 ]9 u

) M5 ]% N' a9 G1 o- Y(2)完成配置工程。. y, I. Y! r' `
' k* M2 e  k& ^, u2 w
备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)
" A' J& }% W# U! O1 v' M" ^1 O; g; v7 [' ^! f8 }
efdb616174f54925b6eac31109f227b5.png
" U3 N+ ~8 [: [6 ~# p  i5 |; y9 p. z0 R$ L7 N
41c3f2716e4e4eda8f62fa3a1d871322.png   ?3 H3 R: }  p* F  S+ Y

# @6 F# q" P% U7 K" O; X+ Q(3)生成代码。3 \  _2 J" s3 p3 t
! I* p" a  u( T1 a3 w) z) D. j& N
8eaa7d0babea40ee93f158481a6ee471.png + s+ Z; \1 ?5 d! H! ?1 T5 w& E7 ]4 x

, n- h  Y4 n% S6 S: X" t  o; z- W 三、在KEIL 5中编写代码
  X; d7 T1 E' @0 U1、使用KEIL 5(MDK)打开项目工程文件

. h0 M7 D. D; Y(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。. M  v2 r0 \% \- u

! v2 u. d) V2 l3 e
9837b01954cc4d3ba3e25073f31b30b5.png
- p5 H1 o& S& l$ ^: l2 D! o4 ^4 g: t# n  m
2、添加LED指示灯作为系统提示/ ^/ f6 V4 A4 k. Z  I
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。
! d; b" d, T8 r! F4 U- x0 Y3 x
' H/ [9 P% V% Z& U
6ab72ceaeb7a41af833842fe5ba6f34d.png
, \, q7 C/ @- U$ A( F: p
+ b0 A1 x7 Q, {- {# v* M2 |3、添加HAL库UART  DMA 发送函数代码
) |& R0 i; o: D* g4 W: ?) B) i(1)STM32 HAL函数库的串口DMA相关函数如下:3 z2 l3 r4 B" \6 D& v( L+ ~: i
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制
    : u/ W  T  O5 U5 R" B
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制% E! o$ U# u3 [4 \
  3. HAL_UART_Transmit_IT();串口中断模式发送
    8 m* d2 k- g/ I# v( j
  4. HAL_UART_Receive_IT();串口中断模式接收
    + P( s: I1 n' @: B: G
  5. HAL_UART_Transmit_DMA();串口DMA模式发送: G- Y" y" Z. `* ^
  6. HAL_UART_Transmit_DMA();串口DMA模式接收  L5 P+ A  }, A/ ^6 n) S! z2 _
  7. HAL_UART_DMAPause() 暂停串口DMA( u2 i  p8 p+ e. w; \, i7 M" \- M- i
  8. HAL_UART_DMAResume(); 恢复串口DMA, ^1 J6 R% ~% J4 m8 U
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码

6 _' B! i2 e3 j; f& _: K(2)添加串口DMA发送log代码:
8 u, G. V! M# v$ }. r
  1. /* USER CODE BEGIN WHILE */) c7 p. C6 V/ D9 U, Q. d
  2.   while (1)
    6 ^$ Y, D% ]( _; T! O" t- W
  3.   {
    * F( L' z1 m: Y0 G) g4 P2 E3 P
  4.     /* USER CODE END WHILE */
    4 B$ ^& {/ X  D' e, T
  5. # b1 X* o! z& g; \% n* d2 w, |
  6.     /* USER CODE BEGIN 3 */
    6 i/ j! c# x- n2 |) |, d7 D
  7.             HAL_Delay(500);
    5 s7 z- C# I& R9 W8 \1 |
  8.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
    8 p4 A3 }6 t8 K) E0 E: u/ z+ C" L
  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"));//发送提示  2 T: i% e3 B: ]" z
  10.         }
    0 H9 ~+ g3 O3 C  ]( l" s  e
  11.   /* USER CODE END 3 */
复制代码
& A% b# L3 l0 n/ F; n% i+ q" I
4、添加HAL库UART  DMA 接收函数代码% _5 h- ]8 g# h4 n+ i! k
(1)DMA接收设置前铺垫知识点:
: W9 j4 }- T% Z( z. h) u        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。2 i' ^0 S* M6 u5 r
6 q* Y) K7 D4 |4 |
(2)初始化中断接收配置:
, p' d, L9 h2 S6 j2 ]% M7 @uart.c添加代码如下:
1 i9 j- I, @' H, n1 w, m6 B

  1. 1 H8 l2 u& x9 T/ [# E
  2. /* USER CODE BEGIN 0 */5 `4 X9 ?/ ~; O0 d

  3. - ]* `' ^0 P$ `
  4. volatile uint8_t rx_len=0;                        //接收一帧数据的长度
    ( ~4 G  `+ b3 v5 Q9 d4 P
  5. volatile uint8_t recv_end_flag;            //接收一帧数据结束的标志位
    1 ^1 z0 E! r% l0 D1 x
  6. uint8_t rx_buffer[100]={0};                        //接收一帧数据的数组大小" i. j2 [9 ]% K8 Y5 N
  7. /* USER CODE END 0 */
复制代码
  1. /* USART1 init function */
    4 H" T5 s# @# U- H* j& E7 J- {
  2.   X. M0 I/ O/ g- x. ^, @
  3. void MX_USART1_UART_Init(void)
    0 |& _4 U. g7 {. y: H% \; @
  4. {! [# B$ ~+ s% g, F! e( E

  5. 2 Z; E% Q$ t7 O) {  i7 C
  6.   huart1.Instance = USART1;. s  u1 _. e; I4 `4 J
  7.   huart1.Init.BaudRate = 115200;
    / E0 u1 V( L) X1 g
  8.   huart1.Init.WordLength = UART_WORDLENGTH_8B;! c+ S8 o( A7 R. v' Q3 p
  9.   huart1.Init.StopBits = UART_STOPBITS_1;
    * H; n# m' E/ L4 T5 |. w. |, ^
  10.   huart1.Init.Parity = UART_PARITY_NONE;3 K6 H1 |  `7 J. E* S3 S
  11.   huart1.Init.Mode = UART_MODE_TX_RX;; A5 U) a4 [9 L. H1 Y( z2 _6 [7 [
  12.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    9 x7 q6 r' o% }2 q
  13.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    / l4 T; S7 X# O' K* f
  14.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    " O6 `# U) J5 ?
  15.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    7 c# {" m, v; X3 I
  16.   if (HAL_UART_Init(&huart1) != HAL_OK)
    / B3 v. n. V% N8 N; r
  17.   {3 E6 T" Y$ h% r" n3 c7 A/ z
  18.     Error_Handler();
    - k. l( c7 e4 K
  19.   }
    ' k3 A# r3 p9 n. C2 H
  20.         /* USER CODE BEGIN 2 */( f& [$ U- Z% p, t6 g8 v
  21.        
    ) s) V1 c6 ], \# J8 G1 z+ S
  22.                 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                     //使能IDLE中断) g& W  y$ {& s" c3 i
  23.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);            //DMA接收函数
    7 V1 S" }" J$ ]) H

  24. , [: t* S# r6 _; g# p( h- y( X( m( k
  25.         /* USER CODE END 2 */0 X5 J. Q% Y- J  ~! Q2 p
  26.        
    ; k: N  s" k9 U
  27. . f% {6 }8 E$ v0 M& G7 t
  28. }
复制代码

* r5 A' W8 N$ C" Q& f! n

9 b3 Y6 g% W1 f. w7 r5 U) `uart.h添加代码如下:

( k+ _6 Z; ~7 _5 l' ]
  1. /* USER CODE BEGIN Private defines */: V8 |  B% t  j- r5 |
  2. extern UART_HandleTypeDef huart1;
    : I3 ~2 q. k, a. Z% y( e
  3. extern DMA_HandleTypeDef hdma_usart1_rx;" s$ {+ B" _( M9 y
  4. extern DMA_HandleTypeDef hdma_usart1_tx;6 ]3 I; |$ n4 x1 h* Y8 u; I

  5. 3 f0 P( {1 Z, N7 D, `3 e
  6. #define BUFFER_SIZE  100  $ ]  t* U) N# Q$ r0 q; V2 f) N
  7. extern  volatile uint8_t rx_len ;                                  //接收数据的长度5 G, ^% T0 }9 u+ l. r$ P
  8. extern volatile uint8_t recv_end_flag;                     //接收数据完成标志位
    & C- j/ z1 b( k& o8 P3 A4 |
  9. extern uint8_t rx_buffer[100];                                  //接收数据存放数组2 P9 r/ c- Z1 d7 Q$ G- n5 Q; a4 X

  10. 1 c% \5 Y2 E( r' ^3 ]
  11. /* USER CODE END Private defines */
复制代码

! L$ J5 P+ T; `. M1 I; Q/ jmain.c添加代码接收函数如下:" J+ u: |3 A1 N8 [: k% I
& D+ p% k: ?- I$ R+ H8 n- @) r& \8 ^
  1. /*******************************************: N0 R3 L8 d2 ~) T& \
  2. * 函 数 名: DMA_Usart1_Read
    0 l* x6 j( {  n  l
  3. * 功能说明: 串口接收功能函数
    ; c% m* y$ ^/ c7 O8 a! S  A
  4. * 形  参: Data,len
    ; i' m4 L% C( ~- X( A
  5. * 返 回 值: 无
    + c/ O2 v& T& N0 f9 h; u" O
  6. ********************************************/
    ; D; i3 k3 V4 d  A- W2 Q
  7. void DMA_Usart_Read(uint8_t *Data,uint8_t len)
    * l9 g2 x& X: d2 w5 \
  8. {                                3 A6 P. B0 B5 h$ W4 @
  9.                 HAL_UART_Receive_DMA(&huart2,Data,len);                                 //重新打开DMA接收) |5 ]! F# v8 O# u0 m
  10. }$ N) t* C2 x* u" I& S
  11. /* USER CODE END 0 */
复制代码

+ B. r8 a% x+ E4 b& o, |5、添加收发处理函数6 f! S/ }$ _; a1 ?9 ]" S/ \
(1)main.c  while(1)循环中添加收发处理代码如下:) ?$ I1 v+ A% y) d9 f4 y7 ?
8 d3 U1 b/ u. q. {
  1. /* Infinite loop */6 m9 z& l9 ?) p' I' I
  2.   /* USER CODE BEGIN WHILE *// w  b. q6 i5 V3 [1 i7 y, o7 u
  3.   while (1)
    ' W1 {2 w, L# [& B6 r* ]
  4.   {
    $ k, V% w- y4 R2 C* B" J$ B7 v
  5.     /* USER CODE END WHILE */9 q/ g+ U/ {+ M! E" I: R5 l; @
  6. , p6 V3 ?- ~7 f. A
  7.     /* USER CODE BEGIN 3 */
    1 T! F- U+ z: e) S
  8.                                 if(recv_end_flag == 1)                                                                                                                                            //接收完成标志,如果串口有数据接收,则执行该部分
    , \+ ~5 p# ?3 c1 r4 g7 D6 d
  9.                           {6 R: X7 c, }6 B. q
  10.                                          DMA_Usart_Send(rx_buffer, rx_len);1 v( P) j6 ^+ h5 a) G) x; C2 `- ~. }
  11.                                          DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));        9 _6 G6 }" P/ p- M" A- _' ^
  12.                                          rx_len = 0;                                                                                                                                                                     //清除计数9 @0 K2 f# Z5 s3 Y+ R3 e$ N
  13.                              recv_end_flag = 0;                                                                                                                                                         //清除接收结束标志- Q- Y1 q. A4 T' q7 v( K
  14.                                    memset(rx_buffer,0,rx_len);, J7 `# g) i# U+ m% Z% }) G0 t% Q
  15.                           }$ O" |6 J  u' s4 _
  16.                                 else                                                                                                                                                                                                                                //如果外部没有数据,则执行该部分) {$ f- N" G- r9 R2 R7 R
  17.                                 {+ y4 F- {; w2 b0 `& x4 B8 ]% Q2 x
  18.                                                
    ! O& {2 H2 P8 U# g( B1 z
  19.                                                 DMA_Usart_Send((uint8_t *)"hello world,this RS485 send...\r\n", sizeof("hello world,this RS485 send...\r\n"));3 Z; p. M4 c! v1 [: W$ l( P8 Y. M$ A
  20.                                                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                                                                                //控制LED1闪烁. ]6 j* \3 R4 E: }. l' p
  21.                                                 HAL_Delay(500);
    : \9 k. F& N% \4 u5 \
  22.                                 }# F( A/ r0 }& F3 U7 C5 y# M
  23.                           HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE);       //重新打开DMA接收                               
    , @' p- t1 V- h& L! D2 z8 _
  24.         }  _/ V& P- [( v4 w4 j8 i
  25.   /* USER CODE END 3 */
复制代码
  x3 L1 m, s, H9 w6 `
(2)stm32f1xx_it.c中添加接收中断处理代码如下:
5 q* O- v6 d' T# ~
  1. /**+ b2 i* Q% o1 _3 u$ L2 l
  2.   * @brief This function handles USART2 global interrupt.8 o6 y+ G" g5 |
  3.   */
    . d( F) F# A# l4 h* h: v
  4. void USART2_IRQHandler(void)
      r- W# C+ ?- |+ q5 f" j' p6 A. ^
  5. {( P' ]0 u- o) O7 L. J/ M
  6.   /* USER CODE BEGIN USART2_IRQn 0 */1 U0 j  V3 i% y+ n$ s2 Z* t
  7.         uint32_t tmp_flag = 0;8 u; W1 X0 L# r2 Z
  8.         uint32_t temp;
    " s0 I6 N6 Q# o- l
  9.         tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位
    + c6 V0 g+ Z# V9 @* T
  10.         if((tmp_flag != RESET))                                //idle标志被置位
    / Q$ w( c% k: s3 X5 Y+ ~
  11.         {
    : y0 c2 `' m0 @  [4 t
  12.                 __HAL_UART_CLEAR_IDLEFLAG(&huart2);                  //清除标志位" n2 o' E0 u2 h# L( Q( @: x! i$ a( T
  13.                 HAL_UART_DMAStop(&huart2);     7 ]/ M2 H' z& J$ o1 ]! @
  14.                 temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);     // 获取DMA中未传输的数据个数   
    ' ~0 ?5 D5 o# t) M( M9 M" ]+ Z
  15.                 rx_len =  BUFFER_SIZE - temp;                                             //总计数减去未传输的数据个数,得到已经接收的数据个数$ `9 w2 |6 \1 J* W- m; X
  16.                 recv_end_flag = 1;                                         // 接受完成标志位置1        $ `/ b; ~6 n( A( R5 K" J$ {. Q
  17.          }+ `( Y9 P' ?" c/ Z
  18.   /* USER CODE END USART2_IRQn 0 */8 l$ C0 `7 V' A( z2 m+ ~, N: O
  19.   HAL_UART_IRQHandler(&huart2);
    7 \$ f" I: v; v1 P9 \4 g: l
  20.   /* USER CODE BEGIN USART2_IRQn 1 */) T+ @. @0 W; z3 X7 Y2 u$ o
  21. 9 j$ m# E0 g( W2 B
  22.   /* USER CODE END USART2_IRQn 1 */
    * Z* m% z# }8 [4 c
  23. }
复制代码

3 h. E* O  K+ X9 T8 e/ z. E0 S(3)至此,串口DMA收发数据需要添加的代码已经完成。
* Z2 J$ e+ ]$ Z6 T/ @3 B$ y$ f5 G2 s4 P6 p) Y" J1 n; V
5、设置编程仿真下载模式
; v2 f! @7 b% @(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
$ j3 c& Z8 t& \+ ^1 _
" Q4 u% [8 B) k! O' k
edefb6b9a2a14be3b1221ad6d5c7a8a2.png 3 t) r0 I. i1 N
* @: F0 |! m) S$ |
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。1 A+ W7 z, P% K! J4 l: v$ {! o; l
: r4 G  Z3 a: H0 T: o' Y) F
f0ed816a3ed14487bf9e857c317fc99b.png : c& a/ R. c7 u& w5 {5 r& l

" }/ P7 X# ~* h' C' D, @+ J3 L" z(3)点击Download(或者快捷键F8),即可下载程序。
( S# N: l- K8 S0 Y4 v; Q! i/ \9 {* u8 a3 B$ _6 \. w6 L1 b# f1 E
ba221842d5db40808aa129dd83c593d0.png
- x0 l9 k0 `: }4 e, a& x( l
6 |& q! B- m* E(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。) |: A9 Y$ y4 J7 a* u" A
% i" Y, Q  j* ?$ q4 |! k
9f8aa1a4e8f04041bcf5cb183facd100.png 8 q3 e, V2 Z, I
" M/ Q0 e; P" I
4、查看串口发送函数打印log效果% }) i7 J* D" X1 U
(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。4 g. ~- W& A8 ]
(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。8 L: x8 e  _7 `6 g9 c3 d
(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。/ e% b( c5 V- W6 b* S2 D2 c7 D/ ?

; ~3 A& O+ d4 n1 W- G: U: g 8f65172eef06499987e27edddf5320f2.png
- t+ b' [: e! Q: X' V- z+ q& I9 G- O* C0 r" V! g! R2 B" T
————————————————- s& t6 R9 m: z& e; g4 y
版权声明:智能小屋ZYXC
0 |: P. P+ K5 E! y5 g1 V/ Z: E. i

# C5 b3 L, a& B! E* p
收藏 1 评论0 发布时间:2023-1-14 17:49

举报

0个回答

所属标签

相似分享

官网相关资源

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