找回密码
 注册
关于网站域名变更的通知
查看: 274|回复: 5
打印 上一主题 下一主题

HAL库的STM32F767的DMA通过IDLE中断接收数据但不能访问

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-12-27 10:42 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
问题描述;  开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。' C. X+ }* z4 ~) r0 ^0 F

, v3 v! c  F( r9 B原代码如下:% J% O" T0 R6 G  }7 j7 G" {/ m

& L$ m/ X" A. v                if(rx_end == 1){  o/ G5 f, R+ ?+ D2 n
                        rx_end = 0;$ V+ ?9 l6 ?* ~$ W& B4 k
                        ' ^) t  @5 |+ `3 q$ v$ z
                        HAL_UART_DMAStop(&UART1_Handler);
% r- E' V, c* a5 c/ x& w. |6 o2 X
                        LCD_ShowString(300, 400, 200, 16, 16, "success!");+ Y8 V2 ~4 ~, F) f* J# y7 D( h$ ]4 _
                        LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);            //这条不能执行,执行就不能再接收数据  
6 Z) T5 d6 o+ W: |' \% I# D( _4 M                                                                                                                     //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常
6 C/ z) B/ w3 l2 I5 w9 q" c                        0 l; M( _" X, R! r
                        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);
' d. ^. q" h  v: G                }          D) K. o& K- ^0 P# K# U

& T$ {$ i1 r5 A. A
  J- {  @* S6 u7 b) s配置原代码如下:
  I$ ]7 m, r. O& j$ M" }3 R. t; k# F3 g) t. d$ s
{
8 h, W# _2 b. \- r        __HAL_RCC_DMA2_CLK_ENABLE();                        //DMA2ê±Öóê1Äü        
* Z, _7 U# J) i+ [4 D/ j$ z        __HAL_RCC_GPIOA_CLK_ENABLE();                        //ê1ÄüGPIOAê±Öó. W- x3 R8 P  z3 c9 p( ^7 |
        __HAL_RCC_USART1_CLK_ENABLE();                        //ê1ÄüUSART1ê±Öó; Z  m- N9 a0 Z
, T  v# Q) y9 U$ d. l, M
        GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
1 Q. o- G# d2 e' i        GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //¸′óÃíÆíìêä3ö" p- K' k+ t- Y
        GPIO_Initure.Pull=GPIO_PULLUP;                        //éÏà-! y9 K1 |# f: @0 @6 O! \
        GPIO_Initure.Speed=GPIO_SPEED_FAST;                //¸ßËù. H/ Z9 o: }# S" l7 w% d. H
        GPIO_Initure.Alternate=GPIO_AF7_USART1;        //¸′óÃÎaUSART10 l5 Z- d5 r/ b! H& r
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA90 Y" B' O5 _5 z/ i& r
% i5 r1 n! T+ a" C) r+ b/ R4 U" y
        GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10
) q% _3 e: d: `- X8 b        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA10& f# q& j/ M0 V/ w
        , p, r' ], u  _2 g* b  g9 ^* V( i
        UART1_Handler.Instance=USART1;                                            //USART1
; _$ o& e" _5 O- n" P6 P        UART1_Handler.Init.BaudRate=9600;                                    //2¨ìØÂê3 M: C; }, U4 f! }" a% i
        UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //×Ö3¤Îa8λêy¾Y¸ñê½
: N6 z9 |; `" d) Z/ ~        UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //ò»¸öí£Ö1λ
9 |5 N/ ~2 ?8 X  P; _        UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //ÎTÆæÅ¼D£Ñéλ6 i& [) S& k% y% D6 j: V
        UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //ÎTó2¼tá÷¿Ø
. P# ^- J  c8 j. O0 A        UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //êÕ·¢Ä£ê½$ D! C+ `* T8 t5 x8 x5 E
        HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()»áê1ÄüUART1! m- j# k9 o' V" @4 l5 ]/ `

