串口DMA收不定长数据0 m5 v. v/ \" _. o! n4 y
主要利用了IDLE空闲中断,然后整体验证采用透传,发送后回传数据。3 d% \7 k4 b! G2 A1 }
整体流程3 e u/ x- b! s# M3 Y" }. _
1cubemx配置
2 e4 j6 V& J/ {! m2接收发送数组,标志位定义,3 X7 U2 T! @% s* h9 N, S3 M5 V# L+ e
3中断使能
: @* @6 u7 J) v2 j; r0 a, T) b, \9 [4中断函数修改, N# w! g) T/ K% f
5回调函数修改8 @; ^0 X) m5 H, v) B
. s: S8 l/ O1 I+ r4 Y: @ X5 K一、cubemx配置/ w* G$ }2 g* }7 n# j
5 Q$ K4 u( _' }6 ]
! F$ G# P# m2 g0 G- G6 z# r* f2 F5 O# ]
波特率随便设置,我设置的是1M,注意你的上位机和串口助手是否选择一致的参数3 }; v3 e& r$ T( ?/ u
1 H) h! H6 x# y
3 K3 c' x- r! G% L8 y7 G
0 X! s3 {4 V" h2 S+ C, R1 uDMA USART1 TX RX 设置,mode都是normal模式就可以6 M0 W8 ^+ @" O" ?& Z5 k! p& M
% D) d7 e. ^7 a2 p
. Y! E8 @2 ]3 N1 K% E9 A8 L
' A+ C1 y+ t! |; O- S/ U8 O" G R$ o' }, K( N/ J7 h
二、程序修改; X" F; X* a3 \! s" p, `
1.初始数组定义
* X' O. v% }. a6 f3 d- uint8_t Rx_Flag = 0; //接收标志位 V( k7 k0 R4 q; ]; f4 x
- uint8_t RecCount = 0; //个数
2 W0 c' U4 D( f. }* x ]/ ? - uint8_t Rx_Buf[256]; //接收缓冲区
q" F$ ?3 p/ _8 X2 C V1 X - uint8_t Tx_Buf[256];
2 |7 r/ V3 h1 N1 d R4 v7 f" Z
复制代码
. p8 x+ ^1 j/ H2 S2.中断使能配置
' u* L1 r& ]' ?7 @/ Y' [0 ~1 S- void MX_USART1_UART_Init(void)
, S$ w3 V) L0 e - {1 v% C& Y4 u2 n7 G1 q# Y
- 5 _3 S+ P$ ?: O1 _+ d v/ E) a
- /* USER CODE BEGIN USART1_Init 0 */
0 [' a" M3 @, ~1 D( m* Q - 6 v" L( x* M4 G( z$ h8 x
- /* USER CODE END USART1_Init 0 */
2 y6 W: p" _& }; @# S
7 K$ `4 ~1 p) B ~* R- /* USER CODE BEGIN USART1_Init 1 */% m" [0 h3 U% u# R
. C1 n5 V- Z/ O. y b4 x4 ^; z- /* USER CODE END USART1_Init 1 */
4 `& L6 Q/ f) y6 l - huart1.Instance = USART1;4 s# M* d: Q2 ^) f% M
- huart1.Init.BaudRate = 1000000;
4 C' u9 \) X E+ E& }/ | - huart1.Init.WordLength = UART_WORDLENGTH_8B;$ Z0 s/ g. k& ^) a6 i) K7 R& k
- huart1.Init.StopBits = UART_STOPBITS_1;+ y4 J) V$ F, R2 D! a. N
- huart1.Init.Parity = UART_PARITY_NONE;+ K+ v7 o) _8 N7 V
- huart1.Init.Mode = UART_MODE_TX_RX;9 R) ?, j$ O2 @6 }3 O7 [ [( a
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;, l2 a8 q$ T1 X! h. d1 y
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
8 ?& i3 ]; u" _. O; s - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
" g8 }: J! W! m% d$ C. B( C% P% X - huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;* e( x4 ]$ ~% a9 B/ Y/ J
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
6 K; i/ N" p1 E6 D( k - if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)2 M- n1 \: O( B: J0 z0 ], J
- {
# B+ A( G V% a4 g6 C3 ~ - Error_Handler();; v5 o4 d5 b( U4 |$ S# Z* f
- }- E8 }: K, ?: a$ }# [+ H1 L
- if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
; i. j. D0 ]! G0 Z& I8 v - {
8 V+ O Q. S. X7 ]" U+ E$ W* h* G - Error_Handler();
1 p0 ~2 h& W$ @( c7 ~$ X+ C; M3 Y8 _ - }: g9 G3 u% Q k3 [1 ?# H
- if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
8 z% Q1 z9 R# G* q. m- O - {9 a/ T( l0 o* ~: }
- Error_Handler();
& Q, B: k5 u2 v. O; e/ A - }5 a- f" G0 I3 T* p$ w/ B( R8 v; ?
- if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK), P; M1 U3 L7 @4 z9 _
- {, i" |0 o! `+ b$ G6 ~! u
- Error_Handler();
; G3 ^2 ~( H8 u - }
; i E ~/ G" ^ - /* USER CODE BEGIN USART1_Init 2 */
4 t [5 M) h7 e$ T2 H - __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启idle中断% |" R$ \% g6 r5 H+ u) L
- HAL_UART_Receive_DMA(&huart1, Rx_Buf, 256); //开启dma中断
9 D7 H4 j# O! a4 G, N7 x# C1 P - /* USER CODE END USART1_Init 2 */0 v. o9 E6 ?5 `5 H7 X
- x( j. J. G& @# r7 K7 W- }7 }( p1 B+ J& `7 B! ~* V+ R
复制代码 ! D% h1 [. t, t. X) Y+ c
3.中断函数修改3 g2 r4 c, b8 ~( B6 W
- */
) @ E+ [: E6 j1 {% K2 \. f - void USART1_IRQHandler(void)8 a- m V" }/ y$ x) ~) E
- {7 V" Q! T$ J2 i( s
- /* USER CODE BEGIN USART1_IRQn 0 */
: m0 k+ r; d" M* v- A -
5 n6 f6 i ]/ s F+ M$ ~$ A - /* USER CODE END USART1_IRQn 0 */
) q* G" R* |' `' v+ T+ v8 ? - HAL_UART_IRQHandler(&huart1);# z! ? o$ ^- E" \% t9 m
- /* USER CODE BEGIN USART1_IRQn 1 */
; |2 Z3 j, C) l: x - //添加idle中断处理# J6 z* G( W1 z( h# ^1 `
- if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET) //是否发生idle中断% |1 f+ q) a1 |* w, u8 ^
- {/ l( v' k$ s/ x8 b% n* c; ~ w
- __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除idle中断5 ~7 P C( ~( h5 i/ g
- HAL_UART_IdleCpltCallback(&huart1); //用户编写的中断回调函数
: N' ^" f. p+ U. N - }
6 h; J' \' e8 V% ?/ n, O3 A* ^( H W5 C - # H( B' A/ }+ h5 x# F x
$ d; G$ m( H" s! M" Y& p- /* USER CODE END USART1_IRQn 1 */
& k9 o% w$ A, A; H - }
6 y& D: e' h* h S0 Y
复制代码
6 p5 W, R; Y+ J4.回调函数修改
7 W5 V3 h! Q) a+ ^- void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart) //空闲中断函数
3 n) O9 ^+ L- z0 N - {
) |" ] `. M% w. H! h# T - Rx_Flag = 1; // 设置接收完成标志: j+ Y, F2 |8 g
- HAL_UART_DMAStop(huart); // 停止DMA传输
s6 T1 Z d6 |9 [! ^8 ]( a" w -
7 f: a# _/ Z' q; D) t& F8 N* @8 J, w - //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
7 u1 Z; {7 z0 i" g x - RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
7 r2 Y5 i; d& D - 7 k! N7 l6 |# h4 D& e/ {* q
- memcpy(Tx_Buf, Rx_Buf, RecCount); //内存复制函数
* S: H6 v& c1 _) K+ ~4 T - memset(Rx_Buf, 0, sizeof(Rx_Buf)); // 清零接收缓存区 ^! @( v9 i x4 Q& Q: E
- HAL_UART_Receive_DMA(&huart1,Rx_Buf, sizeof(Rx_Buf)); //重新开启DMA传输
' x) z' U: T: V3 j2 J0 U( o( K - , c( }; U* H4 z) |
- ! V9 R; H5 N8 I4 `- }; X- p
- }
/ C4 h; v& x' }
复制代码 ! P6 V. {: }6 D% u! \* h2 `& g
1 ?; A g1 T9 ^$ b; [" Z————————————————
+ |6 V. n' U5 f版权声明:超级馒头神
& E5 i) a2 g8 d) J% D1 s
0 O# e2 y+ `( s2 R9 h
/ a3 P) P8 a% G# ] N5 c$ C1 M/ F |