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

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

[复制链接]
STMCU小助手 发布时间:2023-1-14 17:49
一、开发板平台简介:9 {0 M( Y  J3 L0 H
1、开发板资源简介
9 W9 k+ Z% y- H
(1)开发板主芯片型号:STM32L431RCT64 s+ g" O; s0 a. F
(2)开发板主芯片封装:LQFP-64_10x10x05P: s* G& n/ n, |" w1 d$ P! p6 m
(3)开发板主芯片内核:ARM® Cortex®-M4
% O- m- [2 W& p(4)开发板主芯片主频:80MHz6 }4 a7 t1 a1 `& D2 F. C
(5)开发板主芯片Flash大小:256KB
$ w5 M! V5 _& _5 }% F* K3 a# j& R/ `(6)开发板主芯片RAM大小:64KB  U- ]% ]% x) q4 V+ `9 @( b- x
(7)其他外设:请参考芯片手册
+ G( u1 V3 {3 k$ ~2 T8 y* X% }% ^/ D. S5 R5 w
bb91345227434ee7a43a34bf3fe366e6.png
' {" Z4 o, @* A( s& _
% g; ?7 D0 T, x6 }$ P 929c0cce04aa4115a8623703982bf3e1.png * [7 l8 o6 f3 i1 R9 J8 a/ e+ F) @+ q

! N9 P" {0 ^# Q0 e0 h2、串口简介& ~1 w7 T( f3 E9 A
         串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。, [5 x+ c' {, B  `! O7 f, Z