' P! N8 x4 G* m$ b8 i% B" _  H4 b+ H    //Tx DMAÅäÖÃ
) F2 ^+ K. ~' |! D) Q        UART1TxDMA_Handler.Instance = DMA2_Stream7;                           //êy¾Yá÷Ñ¡Ôñ: F& N  F' V1 ?4 }) z
        UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ, @3 C1 h9 D+ ~) M/ i
        UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;             //′æ′¢Æ÷μ½íaéè  |2 `# b5 J% M* e3 ]/ B' D
        UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½2 a! l9 c! s3 @" D# N
        UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½
* F! r0 K7 Q4 ~* J        UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ$ D+ p) A9 L/ v% C
        UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ* \5 m9 I. ?: }5 [" _+ K+ e
        UART1TxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
9 [" n, k) R6 T) `5 ?6 R4 s        UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
& X; W% l% k) L1 L" a( P9 x+ F        UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;                K: {. k& r+ D, l' b' ^% `
        UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      " j) }2 M5 d. n9 C* D% _
        UART1TxDMA_Handler.Init.Memburst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
8 u* q' o  [. \8 |, E        UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä
: H& H3 g1 L% E" C$ [- M: I
/ x" M* T$ e& {% \# W8 L//    HAL_DMA_DeInit(&UART1TxDMA_Handler);   
, _& J4 m- W: L" b+ T        HAL_DMA_Init(&UART1TxDMA_Handler);5 S/ h, ?% g7 B" z8 W% X  w
        __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);  X: ]* F: z. s/ G0 k) w

3 c5 c# M# e' D# F    //Rx DMAÅäÖÃ/ H1 v) h, C) ?8 d% {
        UART1RxDMA_Handler.Instance = DMA2_Stream2;                           //êy¾Yá÷Ñ¡Ôñ
' C; R2 _/ g, k7 y# I; T        UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
$ L6 D* h. m. \3 c$ Z( L# a( s. u/ d        UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;             //′æ′¢Æ÷μ½íaéè
2 b+ \' g+ i1 I  B! ]) r, ^' x2 l        UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½! G! X3 O2 a  g) m
        UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½0 N+ {, a( ?3 W4 R4 g$ k/ c
        UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ3 t% `3 i5 c) `( M2 i1 N, _
        UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
1 H6 E4 y1 j, |/ B( q. o        UART1RxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
: n: _( Q! [, l8 o) V9 Z        UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
) W) A* y7 G" z" U        UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              
8 K  Z  t/ ~0 m. ^" x        UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      
$ \- @; d4 v7 a5 {% z0 O( i7 y        UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
, R/ o, \4 Q: X$ p. ~1 r        UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä
6 S. w, a1 T7 _
3 j) ?, s0 D. i# A# |        HAL_DMA_Init(&UART1RxDMA_Handler);/ N- t  \/ |- h7 [( `1 A
        __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);
# [2 P. ?# a* V& d/ L, N5 p# @: M1 Y
        __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
4 J; t, V* ?; d: K, q1 ^" P7 m, x) e        __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);                //¿aÆô½óêÕÖD¶Ï9 n% d  Y& R; G# d6 ?) A7 f+ E4 F
        HAL_NVIC_EnableIRQ(USART1_IRQn);                                                        //ê1ÄüUSART1ÖD¶Ïí¨μà: |# v! W$ G( o
        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                                        //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3( G" S7 r) H; S
8 }* s( h' ^9 B- [& w' k
        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);              //开启了一次
7 H  L9 K/ p5 I! y: a$ X* i' h& m% ]& N, M
}
  Q' d& J: P/ x2 A' p3 ~% ]$ h" R: h% ]. S9 v) j) s- {+ y
