EDA365电子论坛网
标题:
HAL库的STM32F767的DMA通过IDLE中断接收数据但不能访问
[打印本页]
作者:
faker12
时间:
2021-12-27 10:42
标题:
HAL库的STM32F767的DMA通过IDLE中断接收数据但不能访问
问题描述; 开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过
仿真
能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。
! D4 K& |- E/ j+ d) N* K0 R
( Z- [6 C3 @; y6 w
原代码如下:
+ n1 @/ o* v' _& \6 c: d3 O% j) M
. h: V$ x( B! Y/ ^/ W5 h
if(rx_end == 1){
* F& n, W; k% C4 [
rx_end = 0;
: b7 E* V {. e% K
) y" h: M( Q9 X( \; G% U$ j
HAL_UART_DMAStop(&UART1_Handler);
# f3 }" L2 N6 x7 o: o0 x4 ?, m
( J/ K: E9 i$ e/ u, I% r8 C' B4 k
LCD_ShowString(300, 400, 200, 16, 16, "success!");
' m# T( Z3 J3 p9 g
LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);
//这条不能执行,执行就不能再接收数据
8 O, X$ v ?) W' w$ H0 F8 o6 `' W
//屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常
5 ]$ U/ e% \$ T
) ]4 w- g! N6 s1 R! s( D* x1 n
HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);
2 R0 `, V0 D* o8 y, i
}
/ }" M' e9 Z& s6 l
$ s" b8 g& C* A. e# ~; s
% ?% E1 M9 V. S
配置原代码如下:
* B E w8 |3 I* R
& o5 l* G( Q, q: G- [, o2 d- u
{
, c5 d) m( m2 P* g
__HAL_RCC_DMA2_CLK_ENABLE(); //DMA2ê±Öóê1Äü
7 T: h0 S6 N0 Y6 b; |
__HAL_RCC_GPIOA_CLK_ENABLE(); //ê1ÄüGPIOAê±Öó
8 H; k2 I) q1 |9 n! H8 ?
__HAL_RCC_USART1_CLK_ENABLE(); //ê1ÄüUSART1ê±Öó
: u* Y8 ]) |' n
& R1 e& `& l3 q! l7 t, @
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
3 }7 o; a. [$ a
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //¸′óÃíÆíìêä3ö
8 M1 @) _) u6 `* ]8 t. B
GPIO_Initure.Pull=GPIO_PULLUP; //éÏà-
# }2 r! }7 I9 A2 t
GPIO_Initure.Speed=GPIO_SPEED_FAST; //¸ßËù
m; s/ P' ^6 b
GPIO_Initure.Alternate=GPIO_AF7_USART1; //¸′óÃÎaUSART1
- X3 i9 B' K# l) i; R$ f. z; h& ^3 ^
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //3õê¼»ˉPA9
F# A& M, e3 o& ?# v
1 e+ A' p5 Q5 Q
GPIO_Initure.Pin=GPIO_PIN_10; //PA10
6 ~. y& z9 m% X9 e3 Y
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //3õê¼»ˉPA10
1 _ y9 k' j# @; m8 {
4 z% K9 [6 `8 E3 ~' @/ b. s
UART1_Handler.Instance=USART1; //USART1
$ f: T( u3 h& N& w; @# a; f
UART1_Handler.Init.BaudRate=9600; //2¨ìØÂê
+ E" x( o0 S' L# Z( S, q
UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; //×Ö3¤Îa8λêy¾Y¸ñê½
' X3 h, ?* u& |5 ^2 Z3 h
UART1_Handler.Init.StopBits=UART_STOPBITS_1; //ò»¸öí£Ö1λ
8 f' m0 a$ H1 O
UART1_Handler.Init.Parity=UART_PARITY_NONE; //ÎTÆæÅ¼D£Ñéλ
1 A0 Y! m( y- M
UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //ÎTó2¼tá÷¿Ø
5 x. ^& T1 H% l+ I
UART1_Handler.Init.Mode=UART_MODE_TX_RX; //êÕ·¢Ä£ê½
7 F; f+ b& |. Z/ \% M S
HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()»áê1ÄüUART1
+ m8 B: D2 _; _0 |
+ Z" y+ _7 {1 q5 L9 n! {
//Tx DMAÅäÖÃ
: ~$ k/ B {. w' h6 E' u
UART1TxDMA_Handler.Instance = DMA2_Stream7; //êy¾Yá÷Ñ¡Ôñ
* r. ?3 k' q4 [. |) E
UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4; //í¨μàÑ¡Ôñ
9 B' n$ N' l% O( {+ M2 B
UART1TxDMA_Handler.Init.Direc
ti
on = DMA_MEMORY_TO_PERIPH; //′æ′¢Æ÷μ½íaéè
6 x+ W! L- g+ z7 X
UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; //íaéè·ÇÔöá¿Ä£ê½
3 j7 E8 O6 r" i% i& @5 g) p# Q
UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; //′æ′¢Æ÷Ôöá¿Ä£ê½
# W% S+ |# T8 V" i# N5 L3 R5 z
UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //íaéèêy¾Y3¤¶è:8λ
# l- T/ d7 J3 |2 B2 L& Z
UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //′æ′¢Æ÷êy¾Y3¤¶è:8λ
1 ^0 a* b& p0 h- S
UART1TxDMA_Handler.Init.Mode = DMA_NORMAL; //íaéèá÷¿ØÄ£ê½
! C, w1 u7 K/ D, S$ a1 k4 f/ d
UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM; //ÖDμèóÅÏè¼¶
3 }) F2 z* _+ r' |0 ?. [9 H2 ]- b3 Q
UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
# f7 ?" m. d+ `( `# G
UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
) a/ w$ g8 ^9 _8 T
UART1TxDMA_Handler.Init.Mem
burst
= DMA_MBURST_SINGLE; //′æ′¢Æ÷í»·¢μ¥′Î′«êä
; c3 I8 }% M9 A/ r* F/ S, U* c, H
UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE; //íaéèí»·¢μ¥′Î′«êä
8 ~5 s1 c- ~/ e0 H8 y& j" i! S
7 D5 c7 U, P, c% o9 w l7 W
// HAL_DMA_DeInit(&UART1TxDMA_Handler);
. }: r; e$ H0 y9 m' }. _
HAL_DMA_Init(&UART1TxDMA_Handler);
. s: x, R: C6 ^; i0 `
__HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);
* p. \ ~. c' n6 p6 |
; R7 X2 W( `$ S/ g9 h/ z- {" i5 B$ I
//Rx DMAÅäÖÃ
: Z* B6 Q6 c' g! C' x Z/ I! I
UART1RxDMA_Handler.Instance = DMA2_Stream2; //êy¾Yá÷Ñ¡Ôñ
' w e- E& b! ]8 q* ]+ T
UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4; //í¨μàÑ¡Ôñ
9 O# M I! z; f, B8 Q, F( }
UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY; //′æ′¢Æ÷μ½íaéè
# L$ r J5 w0 o
UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; //íaéè·ÇÔöá¿Ä£ê½
' I: w! r9 G/ m8 l& R
UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; //′æ′¢Æ÷Ôöá¿Ä£ê½
' v" d; T! w$ ^9 z2 i, U
UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //íaéèêy¾Y3¤¶è:8λ
8 {2 s* T1 ?# {; ?
UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //′æ′¢Æ÷êy¾Y3¤¶è:8λ
: s: w- p& @0 H! o8 x# C4 b
UART1RxDMA_Handler.Init.Mode = DMA_NORMAL; //íaéèá÷¿ØÄ£ê½
/ Q0 W) Z. s4 k, s7 j/ h* k* t1 G* [
UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM; //ÖDμèóÅÏè¼¶
% V& B3 W& c- q. F2 r
UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
, `. c% V6 p1 i0 |* Q
UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
3 G& x9 l5 J5 ]0 z" f; ^. \
UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE; //′æ′¢Æ÷í»·¢μ¥′Î′«êä
4 \: v9 L7 a) N/ A6 m G
UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE; //íaéèí»·¢μ¥′Î′«êä
; \& F0 U: Z" d3 G5 g; d
" f6 V5 c g/ u8 [; Z( d8 y/ u
HAL_DMA_Init(&UART1RxDMA_Handler);
u C1 y3 X. E+ R6 Q# t2 g
__HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);
0 C2 P! \4 y+ P. B! Q
; t1 ~0 E2 ~) w a0 S
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
7 I$ b* I1 S% T# @4 m: Y* y8 n3 |2 H1 a
__HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE); //¿aÆô½óêÕÖD¶Ï
* N% \' O4 E: t; d" ]
HAL_NVIC_EnableIRQ(USART1_IRQn); //ê1ÄüUSART1ÖD¶Ïí¨μà
9 k: X# [3 _: B3 r" H+ J
HAL_NVIC_SetPriority(USART1_IRQn, 3, 3); //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3
, c7 ?: I6 j7 X! P
- ]( [4 D9 S8 B- l: v, q3 S( h4 v( h
HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);
//开启了一次
" X. b, k: a1 F! i9 P7 B+ n8 R. s
& u% I P8 }- U6 ?; q8 L
}
$ L( O" R$ Y: S) t
$ l( R- Z: E. w1 Y6 a4 a
接收中断函数
4 M* _3 j! y% V& d) m
7 ]5 X& E$ s8 G' F
void USART1_IRQHandler(void)
/ m$ i1 H0 i' ]1 z
{
" W: Z/ z i! b4 n# C& V W" [1 K
unsigned short y;
- \' k( ]2 n) C" c; t5 o t& r
( s3 z4 V( ~4 r
if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET))
! m9 W3 A/ O: S4 l# l
{
- b. O1 b( M# d Y5 _7 \
y = 400;
& O8 b, f; E! z; o
LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");
; H0 ^% S N% W
LCD_ShowNum(180, y, RX_ADDR, 3, 16);
+ Y' d, R) S4 [8 y: R: y
! L% J. W5 t0 ?& z- b' w- J3 ?3 K
rx_end = 1;
/ W7 Z( P2 z& o5 s+ L7 L
6 b! Y% B+ @1 Q$ a( Z+ G7 T
if(RX_ADDR < 900){
s# _+ c$ P, t/ B4 Q. e6 g9 [
RX_ADDR++;
' F, U, L8 O( g/ y& v; O9 ?
}
5 d1 d7 i/ \7 N: n
else{
+ w% C4 S8 |4 E4 h! V8 y
RX_ADDR = 0;
* y* a1 w9 o8 Q! C6 }% x7 x
}
1 w2 d3 e& ^4 B
}
5 l, }$ U& a P' J" Q' C! Q' R# D" b# o
& z D$ p$ I* i- d7 A
HAL_UART_IRQHandler(&UART1_Handler);
! h' T8 t4 P7 U9 R( Z
}
/ a/ @$ k: l( B8 b5 K u* r4 c
作者:
unix155
时间:
2021-12-27 11:07
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。
* K$ x* U9 U) ]+ n5 `, O
9 }8 I5 N" S5 e% y: h, P, b
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
+ D% d8 g0 I' ?+ y' o8 H
2 y* K: i) J, X
y= UART1_Handler.Instance->SR;
9 C0 J# |+ [% k) H7 o6 Z5 ~
y= UART1_Handler.Instance->DR;
9 m: s- |5 Z1 M. d
9 [5 o7 b8 s) O9 p* d
HAL_UART_DMAStop(&UART1_Handler);
作者:
jspij1
时间:
2021-12-27 11:07
有可能是Cache的问题
作者:
hunterccc
时间:
2021-12-27 11:08
实际上是访问数据访问的Cache,DMA更新的是缓冲区,导致存储器内容不一致,读出数据给人感觉就是没收到数据一样
作者:
sdsdwwwe22
时间:
2021-12-27 11:08
/* USART6 串口空闲中断函数 */
8 `' t4 X8 H6 ]
void HeaterComm_Callback(void)
N# L- m- Z% M
{
( y& J) i) {% K& k
uint32_t TmpFlag = 0;
$ z8 k8 @- y4 b3 S5 i2 F# @
uint32_t TmpLength;
; z8 s/ N& J5 r3 f6 f& q& l
: \. g) z' J: ?9 B% T
TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);
, i$ w/ C3 m i& \) f7 B
if((TmpFlag != RESET))
5 p/ x S3 s9 ^/ d3 u
{
7 K1 }, \% z0 d2 j k0 p0 f
__HAL_UART_CLEAR_IDLEFLAG(&huart6);
5 w: y; A# u0 X
//HAL_UART_AbortReceive_IT(&huart6);
f, x) G1 o# s3 }% u4 S
HAL_UART_DMAStop(&huart6);
% @0 H) o) U }
TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);
; V" S8 E0 Z8 ? E
//TmpLength = hdma_usart6_rx.Instance->NDTR;
+ R: d2 T5 [2 Y% G9 V6 z
HeaterComm.DataLength = 32 - TmpLength;
& J% p% W/ m7 p/ {. J& ?1 g- b
osSignalSet (HeaterComm_TaskHandle, 1); //HeaterComm.ReceiveFlag = 1;
4 k2 S5 p! u: F- k# M- V9 V
}
/ ?4 e |1 Y' B4 H& o$ a9 n
}
作者:
angern
时间:
2021-12-27 11:09
DMA接收数据的数量能够正确更新吗?
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2