+ z) Y8 w* J! f4 k$ s' Q        (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。6 _, Q/ p3 ?+ R0 ~: R# [0 U' V/ T
$ k/ w0 E$ N( a6 H, f. w4 ~
        (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
: M) G- u0 Q9 a3 w: J9 q0 i7 B7 a" L7 \

6 X  [8 a- ?  C3 z: v4 e  二、新建工程
! K9 j6 \6 |( L1、新建STM32CubeMX基础工程

3 ~/ C! q8 L" o4 A6 ^(1)打开STM32CubeMX,点击“File”-->"New Project"​, E$ ~2 P# y7 b9 r; T0 n7 M7 ?
- @- d* a6 |2 p8 x# f
2399170347904e959c855fefd5877f84.png
1 S1 r; O. a7 @( M7 P% {7 @- E
& C# }6 O2 @/ d: ?# Q4 s(2)等待打开主芯片选项界面(大约1分钟时间)。
' J6 J7 S1 U' h
) m( c$ x1 S% }$ |0 @
d74d2fdc60c9440483e2b7cf8d928e7f.png
! e$ ^0 c5 Q7 C6 ^( w/ a3 T- J4 @
(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。
1 ~7 H) E" Z) _# O& u5 e' K/ j) R8 a& R( ~
7b80345238d74bea82ce70e1a348f7b4.png ! ]- b4 Z9 r6 g; H  L1 y0 y  c- V

3 G" m- k3 ]& Z" D( C4 h6 N(4)选择时钟源。
- x( _4 r3 e/ R5 S) k, H! ~0 J5 n(1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。
1 y: z. C$ f5 F
1 O& X9 K1 o: D  w- c! V(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。
% W3 N7 h0 h' l, x/ v$ ]( r; Q* b* V, Q5 K+ u
72119b971f62410fa8344f7f9fb9f389.png
  X3 n- S, R. }! A* Q$ e! q( C* ~' s
2、配置GPIO控制LED
, V/ z4 T- `/ l& O备注:LED灯用来指示系统是否正常工作。" I# ]$ c% p  W$ I$ I1 p
(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。- W) B0 e0 {  N8 t
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。
9 l! i' K/ D; f3 P
' j: |2 \* H% U
492907c1e71149819adbaee4516a2af4.png
( S2 a/ t* z- \) e& V+ ?
/ p1 \& v9 D5 H6 T/ G8 @/ E(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。​5 f4 s) U% C7 d9 u1 e

, I2 ~+ |' E5 L2 s
38ff4b80e1c5495ba3076a5158fd91fa.png
8 M$ L3 M' W, `/ E7 G" r

# L6 A( A  }* Q% J# I, b. m$ \$ I3、设置串口1参数
% D) G: K* Z9 U1、查原理图得知,串口2使用STM32L431RCT6引脚为PA2-USART2_TX,PA3-USART2_RX,引脚设置如下:) P1 d  j4 z1 q; y
(1)序号1用来设置串口收发引脚的选择。
$ g" M! [) r8 Y" [(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。
5 T; n. X/ x0 J* H
. Q2 s8 f& T7 ^2、设置NVIC settings 使能接收中断
# y3 \- Q6 p4 U: V' m  P" G! _3 H# `$ C+ ^4 \1 S
f9d7783b08304465815834f4d2095571.png
" C) g5 `' G+ C# N5 E, e: v
( i( I1 N7 G4 D+ G( @4、串口DMA设置

/ e' ~( i8 \- m+ @1 p  ]5 o' m
" `( g( R  n! X2 T5 g: J 6d26b13dd9d34039a2b426ca47680f8c.png * V" Y  ^4 j) X

3 B- X  G! X1 p: Z# H6 x6 B( I (1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:
  c0 G( i; W7 [/ _点击DMASettings 点击 Add 添加通道
0 g( o$ E' ^' x  s选择USART_RX USART_TX 传输速率设置为中速( ]$ W2 k7 [' ~) a* V
DMA传输模式为正常模式,即发送一次就结束。
" ?3 s' _8 E8 \+ ^( e4 J0 _DMA内存地址自增,每次增加一个Byte(字节)
/ ~0 P* _" I1 g) F- @
' G8 a+ }  C) I1 U9 w( o8 L+ [ 976712e0494a4482bf65c69fc09fcabd.png 7 P/ m) |- M& |

" ^! _# ~- f* K(2)DMA相关参数解析
: J8 c$ R$ h+ J# R6 @8 k0 f) y8 f9 B% Z/ j+ Y' }# j
Dirction : DMA传输方向有四类
9 F0 Y" N2 q7 w; H; N8 z外设到内存 Peripheral To Memory
& R6 w3 l) f1 E( P$ D; f8 h内存到外设 Memory To Peripheral# y, r# q6 x, J% a2 O5 c
内存到内存 Memory To Memory, Z& ^/ b; M, V
外设到外设 Peripheral To Peripheral
; U0 `1 m) m3 ^- I' u0 X) P
Priority: DMA通信传输速度有四类
' l, k! Y0 e. s' U( T3 M6 z8 J3 A
最高优先级 Very Hight
: u& z/ m" J) X6 Z. }2 M+ V高优先级 Hight
( c# ^* E: x: N% m7 v3 _  e中等优先级 Medium
3 B% r! ]" Y' ]8 _* G4 r9 H/ ?9 ]低优先级;Low4 I% ?) f; r: j6 t
: S: u# @6 A& J) @2 p; B$ s+ S
Mode:DMA传输模式有两类
2 I2 r" x# y. c4 b9 L: Y" [8 @

6 Z1 z7 M: `: h1 ]: y3 K* q: u! n$ G
9021c11fed3e4c1885477e062b846258.png
1 L# s3 D* c, w4 q; b$ k2 l& X
; c! j6 s  E0 K- L* u1 \Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。6 p, X! L6 V% x
Circle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
& a- R, R" [. m) A+ @4 Z6 a% x+ S8 E& m
Increment Address-DMA指针递增设置:
/ {, }- K+ @# x3 m" y
# v2 M8 q" ~9 f; t5 r
2b1a952d6514444e9dbb019a9ae88c42.png # d, n7 z: k: O4 e' }# g) h4 x
) C# u1 M* L1 p
5、配置项目工程参数+ _2 s2 ~6 `& M8 B" F( ?5 _
(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。! e' v& L. G8 H/ \1 |

7 r( a4 |( ~+ d, H
2ce1933c10484d819234682f4abc0228.png
! g( D2 `. h& U2 u; l
+ D% m9 O" D: \: e8 E7 z2 v3 e(2)完成配置工程。* M; X" l# {# ]" ?  _6 g
1 L  }/ Y8 n0 z$ o6 a
备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)( j& j5 _2 X% L; F9 a  S; T

) a' v8 d. e9 Q
efdb616174f54925b6eac31109f227b5.png
* J& o: m# r) Z" i+ }% c7 l% W8 x6 D: p6 Y3 F: d
41c3f2716e4e4eda8f62fa3a1d871322.png
; i  H  G+ @6 W+ t/ O5 s

/ R. f) i2 c' D& `(3)生成代码。( ~, g/ {( o5 J" Z( S, e7 c
/ ]% s0 U8 E! u) D; ]2 D7 @
8eaa7d0babea40ee93f158481a6ee471.png
. J" Z. Q* o; _. S2 k+ @
( _3 z2 X( e" P/ g. p+ ^1 s+ U 三、在KEIL 5中编写代码
: I. a4 ^5 o8 k1 Q1、使用KEIL 5(MDK)打开项目工程文件

$ W- _+ l6 o, ^5 h(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。
" n! e: Q( ~8 m- v( G1 h' b& K" D' k  m" N- y" C  a
9837b01954cc4d3ba3e25073f31b30b5.png 9 P: i( a. |& d% V4 x

! Y1 c- z3 J+ v# |, J) Q8 X2、添加LED指示灯作为系统提示  f7 A0 N  p' S; R7 D
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。/ H2 d( J( W' I) m& O5 {, h

* N1 _+ K" @& I9 c1 ]/ V3 r
6ab72ceaeb7a41af833842fe5ba6f34d.png
9 g" C. I, K6 l# q5 y4 t
& w! W! s: A$ G% a6 J- h' G3、添加HAL库UART  DMA 发送函数代码
( `) z* s# H0 P6 n(1)STM32 HAL函数库的串口DMA相关函数如下:3 O! C( T7 B/ ~! k. v
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制
    " G* z; D! x3 G' C
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制" D( x2 ?- ]% C
  3. HAL_UART_Transmit_IT();串口中断模式发送8 L$ j- `8 p% a& o; K
  4. HAL_UART_Receive_IT();串口中断模式接收
    - N% K+ J! g( o
  5. HAL_UART_Transmit_DMA();串口DMA模式发送
    6 c$ |, T( P$ R" b2 @
  6. HAL_UART_Transmit_DMA();串口DMA模式接收- _  [4 ^7 F" T
  7. HAL_UART_DMAPause() 暂停串口DMA
    9 h" ^" o5 O. I+ B
  8. HAL_UART_DMAResume(); 恢复串口DMA
    ( j$ f5 o' ]  f4 y1 ]
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码

( E+ e# l9 Z8 T1 f) X& ]# s(2)添加串口DMA发送log代码:
- t6 `$ ~( D8 X( a! Q0 U7 b  @
  1. /* USER CODE BEGIN WHILE */
    . P5 S4 P6 R" O) f
  2.   while (1)
    7 e9 \2 ]! ?1 V! u, N
  3.   {
    2 ~4 O% ?4 d5 g$ d9 }
  4.     /* USER CODE END WHILE */: Z( i! Y( |3 g9 I$ q: V: D1 t; C; H
  5. , z1 |8 F3 @1 N2 C5 X
  6.     /* USER CODE BEGIN 3 */
    9 n$ t; h' F. v
  7.             HAL_Delay(500);* c. [1 M+ [3 z) k7 T
  8.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
    - C; ^* G, q" Y- E. I- E* k
  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"));//发送提示  
    ) m" f4 `$ P4 v7 O% y- B
  10.         }5 a8 _: k: O6 u! k' q
  11.   /* USER CODE END 3 */
复制代码
. u, l$ R; @0 X6 A, C
4、添加HAL库UART  DMA 接收函数代码* x8 b' V; d, x' S4 c5 O
(1)DMA接收设置前铺垫知识点:
; p9 @$ M$ L1 }6 @* H        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。
) v* Z* h* v* V+ y; X0 O; |! {* ]
# c( k5 m9 [1 n7 J* z. d(2)初始化中断接收配置:
6 J( p: Q  v# S" a$ k' Luart.c添加代码如下:
( C* a  h# w( k

  1. : I, f+ ^6 Z) ~% }
  2. /* USER CODE BEGIN 0 */) V8 P, t5 |) v4 _, W
  3. * y7 x! m. S5 T$ g# j0 h/ K1 S. |* M
  4. volatile uint8_t rx_len=0;                        //接收一帧数据的长度
    $ c- G# t  O7 v8 \
  5. volatile uint8_t recv_end_flag;            //接收一帧数据结束的标志位- V# k: F, D/ p6 G4 J) c; k* g
  6. uint8_t rx_buffer[100]={0};                        //接收一帧数据的数组大小9 y5 V7 }0 S- I7 ~
  7. /* USER CODE END 0 */
复制代码
  1. /* USART1 init function */6 q0 Y- _8 A; }& D$ N: l% K! e1 O! F
  2. 3 K! t) j6 R7 n1 ]6 [. z( u) r* [
  3. void MX_USART1_UART_Init(void)
    4 n4 a/ F) g' L( _/ M! P: Q/ }
  4. {
    7 O8 \* O, \- y5 x4 m' T

  5. 8 f: c1 y6 v# ^* i% b: k
  6.   huart1.Instance = USART1;
    5 Z0 y8 y  A0 v& X
  7.   huart1.Init.BaudRate = 115200;; y8 k- E5 ]' m& e0 m! t2 u" |
  8.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    0 I& b* O/ ~7 z) B2 }5 P
  9.   huart1.Init.StopBits = UART_STOPBITS_1;
    ! g8 B2 r- e1 ~5 J' i( N( E
  10.   huart1.Init.Parity = UART_PARITY_NONE;3 G0 V# w5 L6 ]8 [8 w
  11.   huart1.Init.Mode = UART_MODE_TX_RX;& H0 ~3 t1 a5 a9 C* d
  12.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;* L( ?" M2 w# R! D* G0 J5 r
  13.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    & t: j2 q" e2 x" t- |8 a3 T
  14.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    ( L$ F- D; \3 J) f' W' z) j- g
  15.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    " a% w$ c* s* n' a  W4 V; V
  16.   if (HAL_UART_Init(&huart1) != HAL_OK)
    : s4 _, j9 |8 K
  17.   {
      F* J0 g9 g# d/ a% n
  18.     Error_Handler();
    . D3 Y% l  ~2 T
  19.   }
    1 ~' Q$ x. Y, n( F# Q3 S. Z1 P* f6 w
  20.         /* USER CODE BEGIN 2 */9 z6 `3 S6 w1 q, u6 ~7 p) v
  21.         " }' }5 Z6 [  o5 x: g
  22.                 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                     //使能IDLE中断$ g! F3 q1 z9 i, r
  23.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);            //DMA接收函数
    $ ?/ h) P* c0 {  e
  24. 1 r4 T& O1 d1 o' Z
  25.         /* USER CODE END 2 */# U6 f, b7 k3 p) i2 B* C: K& d: B
  26.        
    / c1 Z, b! f8 R: X+ P
  27. 5 L0 j  R/ [" m2 ~9 r
  28. }
复制代码
3 E7 B6 F) z3 q* r' o8 }6 a/ t( _  d4 `

% L- l# y; X! T! v- xuart.h添加代码如下:
' S6 q0 Q  F& C2 A- ^. d
  1. /* USER CODE BEGIN Private defines */
    1 Q4 O9 \8 H( N! k( ?* m. ]3 A. X
  2. extern UART_HandleTypeDef huart1;
      Y7 O& @8 r, T6 X9 J
  3. extern DMA_HandleTypeDef hdma_usart1_rx;1 @# j% B5 z% @4 w: j
  4. extern DMA_HandleTypeDef hdma_usart1_tx;, i9 c2 B9 Z" w1 K. J/ s

  5. " _5 i) t$ Y9 U/ z% G8 C$ V/ [
  6. #define BUFFER_SIZE  100  
    * w, V: |+ G- n
  7. extern  volatile uint8_t rx_len ;                                  //接收数据的长度+ X4 g% u9 @% }
  8. extern volatile uint8_t recv_end_flag;                     //接收数据完成标志位! }1 ~, Y. F2 o7 D
  9. extern uint8_t rx_buffer[100];                                  //接收数据存放数组! n9 w& p6 q! I% X! O
  10. ( H" h( b3 z. i9 o+ X( u, v2 H( S
  11. /* USER CODE END Private defines */
复制代码
$ E. J& m" I% T8 O5 n% t
main.c添加代码接收函数如下:
' t3 w& B9 U2 x# K$ }4 U% ?% _1 j- f. @% V- q
  1. /*******************************************
    0 N! v4 J" W# V& E/ @
  2. * 函 数 名: DMA_Usart1_Read
    ! {# t8 Z* e$ u9 ~" _5 Q% r: \
  3. * 功能说明: 串口接收功能函数
    9 ?1 ]+ _0 n7 ~, x4 @* p& E
  4. * 形  参: Data,len( P; M6 j+ d5 F6 i. m9 b& e
  5. * 返 回 值: 无
    9 R3 n) p; ~7 h; l7 [$ h
  6. ********************************************/
    6 |$ [3 `( ?; O* I& T5 g7 B
  7. void DMA_Usart_Read(uint8_t *Data,uint8_t len)
    , Y* \4 `7 N$ @( L
  8. {                               
    % e; M: g0 m7 _4 y- k% e. }
  9.                 HAL_UART_Receive_DMA(&huart2,Data,len);                                 //重新打开DMA接收! T- i$ M1 b! s! i% }
  10. }* e9 r! {* P) i. z/ z
  11. /* USER CODE END 0 */
复制代码
: o1 x* |: _* B( r% ?7 X# A: r  B
5、添加收发处理函数0 w" h- F) V. B) h4 O$ K$ @
(1)main.c  while(1)循环中添加收发处理代码如下:0 m- [; V2 T0 ^1 B/ a# ^7 K% ^7 _

0 q) r0 v& }$ _+ ~* T. X. N
  1. /* Infinite loop */' P/ o# t! }% }# H
  2.   /* USER CODE BEGIN WHILE */* b. X, N! G; T- K# o! n0 E
  3.   while (1), K3 ^: `( e+ @# i
  4.   {, P) B+ L# ]. |
  5.     /* USER CODE END WHILE */
    1 M' |1 b. O& `$ o- J! O

  6. ) j& `4 D3 J8 |: h9 z1 c( S0 }
  7.     /* USER CODE BEGIN 3 */
    ; q1 u# d& `* j6 j
  8.                                 if(recv_end_flag == 1)                                                                                                                                            //接收完成标志,如果串口有数据接收,则执行该部分
    8 u9 [$ L% I2 P. \3 e4 H
  9.                           {+ M6 @& W4 t2 E$ E5 v
  10.                                          DMA_Usart_Send(rx_buffer, rx_len);
    2 i% G6 I! v1 R3 t) x$ e
  11.                                          DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));        5 n1 f3 R' z8 M8 O' g
  12.                                          rx_len = 0;                                                                                                                                                                     //清除计数' a6 r9 v1 s( C8 S1 |+ U
  13.                              recv_end_flag = 0;                                                                                                                                                         //清除接收结束标志
      W1 P; w; G& P+ |) @4 F. V) ~. Y$ y
  14.                                    memset(rx_buffer,0,rx_len);% j6 B0 S, s- k8 ~
  15.                           }
    ) Y! R# n5 `" ]0 P
  16.                                 else                                                                                                                                                                                                                                //如果外部没有数据,则执行该部分, D  Z& @6 b$ F& y% _  S$ I
  17.                                 {8 f. Q6 I$ H* g3 R' d! h
  18.                                                
    6 ]7 @0 ~. D+ p
  19.                                                 DMA_Usart_Send((uint8_t *)"hello world,this RS485 send...\r\n", sizeof("hello world,this RS485 send...\r\n"));
    3 n- c8 m) N! m& z. l
  20.                                                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                                                                                //控制LED1闪烁
      w6 ~# _! C1 _- {. C+ Z" Y6 v7 d
  21.                                                 HAL_Delay(500);9 P" [& H5 s/ p! o, ?& ~
  22.                                 }
    ' ?) B' o. C/ \8 Y
  23.                           HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE);       //重新打开DMA接收                               
    8 l- ?  t4 V# R9 S4 x
  24.         }  G" h6 z, i# {3 W" H: Q" |  \
  25.   /* USER CODE END 3 */
复制代码
  x- o2 g7 {- G4 |$ N2 f
(2)stm32f1xx_it.c中添加接收中断处理代码如下:
% b: ~) E+ m3 u! [% ~2 H
  1. /**
    2 [# y& L8 N7 H7 R3 ?/ Y: v) _9 ^
  2.   * @brief This function handles USART2 global interrupt.. R# ^% Y9 r( x& M, t0 C
  3.   */! x, w6 Q3 r$ b' W; y
  4. void USART2_IRQHandler(void)% K" ?& w/ {' G' \# i9 e" Y/ e
  5. {
    . X2 a% @& S6 I4 a& a, g
  6.   /* USER CODE BEGIN USART2_IRQn 0 */' M2 W; W+ E* M1 L
  7.         uint32_t tmp_flag = 0;& u: Q1 A3 f2 B0 }' x8 c
  8.         uint32_t temp;
    $ n" d5 y4 \9 T6 P) h
  9.         tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位
    6 J! ]& V6 a& e/ n/ D
  10.         if((tmp_flag != RESET))                                //idle标志被置位
    8 ?' \' \- F" @; ^$ Q) @  V
  11.         { - h4 I, H8 c  o
  12.                 __HAL_UART_CLEAR_IDLEFLAG(&huart2);                  //清除标志位6 q/ ~" C2 _5 u
  13.                 HAL_UART_DMAStop(&huart2);     
    ( |5 w' l3 o0 G: T% }* ~
  14.                 temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);     // 获取DMA中未传输的数据个数   
    * x7 t6 j" z) Q
  15.                 rx_len =  BUFFER_SIZE - temp;                                             //总计数减去未传输的数据个数,得到已经接收的数据个数
    ! ?& [3 ], C% u1 F1 v' S# a# T
  16.                 recv_end_flag = 1;                                         // 接受完成标志位置1       
    ' w4 l+ t2 K. {1 n( k, t
  17.          }7 K$ w# `- L( s; {+ g0 P0 }8 v) O
  18.   /* USER CODE END USART2_IRQn 0 */
    / w; d! a7 v/ R( u
  19.   HAL_UART_IRQHandler(&huart2);
    $ X* b' [* K$ O, V7 Z
  20.   /* USER CODE BEGIN USART2_IRQn 1 */
    . K  i, v4 ^6 K+ l8 f

  21. : v, ?& [; u1 T5 a; Z' B  P
  22.   /* USER CODE END USART2_IRQn 1 */. b' i3 v* k: D  f3 {( [) r# h8 J
  23. }
复制代码

) l, L  }* M9 m7 a: ~" W3 m(3)至此,串口DMA收发数据需要添加的代码已经完成。  q- [6 }: @7 A; n9 R6 D/ G