接收中断函数) y7 ]. }7 ?9 ^, b3 ?
! _! |; A- N; x
void USART1_IRQHandler(void)                        
8 q! d1 k8 s7 L  G1 Q{( T5 ^9 c' w: ~: R+ T# O
unsigned short y;4 K. Q# j5 M- f2 z( D
        & y* N$ Q. s) Q( |% x, F$ d
        if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET))+ G/ h+ S( l. P3 k5 S" D! V
        {* I. g( e$ |* \
                y = 400;
: C: Z/ `: P) h; c/ N                LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");+ j* u& h0 ^( n5 Q% q
                LCD_ShowNum(180, y, RX_ADDR, 3, 16);) u" F9 }* I4 s' y  n, t+ \
               
% {' h! V# c* K% m- K% I                rx_end = 1;6 M' I# V. W+ C/ l  q
               6 l7 V$ N- _+ r; x  j# R
                if(RX_ADDR < 900){3 X( v9 H3 p8 n' S
                        RX_ADDR++;
4 e; h3 S5 [& n" v! K: K                }
  V4 G/ d6 B1 F3 o3 d) Z) d/ `                else{
2 P  n& s- y/ `: B, F                        RX_ADDR = 0;. h4 O. F* e" _4 h) j7 y$ L; m7 y
                }2 K5 m, x- ~' K+ J, j
        }/ r. `) B5 @( e  K. b/ [. I

0 `) `+ O% E1 X2 h+ w        HAL_UART_IRQHandler(&UART1_Handler);        , J3 W& h3 b* E
}5 f$ d( {; W3 a% S

该用户从未签到

6#
发表于 2021-12-27 11:09 | 只看该作者
DMA接收数据的数量能够正确更新吗?

该用户从未签到

5#
发表于 2021-12-27 11:08 | 只看该作者
/* USART6 串口空闲中断函数 */
, T  x  J+ E5 J7 nvoid HeaterComm_Callback(void)
1 Q3 t* M' G( \( G6 y{
; ^8 q( r  d4 ^  G  uint32_t TmpFlag = 0;( \+ I  O2 Q( L; r
  uint32_t TmpLength;
- j& c* B/ \) x7 h; I: I6 n; g  5 D" B. B$ j2 }3 k% `2 [* p
  TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);      
1 s  [( e0 Q" o( S; Z* e3 ~  if((TmpFlag != RESET))- Y- N4 r4 u7 P) r
  {8 ?' j$ Q  m4 H% l- M- }# w
    __HAL_UART_CLEAR_IDLEFLAG(&huart6);  
0 i2 f( s( E& Z3 }    //HAL_UART_AbortReceive_IT(&huart6);                             
  g3 v! s* k6 F0 h$ l    HAL_UART_DMAStop(&huart6);      
' E& D. \3 d/ D: J1 C, F) G+ k    TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);         2 ]0 z" Z+ E$ L/ v% S
    //TmpLength = hdma_usart6_rx.Instance->NDTR;# o: p1 {7 j9 [* T
    HeaterComm.DataLength = 32 - TmpLength;
6 [3 q& J  q6 T& P4 ?: [; S    osSignalSet (HeaterComm_TaskHandle, 1);                     //HeaterComm.ReceiveFlag = 1;8 e% J7 |9 f3 f. ^
  }
: p6 b" F: w/ ?3 E, J% C, ~}

该用户从未签到

4#
发表于 2021-12-27 11:08 | 只看该作者
实际上是访问数据访问的Cache,DMA更新的是缓冲区,导致存储器内容不一致,读出数据给人感觉就是没收到数据一样

该用户从未签到

3#
发表于 2021-12-27 11:07 | 只看该作者
有可能是Cache的问题

该用户从未签到

2#
发表于 2021-12-27 11:07 | 只看该作者
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。2 y1 b1 A5 n' ^& D* w7 I5 Y! `' w

5 |2 D& T. C0 _+ f__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);! @# g0 ^) m0 i: n
( m: ^$ K, _& t9 V! I
y= UART1_Handler.Instance->SR;
) P% c4 ?0 v# V" _; Qy= UART1_Handler.Instance->DR;
7 n$ @9 x, d6 E3 {# _+ \& A9 z. I2 f0 o
HAL_UART_DMAStop(&UART1_Handler);
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-23 23:28 , Processed in 0.171875 second(s), 25 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表