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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问题描述;  开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。+ p0 t, E( A3 H& I' }2 h* w

9 _- E; |* q9 Q+ G0 ~3 b原代码如下:$ L' V* `8 T$ i" e

4 a' A, {9 \- K" y                if(rx_end == 1){' B; n" v; v1 |7 d2 S/ `
                        rx_end = 0;
. a7 |$ d  q6 [' _# j                        : E7 U  n( w5 O3 M  h, {6 Z
                        HAL_UART_DMAStop(&UART1_Handler);
7 k2 j5 _7 h1 s% ^) Z3 p! ^  u; _
. w' z5 G" L/ x  b1 E4 e. ]                        LCD_ShowString(300, 400, 200, 16, 16, "success!");) a) X; S3 j" D% T
                        LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);            //这条不能执行,执行就不能再接收数据  5 r( b; ], L' ?; g4 L
                                                                                                                     //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常
. v4 \3 b5 D: i/ v                        ! V/ L& t6 K' S7 y, ^
                        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);
2 M" C% o7 `+ P; s3 v+ [                }        & `/ P/ f/ j( i' O: b4 Q, J: l

& p3 @, s, H* B) m( E8 h0 Y9 o; E+ [: Q
配置原代码如下:1 N2 w2 C  `0 S: {  N" @6 ~6 ?
8 r2 ~' w+ u  D4 s7 K
{
$ A1 n& X/ j6 H& b# @) n* d. e8 }  [' e        __HAL_RCC_DMA2_CLK_ENABLE();                        //DMA2ê±Öóê1Äü        ' H/ Y% E& r# W1 b2 ~1 Q
        __HAL_RCC_GPIOA_CLK_ENABLE();                        //ê1ÄüGPIOAê±Öó' b$ C, s' I5 x* m) S
        __HAL_RCC_USART1_CLK_ENABLE();                        //ê1ÄüUSART1ê±Öó
0 ]9 y; V1 u0 J4 E( \) c1 H& o
  L5 E4 n  ^8 v4 `" ^6 Q1 I        GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
6 z3 I  c" o# d' M# h) w7 t        GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //¸′óÃíÆíìêä3ö2 f  r5 S; @6 }6 L% {
        GPIO_Initure.Pull=GPIO_PULLUP;                        //éÏà-
+ d) |' U/ n- b3 G/ w# P+ r0 t        GPIO_Initure.Speed=GPIO_SPEED_FAST;                //¸ßËù
4 {5 b% l: h& f$ m- \& h# P. D        GPIO_Initure.Alternate=GPIO_AF7_USART1;        //¸′óÃÎaUSART15 H: S" L8 d' t! L. b
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA9- O! H. P& o7 P' q

+ N/ Q" U, \6 L, Q4 ~2 n3 Y2 _( ?. s        GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10
* L& z1 _1 a5 m        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA10
, _4 n. P$ c! X! K9 P8 p        2 `% i8 _0 |! C, R; I
        UART1_Handler.Instance=USART1;                                            //USART15 T, b+ ?7 c8 N% ]  l
        UART1_Handler.Init.BaudRate=9600;                                    //2¨ìØÂê6 W1 ~$ V( R1 f1 f4 S, Y
        UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //×Ö3¤Îa8λêy¾Y¸ñê½4 n& r& ]0 u  y! E  l0 j! y
        UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //ò»¸öí£Ö1λ' E& v  ?2 ^  ^* A$ {3 y0 S2 L
        UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //ÎTÆæÅ¼D£Ñéλ; d9 y4 ^1 ?! {' q/ L5 F# R
        UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //ÎTó2¼tá÷¿Ø
/ P9 M# c3 ?4 g( Q  x* T' O        UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //êÕ·¢Ä£ê½6 j% l! C8 l; h8 h. C1 }
        HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()»áê1ÄüUART1
) @; R+ B4 u5 c; z  `5 G6 G8 n4 a  \, F: Y# N* H
    //Tx DMAÅäÖÃ
9 }9 X3 `+ Q0 y( f( S7 t/ ~0 G        UART1TxDMA_Handler.Instance = DMA2_Stream7;                           //êy¾Yá÷Ñ¡Ôñ
, C9 N' |$ u  n3 r1 ]$ K        UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
% R: G) x4 x+ {' R  p; B' G0 ?) {        UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;             //′æ′¢Æ÷μ½íaéè
; J* G4 t  p- Q( m* n: R1 p        UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½) h3 u9 E. S! N. ^* B
        UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½1 ]6 E6 n( k: p  {
        UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
: h" l9 a+ p% C: W        UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
( ^$ \- G2 Y$ z4 U, e6 W, a        UART1TxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½6 \3 c9 f* t5 P  p
        UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
" P) k0 V% ~& B- D/ i        UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              
2 U+ N) J+ L& W7 i        UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      
7 T5 v5 N7 c. X$ G8 W2 L3 r        UART1TxDMA_Handler.Init.Memburst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
6 R+ M; |# @/ U) _( G. X        UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä
/ h  ~/ ^7 b. B" B, Q) D
, N. v3 w  O1 h- z6 u& V//    HAL_DMA_DeInit(&UART1TxDMA_Handler);   
( Q) X$ @9 ^) C0 y        HAL_DMA_Init(&UART1TxDMA_Handler);4 p& Q% y, ~7 C: r; `: T
        __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);
