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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问题描述;  开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。; N1 L. v# t9 I  C
% `9 m( f( b: c$ Q, K% Q
原代码如下:
' G& N5 l, F6 d4 j+ X! {; [; n/ s: ~2 z. O
                if(rx_end == 1){7 V9 b1 E' \- R( G9 l3 k0 ^! e
                        rx_end = 0;
3 \, O; g2 z* Q3 X                        8 {1 s) W+ U: @/ ]0 Q
                        HAL_UART_DMAStop(&UART1_Handler);
% }: s9 [3 G/ X& k5 u0 k
9 ^( \8 A2 A) @                        LCD_ShowString(300, 400, 200, 16, 16, "success!");
0 K6 W8 I9 O% I% O& w. S                        LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);            //这条不能执行,执行就不能再接收数据  
5 v: l( d: o2 E4 w( O                                                                                                                     //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常$ b  i8 h! r4 f- I  U+ ~
                        
" c" R8 W: }  g0 a4 Z                        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);9 N# \3 h; p: G2 V7 c+ I
                }        
8 F# `7 F* }; Q$ A8 k4 t
$ u! c* [3 i% ~  U2 \! e  J* g" G8 q# w0 M. l
配置原代码如下:4 {$ G  \3 l$ A
: e! X) e6 a  T0 p) u: w
{
/ M! v# Q; b  P% T        __HAL_RCC_DMA2_CLK_ENABLE();                        //DMA2ê±Öóê1Äü        & U+ d- S, V9 w+ ~1 ]  ?5 k
        __HAL_RCC_GPIOA_CLK_ENABLE();                        //ê1ÄüGPIOAê±Öó! e# v* H% S$ e4 l' Z3 [
        __HAL_RCC_USART1_CLK_ENABLE();                        //ê1ÄüUSART1ê±Öó1 b9 G. m) N0 l3 T
5 e, H4 u, q8 P3 j4 Y6 D% e
        GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
) v- C$ F0 I6 L/ n% b        GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //¸′óÃíÆíìêä3ö; W- z% S# s: l; [) @* M. l
        GPIO_Initure.Pull=GPIO_PULLUP;                        //éÏà-
! R% y6 J" v6 v2 _( l        GPIO_Initure.Speed=GPIO_SPEED_FAST;                //¸ßËù
/ ]& I2 Z' j! {% C& q1 `0 ?        GPIO_Initure.Alternate=GPIO_AF7_USART1;        //¸′óÃÎaUSART1
+ H+ e4 |+ a% }" L0 @        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA9
8 B! \1 g1 }8 r
" E5 f' D6 L% m7 e        GPIO_Initure.Pin=GPIO_PIN_10;                        //PA100 A8 ?2 j8 k% t# N" G- D
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA10& [0 \4 Y1 Z" Y" `* A. P+ _- x( k
        
; g% J6 h" m; _# e# U        UART1_Handler.Instance=USART1;                                            //USART19 B1 y' p: S6 [
        UART1_Handler.Init.BaudRate=9600;                                    //2¨ìØÂê, I! t! _7 W& u  ~
        UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //×Ö3¤Îa8λêy¾Y¸ñê½
2 i  ]& x4 S  T4 M; k3 n        UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //ò»¸öí£Ö1λ+ Q( m5 M" h$ P* b* w& i
        UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //ÎTÆæÅ¼D£Ñéλ
7 @0 [6 `% G( D9 p; N        UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //ÎTó2¼tá÷¿Ø
+ B' E0 ]% H$ c" l6 n& [        UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //êÕ·¢Ä£ê½
* s' ]* {" q. W        HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()»áê1ÄüUART1
$ u9 O- D! T& m: G
8 x/ y& X: _7 j0 `6 e, x    //Tx DMAÅäÖÃ% |7 g8 T. b3 E4 T. l% R# h
        UART1TxDMA_Handler.Instance = DMA2_Stream7;                           //êy¾Yá÷Ñ¡Ôñ5 k* m1 [# C# u. N) |$ T" [+ c
        UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
7 d5 y9 z5 k! D8 A0 @        UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;             //′æ′¢Æ÷μ½íaéè
0 d/ x  E3 B/ i: `) Y        UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½
5 R  D! E' A/ X( c2 ?        UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½
: s8 z6 _2 f+ {        UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
+ j# E6 Y' @  Q' i        UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
2 n) P# j) E" ^" q        UART1TxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½" I8 v0 t! i6 T& o' y9 q/ f
        UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
  c3 x0 {9 D  C        UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              ' [/ {' U% e$ ^
        UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      
  |# o3 b* x1 l- D3 z/ M        UART1TxDMA_Handler.Init.Memburst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
7 r1 U2 R4 c: @' e8 r  f        UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä8 o. n& D' M! `0 T3 e& B9 _8 a5 i

, r- X* G, U8 r! J4 n0 u//    HAL_DMA_DeInit(&UART1TxDMA_Handler);   5 q7 V# F1 m9 K8 P
        HAL_DMA_Init(&UART1TxDMA_Handler);" W, {9 }7 o! w9 B
        __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);) ~- `6 s, Y9 r" ]
3 C7 Q8 F! b, G' _
    //Rx DMAÅäÖÃ5 v7 B% r" l7 \0 _  U2 l1 ]
        UART1RxDMA_Handler.Instance = DMA2_Stream2;                           //êy¾Yá÷Ñ¡Ôñ
9 O: {% d: E. Y( h        UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
  j) |: T' q" e  _        UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;             //′æ′¢Æ÷μ½íaéè8 m; Q- C6 V) Q: f* G) L$ d
        UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½
: y: k1 E: N( k+ ~6 D6 r        UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½. a0 _* k3 [. A, H+ k3 p) K
        UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ; x. w! u0 I4 L9 [2 Y
        UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
/ c+ A& r& o0 b! A! \3 ^        UART1RxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
8 N  b, o' N  r: f: ?2 _        UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶% W# b6 y- e  F  h$ a
        UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              3 w1 G& E: f9 X
        UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      
& ?5 F  v1 S- n7 X; U0 G) \3 r* V        UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
5 h+ z$ f# ?4 N( ^$ ?4 z  ]        UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä8 I1 k) ^" @9 h

* r" p5 F$ p( d        HAL_DMA_Init(&UART1RxDMA_Handler);3 Y, k, p% P: c/ W0 p3 n* B
        __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);
8 V4 Y' P7 b# P, a) z$ x' t
! ?2 p, g0 N4 x" O        __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
2 S/ m2 v6 Y; p$ N; w! W6 c        __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);                //¿aÆô½óêÕÖD¶Ï0 y0 u" _" g: c' C' w. ]
        HAL_NVIC_EnableIRQ(USART1_IRQn);                                                        //ê1ÄüUSART1ÖD¶Ïí¨μà; Q& n  r* ?( l; v. J; l
        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                                        //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3
3 X# [0 f' O8 P8 H" [# B$ _) d* J3 T' \3 ~2 {0 b: _
        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);              //开启了一次
) Z  n4 f' W( D; m5 Y# u/ f( P3 R, z  s) p) Z
}4 A0 H1 O( D0 i1 ~1 Y, `2 |' G' y7 j

) z  O! x2 ~6 c5 M4 r' g9 `3 F) C7 S接收中断函数) w4 E# v5 E- s0 c5 Q: w! \