0 ^* |! I0 ?' O 5、设置编程仿真下载模式. s3 f/ U+ q" C( e* s2 E
(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
" L- A* p  ]; [, R/ R+ u' I  p1 `5 f3 H3 Z! f0 J7 f% I9 \8 b
edefb6b9a2a14be3b1221ad6d5c7a8a2.png 5 X4 G2 A% ?! A
5 E# G& B6 s$ l& f1 L, n
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
4 @: j/ g3 b6 M7 h$ D# y, p. V! \' J$ b9 ?  J# ~
f0ed816a3ed14487bf9e857c317fc99b.png
3 K: f: b6 s) t. ^: j' S8 x9 ?$ B

4 v& O* D( p8 L8 C; t(3)点击Download(或者快捷键F8),即可下载程序。
3 f8 @% @8 e6 V! A$ J2 N+ n
! A8 ?' ~7 X2 [6 N6 t" [7 S" j" l
ba221842d5db40808aa129dd83c593d0.png . R! o, M: K4 a* [: e, s: w! e1 }
. t/ R0 M; c  M% |/ ~; C  z3 e; S8 k
(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。& y4 u# D! O6 p8 c: T

7 e- f7 h- r, |  A4 Q% F
9f8aa1a4e8f04041bcf5cb183facd100.png ; {, Z: l8 ~3 E9 u+ t
3 o- E4 _9 H7 i1 x% G/ Q
4、查看串口发送函数打印log效果
- E1 m9 \! f7 E$ Y7 b(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。2 A( u$ Y$ @3 B( @
(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。/ I. P0 [8 P- k$ Z2 n
(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。0 }! C0 V8 I/ w& C0 _) _3 U
- g/ d, C4 W: w
8f65172eef06499987e27edddf5320f2.png
8 Q. U; G! I6 Z8 j
3 k  }" @5 N$ d- N5 l3 P# X————————————————
2 _4 C0 U; X1 @版权声明:智能小屋ZYXC2 b! P) X5 g- h5 T
' A5 w7 |, ]; p% X/ {; E  o

% U! v3 K1 m2 P/ \
收藏 1 评论0 发布时间:2023-1-14 17:49

举报

0个回答

所属标签

相似分享

官网相关资源

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