串口DMA收不定长数据$ F. i) Y- y4 B2 q
主要利用了IDLE空闲中断,然后整体验证采用透传,发送后回传数据。. ]% t. N( J! g- O; {& @! \
整体流程' ~5 s/ x- ]0 }) u3 F2 o+ A5 C
1cubemx配置( z d& a& ^4 f) s# ^
2接收发送数组,标志位定义,
4 N5 t' d, A3 y+ O6 V) l3中断使能( o' R6 ~, ^) ?/ } g# O
4中断函数修改- `. `! x. k+ Z* C
5回调函数修改
% _& R8 s: v6 U# L6 h0 T0 b* ]+ R% e F: V
一、cubemx配置
1 D9 L% _$ }5 s% `; R$ U( t' M* p) d/ g! X5 ^/ W; } l6 K# a. ?
! q) f1 z' b3 }8 j% F
6 g0 ]/ ^- [# T6 D( Y) t1 Y波特率随便设置,我设置的是1M,注意你的上位机和串口助手是否选择一致的参数
7 f* H1 ^: g- U! \1 g" Y" s/ F6 A% I8 _8 X& g7 G. v" c+ G6 X
; l" n" p& `7 B' s$ w
: b5 k+ I/ p. j) J, m/ E; p$ j
DMA USART1 TX RX 设置,mode都是normal模式就可以% @. P% y N8 |# u4 ?+ u. m4 s9 U
) K# j9 A( M" t1 R; g
0 j$ t' A* M" i3 o
( p; a, s; l6 [, |6 u! _" e9 l
) N4 W. B& a$ R5 v1 K" {# O二、程序修改7 f, [' L( N; r/ ^8 T
1.初始数组定义/ @$ J5 p: t% N; F1 ]) G1 H) P
- uint8_t Rx_Flag = 0; //接收标志位
# ]! g( v5 a- b2 M7 J) x - uint8_t RecCount = 0; //个数: W! r( h7 t/ d4 Q4 ^4 [4 H; f. d
- uint8_t Rx_Buf[256]; //接收缓冲区
, }( Y( f& C+ t5 x# G4 {6 I- Z - uint8_t Tx_Buf[256];
0 q. |, |& B* y8 B
复制代码
8 ^6 z* p0 m q, n, C, a5 H2.中断使能配置8 a# I! E( t& e! i
- void MX_USART1_UART_Init(void)" O) ?' z* S4 A7 y' `4 \
- {: ]3 B! n! g8 G6 e7 S. c9 F
5 J& S! A# [# @+ R' n- /* USER CODE BEGIN USART1_Init 0 */* K; ]/ W3 G2 d: F/ j% @8 a( X4 I- W
- . |' m4 G, r+ C; Q/ D+ V* ?2 U
- /* USER CODE END USART1_Init 0 */
, R8 u# ?# c1 e: Y6 P1 N - % G% G+ Y& M* K( }3 g; a
- /* USER CODE BEGIN USART1_Init 1 */
1 h {, K8 U [
0 q3 I: j& L/ z+ }- t7 S- /* USER CODE END USART1_Init 1 */) b6 t* O" n! }
- huart1.Instance = USART1;3 {" s+ H* {" q. s! r+ N) m
- huart1.Init.BaudRate = 1000000;
1 n, B3 |: L$ ? k8 { - huart1.Init.WordLength = UART_WORDLENGTH_8B;( i6 M" j, q3 M4 Y- _* z) U
- huart1.Init.StopBits = UART_STOPBITS_1;
5 @: l" ~, L1 v6 ^$ c' y* L4 X - huart1.Init.Parity = UART_PARITY_NONE;* M7 {+ r, P, U# `0 m. E1 z
- huart1.Init.Mode = UART_MODE_TX_RX;
( ~$ F9 T, @( d, ~6 ^ - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
. _4 X" p' I1 E) y6 F g1 { - huart1.Init.OverSampling = UART_OVERSAMPLING_16;
" X$ w" ^4 H: ?+ b - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
8 L. d- M( G% J - huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
) @* s+ b8 u6 r% r - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
5 f# {, ~' P' w' t- H; [+ r - if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
6 R9 v; b7 v* ^, ?& a/ ? l - {
* B5 T% b) T2 a# x+ V% g3 g6 u - Error_Handler();: }% n( }3 ?% \! ~# Y( D; l2 m8 l8 f- X
- }3 O& D& l: d5 L- f1 |, s5 N3 ]
- if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)5 L, ]9 U' }1 t. V
- {
0 a4 R5 w6 i8 C - Error_Handler();' I+ |# C6 `3 F# g8 ] d$ C
- }! u6 o1 ~; Q% Z& r: K
- if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)& g: Y/ w0 O, |. b0 @
- {
" Y& r( T, j9 F+ h8 W$ v. b4 Q - Error_Handler();
8 m+ q' G v2 C3 V0 V2 u - }
7 U- d8 {% X- r2 q: V- s) S# V - if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
d# t t9 E9 O1 G1 Y& e/ P - {: K# S" C4 C8 b ]0 F& O
- Error_Handler();
k( @% M% v, r P k - }
% H5 P4 }' t+ I e+ ^- B8 n - /* USER CODE BEGIN USART1_Init 2 */( M1 X8 \- G* X% g( R
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启idle中断3 W. k! r% }* ]( w; q7 k( ~1 q8 B4 s6 {
- HAL_UART_Receive_DMA(&huart1, Rx_Buf, 256); //开启dma中断" W. ?% H- }& f& w7 L6 e; j
- /* USER CODE END USART1_Init 2 */( O0 D% w$ m, [) V- p. K
! l% G6 k) m/ z7 a2 b: O- a% _- }* `2 v2 a8 q' o* P
复制代码 0 H U @% C; O) P# b* z
3.中断函数修改9 ]* \2 s' a. d2 F+ v
- */
6 ~ F# _) c3 t% {+ @' t- a# b - void USART1_IRQHandler(void)
+ w( K- w4 K3 x% Q6 e( v m - {
* C* P0 ~) L6 H9 J7 ~: D - /* USER CODE BEGIN USART1_IRQn 0 */5 d: e2 D2 g5 s( F# M- A( |
-
D" F% R6 f3 J3 H% N' r2 i& `' I+ z' i - /* USER CODE END USART1_IRQn 0 */6 j! y. y1 `; a5 ?/ m4 L# @
- HAL_UART_IRQHandler(&huart1);
; g% O) d" w, w - /* USER CODE BEGIN USART1_IRQn 1 */
- c9 b7 B3 g# S3 D A" C( n" |& c - //添加idle中断处理+ F2 C0 V& j2 W
- if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET) //是否发生idle中断2 o6 B; {2 f2 j7 b
- {
/ }6 z# {; w( L! G - __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除idle中断+ ?4 X$ [4 @; g3 T5 B2 c
- HAL_UART_IdleCpltCallback(&huart1); //用户编写的中断回调函数! C2 _/ H* ?4 }% a+ d J
- }
. Y6 D5 Q6 a: j: o
# V0 M h& D! L1 U' n% N
, s4 O: p# o- z- /* USER CODE END USART1_IRQn 1 *// c) r% b7 Y6 k1 o' ^( a N7 x9 z
- }; S. ]1 d$ i% [5 m/ D: W2 h# B
复制代码 & D Q2 s/ N5 Z- L
4.回调函数修改
/ j8 s% ^/ j. I$ O& W- void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数
5 k; \; `. A* a* n' ]1 \ W - {* H. Y2 ?; i. d7 @" `
- Rx_Flag = 1; // 设置接收完成标志
: | q' v0 u @& {# ]( J - HAL_UART_DMAStop(huart); // 停止DMA传输
8 C7 C( z( ~( l) E8 _ - 1 ?, V F8 b; ~7 m0 ]: P$ A
- //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
- X) L5 U. N$ F4 T1 m - RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); ( e: e; n M1 ^( M* S5 l$ T
-
# O* m* W4 n S& Y" R7 C/ G - memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数
+ a4 q( y7 u1 y4 w% L! Y - memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区
+ m( H5 H I# _& [/ X( J" b" }+ `3 l% o - HAL_UART_Receive_DMA(&huart1,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输
/ w/ s3 W/ i$ N -
$ J5 p6 r6 h# E9 s, K - ! N! L3 e' I, g- N2 ^# F
- }! j- o3 d6 u; C
复制代码
/ F. `( H3 ?& x4 }( V
; T+ Y8 h4 V4 u$ `————————————————
8 G8 K3 H9 X6 I3 E! C$ @) G8 E' Z版权声明:超级馒头神# N/ Q# @! u/ t
6 _' Y) K# ?+ @9 x
: X2 ?# A; z# r- d |