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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问题描述;  开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。  z# |1 h  R) Y. f6 W
8 l3 o- _$ t3 [2 V7 _8 b# M; Y" G: `
原代码如下:$ T5 l  w1 b; E9 R& ^  N' u
8 ?# t0 {) H6 \, e/ n
                if(rx_end == 1){( z* n: h  p$ r0 S
                        rx_end = 0;+ }4 U' ]& @+ j. a! a) m, E2 w7 b
                        0 O$ E* e; _6 [
                        HAL_UART_DMAStop(&UART1_Handler);
1 s  D( r# _- B% @' e
" y- X2 [1 V, M# v; `7 k! M) R' n                        LCD_ShowString(300, 400, 200, 16, 16, "success!");
9 c4 {( ^6 j7 v0 l* j, N! r                        LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);            //这条不能执行,执行就不能再接收数据  2 h6 w7 s3 S% L' Q" Q7 q( @! k
                                                                                                                     //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常; _! V3 ?8 t: s5 d0 H0 v. ?6 S
                        
, T- V- \' w1 i1 ^8 p                        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);3 J  K) [( `# {2 ]- [5 r% k
                }        
) U) v5 Y  k' D: u* b$ B3 e) I8 N, h( }# g  N

/ o/ Y: F9 y* B( l/ H% Z) j配置原代码如下:
( D# q3 U" T* q( W& T% C9 W# J6 k; k; w
{
7 g1 P; m; w4 a        __HAL_RCC_DMA2_CLK_ENABLE();                        //DMA2ê±Öóê1Äü        1 V# z7 c3 ^2 m
        __HAL_RCC_GPIOA_CLK_ENABLE();                        //ê1ÄüGPIOAê±Öó
3 T! ?* P$ N# Z5 l7 v4 e        __HAL_RCC_USART1_CLK_ENABLE();                        //ê1ÄüUSART1ê±Öó) N: \/ P4 X+ U

8 z; J2 D# t0 C( a/ u8 }# ^        GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
% J, C3 m8 J) B        GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //¸′óÃíÆíìêä3ö0 U. f  P6 P* [1 ]  r" d" F
        GPIO_Initure.Pull=GPIO_PULLUP;                        //éÏà-6 F7 _6 P& N5 ~* q+ C' g
        GPIO_Initure.Speed=GPIO_SPEED_FAST;                //¸ßËù
/ F0 t% a9 f5 Y( l: a        GPIO_Initure.Alternate=GPIO_AF7_USART1;        //¸′óÃÎaUSART13 o& x" a8 S7 b: N0 S. K* q
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA9
, j, ~* ?" o8 R$ |7 c1 y; S( k5 q  j3 N  y- T! F8 a$ ^+ c
        GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10$ \8 m8 M+ y5 A7 o& g/ H
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA10
* [- f6 g' W0 K5 i  K9 }, w        ! L) j3 b; i) h. }! R3 O2 J
        UART1_Handler.Instance=USART1;                                            //USART1# d2 _% U5 n! g
        UART1_Handler.Init.BaudRate=9600;                                    //2¨ìØÂê
. V9 t( a# t  ?  \/ _        UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //×Ö3¤Îa8λêy¾Y¸ñê½! e2 @& t4 d0 X" v5 M
        UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //ò»¸öí£Ö1λ
8 _) P- q/ G- ?1 u        UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //ÎTÆæÅ¼D£Ñéλ
- L& `& l  m( \& S) }. V        UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //ÎTó2¼tá÷¿Ø
, ~" a& V8 f  K8 `        UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //êÕ·¢Ä£ê½  p! x) i+ i- B$ ^/ P0 D) ]
        HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()»áê1ÄüUART1" Z  t" g( V2 ^
3 u4 q: Q, L- m& j. K, Q& ^% _
    //Tx DMAÅäÖÃ: J0 p3 e% L8 s! K& Z" i+ `/ s0 O
        UART1TxDMA_Handler.Instance = DMA2_Stream7;                           //êy¾Yá÷Ñ¡Ôñ
' M8 n; L, L. r        UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
3 {$ e' b3 N; n' ~" w2 z: G        UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;             //′æ′¢Æ÷μ½íaéè7 [, h# d6 J! X5 \; R
        UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½$ q$ p" M. C8 B8 r; r# Q1 d6 d
        UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½+ w/ Y/ o+ i: `7 a& h( P! w
        UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ+ s* h# G: B; v8 ~' ]9 a5 M
        UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ; S( r1 ?8 K$ O" n! r4 ]8 h
        UART1TxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½* [  Z7 Z6 e4 G9 h. Y
        UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶; A1 n; ^: M9 n$ [. @
        UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              
0 h" o8 }0 I, u2 z; W4 j$ k        UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      ) d. `  Z: u& j. g2 _' I2 J! y
        UART1TxDMA_Handler.Init.Memburst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä" |) E) _+ x) E5 }2 t5 L% h
        UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä* [3 k. R4 s; n2 J) D  E5 d
! J! d! _; V! V9 W: a! C
//    HAL_DMA_DeInit(&UART1TxDMA_Handler);   
& x) V# J& C5 D- T& Z        HAL_DMA_Init(&UART1TxDMA_Handler);
# ?- @; j) b6 {. m% C        __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);
& f: h4 L# S8 D; E+ D
- _; c; r+ Y$ h    //Rx DMAÅäÖÃ
7 r9 {2 u! p2 |. B+ n+ b        UART1RxDMA_Handler.Instance = DMA2_Stream2;                           //êy¾Yá÷Ñ¡Ôñ1 K9 C- ~7 V0 u  v
        UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ$ F5 ?6 C7 g2 X. O; @% c
        UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;             //′æ′¢Æ÷μ½íaéè8 S9 `1 V4 h" e
        UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½0 J/ V2 ?! f( O
        UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½, Y" z; ^5 z- W$ b* ~6 x( Q
        UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
2 r9 U0 A  a! d2 R% a; S        UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
. Z- T* ^) m7 O6 Z( y( [        UART1RxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
/ F! x2 p/ |( B1 R        UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
# M" ?# c0 i, l/ m1 O' Y' ]8 \" a        UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              
4 w  O/ [3 R: A9 c, w- f3 U        UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      , i: G% i$ ^9 [7 m6 _
        UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
& K5 f/ K& }/ @' e5 C8 I; v        UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä1 ^' x  O1 j9 {0 ~; |

. m5 q5 l* `7 }: f" g6 m        HAL_DMA_Init(&UART1RxDMA_Handler);
0 s" [% k1 h) C1 ~1 J        __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);4 i' W/ }. |2 y% r  ^& ]

4 {. [: D# a7 y7 N3 X! r. v        __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);* y+ Y% D2 \, j: o3 A
        __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);                //¿aÆô½óêÕÖD¶Ï! a: V9 q5 o: V
        HAL_NVIC_EnableIRQ(USART1_IRQn);                                                        //ê1ÄüUSART1ÖD¶Ïí¨μà/ `8 O5 j% h0 J: i+ G! H! m
        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                                        //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3( J5 n9 n5 Z+ y9 B6 Z7 W: ~9 V

- F# Q% k' W5 ~. P5 B# F2 c* M        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);              //开启了一次
0 Z* l$ l# f3 ~) s( C' y, Z  d
( l. B' w3 ]' O/ ~* v}
4 `7 N: W; @7 i  ]( n8 N; M0 `4 }4 \0 \  v1 c5 G, {
接收中断函数1 w5 G  a# n" f' Q6 w: Z
4 [4 Q6 ]6 J7 o1 U
void USART1_IRQHandler(void)                        
. x+ f6 S: y# G/ x' Q{1 j0 A5 B, `$ [* D  o3 l
unsigned short y;5 c% G7 D' A& p
        
  Y1 D0 N+ O) g0 S+ G2 F        if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET))5 e, h( M6 U& o" F& H
        {0 C/ u7 M1 i/ o, i, t0 P
                y = 400;
; m- ^) q  k7 \                LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");! s5 ^: Z( @7 W2 @
                LCD_ShowNum(180, y, RX_ADDR, 3, 16);
+ X: l$ L- ~5 q+ R, a6 s               $ q0 L( ^) s& j# y  [' J
                rx_end = 1;
! q( g  W$ }5 O; {               $ H) a# g# i! H' F% d
                if(RX_ADDR < 900){
' e% Q" S0 t9 x0 O- n$ h9 G                        RX_ADDR++;
) S) G2 `7 Y, G3 P1 Y$ c                }1 L0 ]. |+ k5 @4 b, @
                else{9 H' S  m8 k4 r% {" N* E; Y( D
                        RX_ADDR = 0;- p2 b1 K- s8 K+ v5 V
                }
- J2 X; v  D$ ^- S8 g        }
) P  c& \+ j  G  n; q! h
) q1 S9 B2 P5 l& k        HAL_UART_IRQHandler(&UART1_Handler);        
- N% X, j( \  I; Y}+ `* U) D& J( B! |1 V

该用户从未签到

2#
发表于 2021-12-27 11:07 | 只看该作者
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。
$ F3 b0 n' E/ f% T
- m/ H/ X$ F" |6 B: r; o! i__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
" g' t2 x: ~; f' \  ~7 O  F4 \
: l' K: z* `% j% {! }1 ty= UART1_Handler.Instance->SR;$ R! V. S! x$ x! X$ f
y= UART1_Handler.Instance->DR;, k( S- T8 o3 G0 C6 T1 b+ v  P
8 K8 Q' B* H" g
HAL_UART_DMAStop(&UART1_Handler);

该用户从未签到

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

该用户从未签到

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

该用户从未签到

5#
发表于 2021-12-27 11:08 | 只看该作者
/* USART6 串口空闲中断函数 */+ M- L$ ?; t! x2 L- ^' s
void HeaterComm_Callback(void)
. s. l! L+ V, w! B  U{
  s$ O& n; p7 \  uint32_t TmpFlag = 0;
: E7 e/ K& }2 K7 Y  uint32_t TmpLength;5 I" Y  B8 l! U+ K( E
  
, h9 X( N; Q1 r/ u  TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);      
" t& M. M! S/ {9 V* n2 |5 y  if((TmpFlag != RESET))
  F' a6 I7 m- M( e! A3 \6 I  {1 ]2 t; j4 ]0 a) b
    __HAL_UART_CLEAR_IDLEFLAG(&huart6);  
! c/ N: t6 ^* j  I    //HAL_UART_AbortReceive_IT(&huart6);                             
* j1 f+ L5 P; ^4 y    HAL_UART_DMAStop(&huart6);      ! f* }' m$ W8 O. O+ D- S. V; N2 l
    TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);         
2 Z0 m% Y# k2 u5 y    //TmpLength = hdma_usart6_rx.Instance->NDTR;
3 M3 y$ f! l3 D3 Y' _    HeaterComm.DataLength = 32 - TmpLength;. k& {5 s0 n$ F5 s
    osSignalSet (HeaterComm_TaskHandle, 1);                     //HeaterComm.ReceiveFlag = 1;$ t! }% `3 f! e2 i7 s
  }
& R" m8 p+ {, L& k9 z}

该用户从未签到

6#
发表于 2021-12-27 11:09 | 只看该作者
DMA接收数据的数量能够正确更新吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 00:06 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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