串口DMA收不定长数据
! l' A0 j+ e2 X4 E5 M4 p N9 U主要利用了IDLE空闲中断,然后整体验证采用透传,发送后回传数据。$ i0 X/ c5 w3 J) b
整体流程
5 @2 d7 Q! h& _' f% r( ?' L" T1cubemx配置
5 y1 A' o6 n! l1 t4 a o2接收发送数组,标志位定义,# h8 _' a8 G- x+ N
3中断使能. u1 Z; o7 N- k2 O7 r! c0 \8 t
4中断函数修改" a. K/ w1 ~( ^2 Q2 [( A
5回调函数修改
3 e. V7 x0 B+ n" N& T
+ q$ S) W% M, {0 @% j; M& F一、cubemx配置7 l, ^% _# D/ }& T
`1 L, I0 D( K$ ]- y/ u% |8 f1 [
; Z( q) x6 ^# C" C# \, m- Y5 ?7 m8 Z" L: c2 m
波特率随便设置,我设置的是1M,注意你的上位机和串口助手是否选择一致的参数
1 `# `3 e! c2 H7 E9 A- `, m; @$ ^/ a3 [6 Q* N
& Q/ ~* }& c5 o' f( m
6 ~6 {* R- N8 E: V. WDMA USART1 TX RX 设置,mode都是normal模式就可以
% @" @- o/ ]7 A0 g. R1 y0 G8 t2 T6 W+ O
1 @0 E$ }8 A* }' C( z3 ?
* e8 Y7 g9 x% E, `7 l) \; }+ K* C8 S; c" ^1 Y8 X
二、程序修改
; _9 C' W7 y. @; I' t: n9 n1.初始数组定义 @/ V4 G0 v8 | t* ?) D
- uint8_t Rx_Flag = 0; //接收标志位1 g& r: U. Q* k
- uint8_t RecCount = 0; //个数
8 N" m% u0 h% L5 l: X5 @! O6 W - uint8_t Rx_Buf[256]; //接收缓冲区
+ C# r- Y- r% r% x# {# Z1 S, r( T: n - uint8_t Tx_Buf[256];
. Z( h+ d6 Y* ^1 ]$ h, t
复制代码
* r2 y1 g6 l- \% C% o2.中断使能配置6 z6 [1 z0 f0 @6 F/ e) C1 k
- void MX_USART1_UART_Init(void)
% V% M k& k, c- Q/ u l - {
4 N D# w, C$ L
5 \& A$ I( s0 L+ a- /* USER CODE BEGIN USART1_Init 0 */. i0 V4 z- a' @. ^* ~7 o
1 a" w6 D' f( w( E& ~& Q% n2 ]- /* USER CODE END USART1_Init 0 */4 J! O" y: ?) K |: A* {
- 4 {( i% A4 X$ ]; r" c4 C1 I
- /* USER CODE BEGIN USART1_Init 1 */# l ]1 }+ q( a& b7 W U
2 o5 w7 Z2 J, y3 Z3 Q- /* USER CODE END USART1_Init 1 */- f! v& p# d( k! m4 J0 r* @
- huart1.Instance = USART1;' _; p& A- V/ @% }, }) U) j% E
- huart1.Init.BaudRate = 1000000;
5 G5 q: u6 _3 E5 a9 D; e - huart1.Init.WordLength = UART_WORDLENGTH_8B;( U+ J( L( a5 C: f/ y: x
- huart1.Init.StopBits = UART_STOPBITS_1;
4 C0 Z& S2 r& w; U, k1 v: i - huart1.Init.Parity = UART_PARITY_NONE;9 l+ X6 H( r; Y5 N0 W( N9 O
- huart1.Init.Mode = UART_MODE_TX_RX;/ E* g6 T5 [9 a1 t* P' @
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;2 R) ^6 ~- z+ y3 L
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
2 H3 c# c# `1 k" W - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
0 |8 m# z2 r0 {% x/ o, P' n - huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;! m, E/ j" C! U% L" O' i9 S! P
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
2 }, l! }8 ^1 | - if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
4 _% u/ L5 H. Q7 X+ [ - {* B2 D9 F7 w$ s: s8 l
- Error_Handler();' A/ x& o) I& Q! Z
- }
. x `" K9 ?: `* A$ M - if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)/ q5 f! _; m8 J, W- |
- {& B5 N0 A7 R: ^9 [
- Error_Handler();
- K: W/ W5 Z/ F; T$ \* G - }# u4 K# S. i+ Y) X: Z4 i
- if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
) @% h# l r/ E! F! Q8 P - {9 G0 F# j, x4 ~4 Y$ P+ P
- Error_Handler();2 n/ b3 j& A. X6 d V Q" _# D# ~- Z _# v1 {
- }
2 m# W. T) T: _- p! c - if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)9 B9 v9 G% X0 A
- {
: e$ i9 b1 b9 E! L - Error_Handler();
7 Q( W6 s# O, k8 v: X4 D9 e- @- u - }
6 H2 a/ G, C& @, B: u# X - /* USER CODE BEGIN USART1_Init 2 */" X/ R( Y2 ~ j. W
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启idle中断
3 L+ v+ o9 s6 R, e - HAL_UART_Receive_DMA(&huart1, Rx_Buf, 256); //开启dma中断+ u, m) m5 _* c
- /* USER CODE END USART1_Init 2 */
( h9 O5 _4 A9 l1 i
5 S5 W( S' O/ J U* B7 {- }" h1 E/ @9 A, C, d o U# G
复制代码 : E* Q; o1 O* c# e0 o4 } q
3.中断函数修改* a, m3 h2 ?: f8 D1 C ~' A
- */
, L9 c% k: W$ f) Z$ C& { - void USART1_IRQHandler(void)
0 L; k' \& B& o" ` - {
4 |* A0 X. C* } - /* USER CODE BEGIN USART1_IRQn 0 */
/ r% z* u. g$ z& C- ] - ) u N/ L- Z* D* ?$ W
- /* USER CODE END USART1_IRQn 0 */6 L0 O, k8 d2 q/ D% ^: z% A* ]
- HAL_UART_IRQHandler(&huart1);3 K2 l. ?4 J/ c; ?9 W4 V. I' n
- /* USER CODE BEGIN USART1_IRQn 1 */
, v/ V" ?7 X; ]( y; \ - //添加idle中断处理
' Y3 }6 {- Y" u) V+ x" ` - if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET) //是否发生idle中断
( M# i( C; v5 Y5 Q6 K( ? - {
# k8 }: w( t4 o) B - __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除idle中断
, y/ m8 P' L* K, @0 `5 d - HAL_UART_IdleCpltCallback(&huart1); //用户编写的中断回调函数
1 ~- O/ x f: Q v1 ^ - }
- V9 \ t7 C1 L" \) T - ( w1 L) P" N+ z2 M( S7 y: u
- & I0 E6 e2 Z; l( X
- /* USER CODE END USART1_IRQn 1 */; b; R2 S; i# m# l8 X
- }* X0 [) g: H9 p# \* A3 {) p0 G
复制代码 7 X# G1 c6 C+ g* U" o( e# u' O
4.回调函数修改, L% H/ z. D2 u4 k+ C( U, U! C
- void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数5 B. {6 A& p* V" M' ^
- {
, C1 k5 m" R7 j) C - Rx_Flag = 1; // 设置接收完成标志
+ R m6 r9 O. v; w/ t: y& B - HAL_UART_DMAStop(huart); // 停止DMA传输
. z5 E. K/ e; ^; M6 a. S - 0 {$ A8 t! e! I( i/ y2 [- w: e
- //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
5 \5 ]1 _+ t9 W: s - RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
: E8 O2 I) E9 Q4 d v -
9 J( A2 \ y: {) { L3 @ - memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数
' V) n M5 C0 w8 S; l - memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区
; l$ C& V- D5 I* ~- M - HAL_UART_Receive_DMA(&huart1,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输
: I9 t- x, N2 P8 _! m -
. O$ _% f" w! Y9 d) u8 \+ } -
: e+ ~+ _: r1 Z4 Q - }
! U) `! B3 ]/ z* d
复制代码
1 l e# c. `* v; ^/ n# V4 ]) k/ p) V6 E6 k6 K1 }* `5 \: ?+ @; x8 j4 @
————————————————0 {4 S, v2 N3 _# \* w5 j% X
版权声明:超级馒头神4 b0 P' |2 N3 t( W
7 l! U+ e% E2 X/ z# M) P' f" V! B
|