. l) a- Y& |9 y  a& c3 M
4 r) M  L* X$ \9 H    //Rx DMAÅäÖÃ3 [  {; L" b. j0 o9 g1 v$ O
        UART1RxDMA_Handler.Instance = DMA2_Stream2;                           //êy¾Yá÷Ñ¡Ôñ- E4 a: A+ _4 B( w0 ], s3 ]5 a
        UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ, O# p2 _$ a3 a0 a: j. V: s
        UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;             //′æ′¢Æ÷μ½íaéè
! P$ Y5 f4 S9 d; a( Q        UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½9 L- V; O8 D+ i; ?+ N* e: K
        UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½
: S7 I5 g' v! n  t$ X        UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
4 D( O# G5 `! J) a, m# q3 b8 |0 G        UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ, _, Q6 K4 ?9 J% S3 h' M
        UART1RxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
/ K- U  W4 ~  [3 M        UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
* {7 p0 `; [; a) z! P+ o( q( D7 f        UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              3 x5 c0 R% l' k+ |+ {. Y. X- ^
        UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      " Q/ |/ Y( Y9 k+ P- i9 E
        UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
3 ]6 t# V) b- c7 z: v% ~9 s8 Q3 k        UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä
" e1 C: V7 L, f8 a! H/ d
2 Q* ~: }- {+ Z1 L) |% e) e        HAL_DMA_Init(&UART1RxDMA_Handler);
' p6 A' D. F, q# w# T, |# d& E& H1 v        __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);
; O# R* A' j" a7 G( X+ C, H5 P4 N# p% V/ R! A3 a- y
        __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
+ \8 P+ D+ o7 I' m7 Y        __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);                //¿aÆô½óêÕÖD¶Ï
3 x% d* i( _: l! N% H        HAL_NVIC_EnableIRQ(USART1_IRQn);                                                        //ê1ÄüUSART1ÖD¶Ïí¨μà
6 ?* A8 }8 |. G: a5 u+ s, O, j7 ?        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                                        //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3
5 U5 }9 e# \% g. q' B- G
) a  E  }0 _$ Z% {- j        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);              //开启了一次
( L* |& U  o$ |1 x" X
5 N7 ?1 p3 V0 m4 |) T5 Q}
/ S% i2 d* I. Q6 E1 `2 r) m) u4 @  h
& y. n: }3 p  R7 R! R接收中断函数6 ?( y5 Z6 W1 D- h4 W3 b

% I4 b6 x/ A% l) x6 Ivoid USART1_IRQHandler(void)                        4 R( }, ~& y7 f$ v+ F" z4 K, ^* \
{4 |  f( ?8 B8 q
unsigned short y;9 T$ |  T% e( M( m4 \$ e6 s
        
! E' l% ~1 M8 a- ~0 c) a+ z0 G        if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET))+ D* Q8 J8 ^9 o7 R1 K+ Z
        {6 N" O) j7 y  [( P# j* S8 P
                y = 400;4 f- d! ~, n8 [3 Q* |
                LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");
. \7 D- V* I+ @7 T" w; ]1 w                LCD_ShowNum(180, y, RX_ADDR, 3, 16);4 V# ^8 p1 Y* U/ e8 p5 a1 B
               
6 `% D- f# Z7 L0 g% g: m% b                rx_end = 1;# _3 @% p5 @" m: u  @
               
7 a2 e0 F* U0 d: V+ i                if(RX_ADDR < 900){
& N" C% J! a! U7 q) @3 F% C                        RX_ADDR++;4 Z8 V- S* H  y2 G  M
                }
: O. b; v) r- k7 k$ F                else{) `+ D: d9 u* s" K% L' a7 y
                        RX_ADDR = 0;$ z- I* x" g5 L% ^% A
                }
/ d! U8 p7 x9 G/ ?3 N        }7 G7 H+ Y  \& @  \
/ q) a; n! K# K2 B/ z+ D
        HAL_UART_IRQHandler(&UART1_Handler);        
' h# |' M( N9 l1 f}" A3 t" K& ]2 w6 b, g7 W7 |2 G& q

该用户从未签到

2#
发表于 2021-12-27 11:07 | 只看该作者
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。* L$ z3 x. f: J/ s2 h* Z+ c

* v0 C) h( W$ k  P7 S0 w' W__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
) h5 u! M; U! Y, a! L2 N9 E; y" g; K( U1 M, y2 ]
y= UART1_Handler.Instance->SR;
3 S6 \. |  z" w; j0 t5 c6 \8 {3 @8 g: m8 ^y= UART1_Handler.Instance->DR;& T: y5 Y0 C/ S; V' a! B
: E: x/ _6 n, x1 E% G# o1 p
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 串口空闲中断函数 */
# b2 J1 G& N8 i2 m% p, C/ A  E! xvoid HeaterComm_Callback(void)# e/ l. x/ _! I& H4 \' j& u% M
{2 {8 t/ Q% G3 O1 H
  uint32_t TmpFlag = 0;4 E7 q) j% e8 d) K3 u' p, ?  @
  uint32_t TmpLength;3 a, z  o+ j, z$ N
  
1 N# w  x, ]9 q( d2 s2 k  TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);      
2 ]9 ]! I+ `" }$ o% t) s  if((TmpFlag != RESET))
5 U; [# o& `8 c! x: Q  {1 ^, A6 i# i7 I8 |
    __HAL_UART_CLEAR_IDLEFLAG(&huart6);  
+ m! o6 L, j( G7 J7 Y0 M& B$ Q    //HAL_UART_AbortReceive_IT(&huart6);                             * u" i& k9 I1 U) t6 ]
    HAL_UART_DMAStop(&huart6);      
1 ]: I7 L- _  Q# I& z    TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);         
) ?( ~! J- }( n& G8 ~* i5 `- K    //TmpLength = hdma_usart6_rx.Instance->NDTR;
9 V/ Q8 B4 e7 Z' G) j6 {- T    HeaterComm.DataLength = 32 - TmpLength;
- T" f6 ]/ [5 b8 C0 \6 [( M+ {    osSignalSet (HeaterComm_TaskHandle, 1);                     //HeaterComm.ReceiveFlag = 1;
0 ~1 b$ R4 O$ f% M  }
  D) W4 z0 \  H9 @! ^}

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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