# u8 {! L! m) {, A: }void USART1_IRQHandler(void)                        ' E$ u8 Q- ?! N* w0 l1 s
{+ g. a$ ~2 T1 N/ Z8 }8 s
unsigned short y;; x3 Q( g; d6 n3 }7 {1 T8 {
          g1 F+ K5 G, N: [& l
        if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET))$ P' W7 B( `3 y' F6 j1 f$ e5 M
        {
5 ^) x( T/ V" F5 r                y = 400;
% ?* S+ p$ i7 V3 I& n0 l                LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");
# @+ W5 j, d3 ^/ g( T* d                LCD_ShowNum(180, y, RX_ADDR, 3, 16);
* i; f# y. U7 G2 S) i                 g+ t; @8 T$ x
                rx_end = 1;
8 ^' W1 y5 ~) B4 Y               
! H" O; R: u( h5 |                if(RX_ADDR < 900){
  A" |" U; }$ C, L! L! K                        RX_ADDR++;
! b, k! P& ?* h# a5 _& r4 f& T                }
; N3 k, D' M7 `                else{
8 ^- Q( g7 E# m) e1 K' N8 Y                        RX_ADDR = 0;8 k. @+ ^8 t2 |2 S: V
                }
0 U) k7 C, n+ ?) a. _; M        }/ R, ~4 T/ ^3 c) H6 P( A6 k4 ~

- `6 u; Y& a* F; g" V9 A: f) m; Q        HAL_UART_IRQHandler(&UART1_Handler);        $ ~) F4 z/ a) U) l6 K  ]
}% n* a  Z0 v  d# ~& U7 y% d% L

该用户从未签到

2#
发表于 2021-12-27 11:07 | 只看该作者
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。
( n7 L# L' t/ c% o! l
+ T, b6 p2 K" ~0 i4 w3 v__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);* V1 z( [, [' Y

2 n% e. m; }5 x* uy= UART1_Handler.Instance->SR;& o# s, W9 @4 n, s$ J+ o
y= UART1_Handler.Instance->DR;
, s& a# M: [5 g$ g, T; m) ?1 @+ |, T% Q
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 串口空闲中断函数 */0 C8 O/ k& f! J( i; d# }5 R
void HeaterComm_Callback(void)' l1 \+ E2 R" l% Y. P
{
+ c& V3 p, z1 J5 y0 v- |# n  uint32_t TmpFlag = 0;& z- s) c) v! _
  uint32_t TmpLength;$ F" X, K/ t( T. e! u8 H) U% c
  + `) G+ a+ R6 {% d- j. l
  TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);      1 D5 z# w( [. ]* L
  if((TmpFlag != RESET))
4 |; ?! i$ I) ]" T* R  {# c" r& i- B  r6 u$ D* U. ?# m! Q
    __HAL_UART_CLEAR_IDLEFLAG(&huart6);  
6 [. v, S  d: g4 t  d    //HAL_UART_AbortReceive_IT(&huart6);                             
3 Z  H* k4 R$ N8 @2 F% t+ J' @. ^    HAL_UART_DMAStop(&huart6);      4 N, \# T* m$ E2 G
    TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);         : C  u5 t! ^+ l+ U
    //TmpLength = hdma_usart6_rx.Instance->NDTR;; w2 j$ U. s4 O; a
    HeaterComm.DataLength = 32 - TmpLength;
6 q  O5 p3 {: r0 j% i    osSignalSet (HeaterComm_TaskHandle, 1);                     //HeaterComm.ReceiveFlag = 1;: \$ T* J0 J# X# D+ Z
  }- C/ [/ y& I. @! s  W% q
}

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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