串口DMA收不定长数据; f- V, ~5 W- }$ d* ]# K. l
主要利用了IDLE空闲中断,然后整体验证采用透传,发送后回传数据。. C* v( }0 |* m7 E
整体流程
9 T& y! P# F# f3 `4 j6 a2 B1cubemx配置+ i& X5 _; l( ] D K
2接收发送数组,标志位定义,
* u1 W$ c U7 K4 _; W- U3中断使能
% }% ?% x i) D6 N# e9 f4中断函数修改
* Q8 k" ?; O- o. q5回调函数修改; v/ a9 A) E- i9 s8 r; o) ~2 G a
7 t ^; f6 ]/ w# ], Y: \
一、cubemx配置2 v" l9 z7 H* w" Q ?
. U, d w/ p" L: z( O! U; r& B
+ Q$ x" L4 b& H' X# }, `+ G$ Y2 w
3 u& Z; \ q+ Q波特率随便设置,我设置的是1M,注意你的上位机和串口助手是否选择一致的参数! x- `7 Q7 j) t8 C
: f9 G4 D( f0 g+ R4 ^
* R* |* j( {! @5 a( s# O* ^7 T, Y
# b/ v9 J1 d8 i7 `) W% aDMA USART1 TX RX 设置,mode都是normal模式就可以: X& p: ^4 l" g6 W) S- Q
8 _' y2 [$ G! Q; i! U _
( T" D% d* r7 @! J; U' G
5 A* {8 q5 J2 u! i
7 C# }) }2 v' C, j; O! V/ d二、程序修改
" ?1 ?% Z- g6 Y$ j5 c5 C1.初始数组定义
8 A- q2 S% D; B! v1 G6 @- uint8_t Rx_Flag = 0; //接收标志位- Y- R( _- @, c1 r6 a' v& W
- uint8_t RecCount = 0; //个数( H' b2 C5 ^" Z
- uint8_t Rx_Buf[256]; //接收缓冲区
- {5 }: S& U$ H( o c - uint8_t Tx_Buf[256];7 C( P4 C4 M3 Y( z6 C/ n
复制代码 : j. m" ]2 t! t1 c9 O8 I
2.中断使能配置' c0 E( s/ } \2 a
- void MX_USART1_UART_Init(void)8 M) `2 k+ x/ L1 E* f) |
- {0 r! p% @- B- I: c" f
- 1 B4 P: d+ d2 ?8 K9 C8 }
- /* USER CODE BEGIN USART1_Init 0 */# j' f, B3 m( k/ @
- ( @: L) P' M; {# A$ [+ r
- /* USER CODE END USART1_Init 0 */5 z V& M/ j3 s2 n
- d5 N5 X: ~ p2 J% m
- /* USER CODE BEGIN USART1_Init 1 */7 L; O7 O, E! R; G! e; B/ z
- % }8 m! U, x0 v0 L- s
- /* USER CODE END USART1_Init 1 */
7 l1 t k7 z' [+ K% c5 T$ p - huart1.Instance = USART1;
1 C, W/ S9 Y$ I. j$ x - huart1.Init.BaudRate = 1000000;% `) R% Z7 R: G: w& Z) S
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
, R! e" H1 L' h6 W y M1 O7 n - huart1.Init.StopBits = UART_STOPBITS_1;
1 M) H! l# D9 p6 y+ x. V - huart1.Init.Parity = UART_PARITY_NONE;
. S* p" k" A1 H* G8 u4 w - huart1.Init.Mode = UART_MODE_TX_RX;
* S9 A. C }/ ^ - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
# x* ~. _3 L) l8 R5 E4 r - huart1.Init.OverSampling = UART_OVERSAMPLING_16;% S8 ^8 l& o: b5 V
- huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;( b; \: ]7 H; }: a0 Z: V( b
- huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
1 G9 o6 h; U ^; A& C6 D& B - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
3 V N& R6 H1 W( F. V& c1 { - if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
' e. _, x2 f2 i: X K8 M - {
8 D" Y) l4 q( q9 i1 f - Error_Handler();4 O4 B' _0 {3 G2 S
- }
4 T8 D, f' }# b! \$ x* E - if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)7 R; H0 z% i2 H. [3 r- P- y+ L
- {
) b0 |4 i$ y+ {. Q( V0 J2 U - Error_Handler();4 b: \$ ^) k, R, H% x
- }2 f) ?2 ^" n( r: e
- if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
, J& V) c- D/ z& L5 B - {8 v5 P0 r6 g, c
- Error_Handler();7 U4 X1 a* h$ y. a, w7 A
- }
$ ?" S- E4 R. r9 d- W) G* ^$ p - if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)& N) A+ I4 X9 L( y: T* }4 A
- {: @/ R# f/ X( ^+ G) b' y+ r% o
- Error_Handler();
2 \: v9 ?1 ?' ^/ B ?8 p - }
' Q8 G! c% m4 ?( E6 o - /* USER CODE BEGIN USART1_Init 2 */, [: b2 v! w/ s7 H9 A5 @+ C
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启idle中断: S. a/ \$ P2 A8 D: H
- HAL_UART_Receive_DMA(&huart1, Rx_Buf, 256); //开启dma中断
- P( f. ~2 _& u3 A/ p - /* USER CODE END USART1_Init 2 */
9 ]4 f9 {, [& z+ g - 9 M: Z: L* Z3 `! p& [/ q9 T
- }6 \& d8 P$ W$ [+ n' o+ i, Q
复制代码
9 V/ H3 r* j8 p& O. O3 S# W3.中断函数修改- p# l3 s3 T3 B3 V! t
- */
8 i( j$ Q P$ Y+ H( Y - void USART1_IRQHandler(void)& _% R% S* F+ j; u4 z, F
- {
& L+ `% K- Q! B+ f# b" x( J - /* USER CODE BEGIN USART1_IRQn 0 */
7 d& I" Z- Z4 b4 J. l4 B -
2 `5 p% M& r3 b1 b9 K# R) D! g! V - /* USER CODE END USART1_IRQn 0 */
; s0 U5 N. l) Z* W - HAL_UART_IRQHandler(&huart1);
& e3 r. W" X( I% x6 A* M. F - /* USER CODE BEGIN USART1_IRQn 1 */+ Q0 }# Y1 Q) m Z0 v
- //添加idle中断处理
5 S* `# g/ q# b) B - if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET) //是否发生idle中断( s: B" T8 t4 R7 E. o% m+ `
- {
4 u# ^$ o) w/ t3 ^0 l- F' v - __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除idle中断
$ C/ B7 g# s: c7 s; b( V* L- \0 ` - HAL_UART_IdleCpltCallback(&huart1); //用户编写的中断回调函数
/ ~! V; [9 Y. Z3 _' g* t& x* R - }
5 ^% Y9 r" P. y2 s8 @ }% C! G3 Q - / `3 H, `0 l, [4 k
, _( P: K# L3 b( A- /* USER CODE END USART1_IRQn 1 */# j# z7 q+ l9 J! d: V* U: j; n- i9 ?
- }
. K: X7 y3 b7 T& @9 x
复制代码
0 ^% h D: v b( m! W4.回调函数修改" Y, @! l: i$ A" Y8 G6 I( w
- void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数
4 u6 P6 G, q7 U2 g; O - {
! @* @' {0 {6 y- ]" l( U - Rx_Flag = 1; // 设置接收完成标志
N+ Z/ _& K$ v6 V8 ?7 \1 D9 x { - HAL_UART_DMAStop(huart); // 停止DMA传输( ^' }; i$ k5 z% i" p0 B
-
# [/ y# j& e2 T2 V, ^& t5 `& N* m - //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据1 v2 r0 X+ O$ D) I1 o* f
- RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
- ~' E- s$ {* B1 k$ a. h - % `9 T! f; a l* I/ A
- memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数' `6 f. e2 x; b; ]
- memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区9 `9 S5 L& N' J% [6 _
- HAL_UART_Receive_DMA(&huart1,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输" T. y, I# a0 u, L7 k
-
' Y. ~) z X% p - / k6 X ]$ _) Q
- }
" ^5 J X3 e% _& N0 p N
复制代码
7 V5 I. T; t4 S9 j
5 X) H3 Q- E7 ?4 D2 Y. k; \————————————————. \7 G6 o( B+ S6 m: p9 E. M) r
版权声明:超级馒头神
, c% e) i4 l3 y; r; u/ h2 A& E. ~: N4 h7 i
! v) b1 O! p+ b! ? |