串口DMA收不定长数据
7 T' O$ I1 V9 U主要利用了IDLE空闲中断,然后整体验证采用透传,发送后回传数据。+ x" p9 [, W% u# [
整体流程
: Q5 {: u- x/ O" t' f1cubemx配置
- K) n( g6 x0 Y3 `7 h2接收发送数组,标志位定义,
/ U8 y/ m, C; r3 u! q" d3中断使能2 J+ h# M' ~7 i6 R6 W+ }- T7 c! M [
4中断函数修改
4 a7 g& ]" m5 K) w4 s+ C h7 r) Y6 A% O5回调函数修改
% m1 I d' Q, q" K) Y1 h+ O- H/ x* V) k: ?1 w9 B/ g
一、cubemx配置2 ?* G" Y- }5 I( ]
; {0 k' Z! o4 s4 |3 r1 H" B
, H0 b% O7 p' A
4 z0 d' n* C% X! g+ X0 @& ^波特率随便设置,我设置的是1M,注意你的上位机和串口助手是否选择一致的参数
6 K2 [2 E' n. a+ y/ }& \$ s4 B" ^" E( d. e& M! g# Y/ P
! D& o3 l/ g4 l; n
& \1 E* I* r0 @8 o m! g
DMA USART1 TX RX 设置,mode都是normal模式就可以 R- M9 z! h1 h! V. e9 X
1 K5 M: P& _- f9 q/ D2 [
7 D8 q5 P3 v' [3 T7 `
4 a7 P* ~( j' ~( }0 F8 Q( ?* U3 a. ?) W
二、程序修改
4 x* a0 w7 j5 { j/ t. ^1.初始数组定义: @- e- d8 y5 D) T1 w) q
- uint8_t Rx_Flag = 0; //接收标志位
) C& P2 i6 q% S! M8 m; }5 z - uint8_t RecCount = 0; //个数
5 {" Q' A. `) U, _2 [ - uint8_t Rx_Buf[256]; //接收缓冲区
( z# E' [ l* I( l - uint8_t Tx_Buf[256];, ?* O9 M6 a# w* |5 i
复制代码 - f3 o* ?$ u! v& j
2.中断使能配置" n! Y7 |4 }8 ~4 c
- void MX_USART1_UART_Init(void)
' D# Y# z5 X- q: z% n - {
- ]& D; ^* F8 l; K; s% }; \0 I - + H, r; W/ E/ e6 V# c# k+ _
- /* USER CODE BEGIN USART1_Init 0 */$ `( R* i' }9 x% X) z
- , \, A. V7 J {2 I
- /* USER CODE END USART1_Init 0 */4 K3 V$ @$ w3 l1 h
3 G* J& A3 j$ E- /* USER CODE BEGIN USART1_Init 1 */
! D- q6 h' h7 U9 u
6 X* j9 l% ` G7 i& p- /* USER CODE END USART1_Init 1 */
+ v1 c6 S! ^1 t+ t - huart1.Instance = USART1;2 \' q) @. j3 ?
- huart1.Init.BaudRate = 1000000;) E: V" p& o9 z' u1 U4 A8 H; Q+ \& i
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
3 Y0 k4 }3 A; k3 z3 ^" b - huart1.Init.StopBits = UART_STOPBITS_1;9 H; O& Z8 o w }
- huart1.Init.Parity = UART_PARITY_NONE;# i# m w0 ?$ t0 d
- huart1.Init.Mode = UART_MODE_TX_RX;" v% Q( q4 T. c( `: i
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;+ C' R2 c. W1 C7 ?4 o; b
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
- d2 r0 ], D5 x; W0 K0 t7 q - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;' z1 F& D2 K+ I& f, Q- \& B
- huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
( {: w) K, p0 n# t h - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;' @5 r( @( c$ t( ~! v# U- m
- if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
8 d5 r; t0 ?2 X( S ^9 g b4 a - {
9 n" ?" U3 ]& ` - Error_Handler();: U: a& [% X' a% A9 J5 E8 R2 W R e
- }
5 H0 Z4 i- m* q5 E$ e7 z4 r - if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)( G/ x5 g8 r1 n* f: |9 A
- {) `- w" d/ Z* ^. p3 r$ t' Q
- Error_Handler();' z, c9 [- p; w8 _& ?
- }" r2 h( ?% A f7 q
- if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
) {0 k$ m+ i1 T - {
1 q. b* v. Y8 V- }; D - Error_Handler();- C5 K( D2 V! B$ L
- }' p! Q; s" ^! @# p$ P$ B
- if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)/ |3 n; p7 T9 B! K6 ]
- {2 l* X q; C8 ?
- Error_Handler();
. T! Y' a. _: [) L: [) O( K - }
) ?: S. {1 C5 _/ J( s s - /* USER CODE BEGIN USART1_Init 2 */
2 h0 w0 q* |' @4 Y - __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启idle中断
3 |. W! k* c/ h - HAL_UART_Receive_DMA(&huart1, Rx_Buf, 256); //开启dma中断6 [8 j1 O+ \" U- \# Y2 t! U
- /* USER CODE END USART1_Init 2 */2 v# E- c( \2 n2 H: p3 O5 y
- + N4 t1 |# x9 u G x: R& H# s
- }
* U1 T# s* t8 J0 ?0 U* ?0 g
复制代码 . a' F# N# w4 L9 g
3.中断函数修改6 I9 Y! x6 H9 g2 o: [0 ~2 `" S
- */2 D0 q) h5 f( D: G
- void USART1_IRQHandler(void)
/ ~$ L, Y+ f: a3 w1 q3 l1 | - {$ z1 A6 q0 c: H1 j2 E* W" F
- /* USER CODE BEGIN USART1_IRQn 0 */
0 q& \9 A/ [8 ^: i1 Y- ~ -
! F( Y7 H3 m1 A/ `. z" W0 \ - /* USER CODE END USART1_IRQn 0 */3 @8 k8 i& Y4 L- }8 n
- HAL_UART_IRQHandler(&huart1);: g% \4 y, x4 _) t
- /* USER CODE BEGIN USART1_IRQn 1 */, m" R7 u% U5 }5 D
- //添加idle中断处理" K3 O9 f% i% s4 H
- if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET) //是否发生idle中断9 \) A) z+ |4 C( h, F! |8 h5 P
- {
- R+ r8 a" p* E3 a* I& V$ [& Q8 K, B - __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除idle中断7 V' K9 h' b1 t6 E/ N& ?
- HAL_UART_IdleCpltCallback(&huart1); //用户编写的中断回调函数; _) t; c2 [/ _; T. P
- }2 f7 ]( Z; @, b' N' U- m/ r
% f) _9 t* y# [0 W0 y6 b; b" }% H- 3 d. R7 V0 o! K
- /* USER CODE END USART1_IRQn 1 */$ s* f, G5 h$ {' _6 I
- }# |; G8 H( ?3 R
复制代码
4 q# p# Q# }5 T d5 U0 Z4.回调函数修改
8 [* }1 y1 H( B" H0 {- void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数
6 S3 }/ Y0 H5 f7 _+ d' C, ? - {
5 T( N+ T+ {$ ^- E - Rx_Flag = 1; // 设置接收完成标志$ ?9 `$ Y; h! H# `' ?& ]; D* W& ?
- HAL_UART_DMAStop(huart); // 停止DMA传输
% T& {: p) K& o% y$ N+ Y - & E; {% B- ^- N- x
- //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
, e& A" @6 x2 h( Y& R( s1 j - RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); " Z* l3 O. Q( s" Z. {- M
-
. O+ S$ J: E2 d- F0 c - memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数
# y! }3 V j, T4 p% D - memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区' F' T9 w# r0 k0 r$ `" s
- HAL_UART_Receive_DMA(&huart1,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输; a3 B* S2 H! E% F1 j+ c
-
+ `$ r% q! t- G# Y - 9 [/ D. H, A/ _0 T5 d
- }
* ^+ D, i& B. P! p4 b
复制代码 D k# b5 F, r. V8 Y
& f n8 n1 G5 r X, x8 f* j$ O————————————————$ _2 P. n- ~3 r1 G) q9 Q0 ^
版权声明:超级馒头神0 a7 M' \9 D8 a* Q/ P2 D! ~
/ q: P* |0 o5 ^
9 B: {' F- N3 Z& O |