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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问题描述;  开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。5 H/ Y, ^6 j" p- ]' y

" K$ J, l2 X3 N原代码如下:
' _- K- n; @. q6 J) ~1 K3 r+ {. `" d
! k' m2 x- ?# K) C# F                if(rx_end == 1){; u! g* N3 m& A+ Y: s9 |
                        rx_end = 0;2 w6 `" s0 u5 s5 r0 f$ o0 C; H  n+ z* N
                        
; ?. Y$ t8 i; W                        HAL_UART_DMAStop(&UART1_Handler);3 L) y7 w3 v9 v2 V/ I: n

* J3 @+ l( c: f, P4 N" }                        LCD_ShowString(300, 400, 200, 16, 16, "success!");' R/ U2 X% j: F7 k" ?1 O
                        LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);            //这条不能执行,执行就不能再接收数据  / _7 R6 a  U9 t; J* \/ z0 m  v
                                                                                                                     //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常
8 H3 p) R4 J4 m$ E8 A1 U                        , A! ?+ j' n9 Q" G* O
                        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);2 |5 C7 S" c0 p( ?$ x2 ?: v) G2 Z
                }        
8 G. C$ T7 m9 Q8 C' ~: r2 K3 G& ?4 E; _$ E( ?6 E! g: @0 b' x
: M1 Y- u! J4 Z& H9 l: x( ?0 H
配置原代码如下:
. b+ [* e! q9 g$ T
9 p  ]- d$ l2 `; z/ ~{# J  `% S" T9 j) D4 x
        __HAL_RCC_DMA2_CLK_ENABLE();                        //DMA2ê±Öóê1Äü        
# k4 [  b$ ?: \9 H2 K. i# Y, ~- h        __HAL_RCC_GPIOA_CLK_ENABLE();                        //ê1ÄüGPIOAê±Öó
: Q2 m1 e  H- O- }7 [- y        __HAL_RCC_USART1_CLK_ENABLE();                        //ê1ÄüUSART1ê±Öó: i# K# e: e+ H# ^3 p

3 z5 i3 R+ O4 l8 `( D, D        GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
  y( C9 _: U: F+ y' t        GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //¸′óÃíÆíìêä3ö  a9 }( f# c4 z# V* R
        GPIO_Initure.Pull=GPIO_PULLUP;                        //éÏà-
2 @, }* D. t1 @$ Q9 Y        GPIO_Initure.Speed=GPIO_SPEED_FAST;                //¸ßËù
* y. P6 R  X* o$ A) I- U* x  A& a        GPIO_Initure.Alternate=GPIO_AF7_USART1;        //¸′óÃÎaUSART1# R- \: H5 P( @" \
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA9: Y5 x2 }2 j% k/ k2 D% G, E
. H4 w1 P! U, x- ^! k& U5 y
        GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10# E( x9 X- h0 x4 E
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA107 n& a% z4 d8 {/ d  Y" l  \4 u) ]
        2 f6 I2 Q: J7 j8 m! B2 K2 b8 a* R
        UART1_Handler.Instance=USART1;                                            //USART12 v# u& r/ o4 D: l3 B& C1 \
        UART1_Handler.Init.BaudRate=9600;                                    //2¨ìØÂê
6 M1 J5 A* u" w; V: z        UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //×Ö3¤Îa8λêy¾Y¸ñê½
. k, W7 c# I3 H8 n        UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //ò»¸öí£Ö1λ
, N& D# h0 I$ v3 D( H1 _        UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //ÎTÆæÅ¼D£Ñéλ
+ C) p5 D/ q4 F, o8 S        UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //ÎTó2¼tá÷¿Ø
6 T0 A" B$ ~; F3 S9 _9 w. @        UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //êÕ·¢Ä£ê½; P8 b( H6 T: x1 p3 L
        HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()»áê1ÄüUART1
( C8 i$ w1 I8 e8 x8 l, d$ q# {0 z# ^! t- \6 d+ q9 |) Q) \6 w" M" ~
    //Tx DMAÅäÖÃ
! \  d& E7 Y/ F& ]5 C  b        UART1TxDMA_Handler.Instance = DMA2_Stream7;                           //êy¾Yá÷Ñ¡Ôñ! _# K! m" z' e, y
        UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
4 W2 I# W9 {, t0 m0 C        UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;             //′æ′¢Æ÷μ½íaéè
/ K8 H7 j" `% t* K# x2 l        UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½
8 _4 y$ A# Y# [& o% N- n) E        UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½
! Z( X" p+ M/ f( ^        UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ5 ]$ y' K, t9 D; J
        UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
0 C% b) ^; ]* T1 P& i! t8 s        UART1TxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
: W6 b/ J: U; o7 v3 ]# y9 a( t        UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶( i+ I% h% E# ~
        UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              8 B& f& L; ?/ u
        UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      * X! E( O7 K' b  ?3 Z( S' B
        UART1TxDMA_Handler.Init.Memburst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
% q0 W$ K, t. r. F% U. k5 u3 C, z# \        UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä' w! A: [6 b/ o$ [3 f& y

, j2 @6 M4 M" v. Y' v//    HAL_DMA_DeInit(&UART1TxDMA_Handler);   
' V! ~0 B! Y* t) `8 g        HAL_DMA_Init(&UART1TxDMA_Handler);% C7 {5 E% w5 d) d! j" {
        __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);
9 ?% `' H3 x* d; h7 w! _4 @9 G9 n; w( h  v% C
    //Rx DMAÅäÖÃ. w( z! _$ l+ w/ w3 |
        UART1RxDMA_Handler.Instance = DMA2_Stream2;                           //êy¾Yá÷Ñ¡Ôñ
" I+ x8 l9 a# q; p+ E        UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ, |! p( B  R' Q2 A8 C# \# `5 a
        UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;             //′æ′¢Æ÷μ½íaéè) S2 Q6 V, n* o) {! t! y0 J
        UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½* n) ?; F- D) w. i
        UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½" n$ d8 _* g3 q6 N- a3 x
        UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
9 Q7 e4 m9 ~4 H/ [        UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ
, b# z% d: O7 D. L- j6 Z# C9 f9 T        UART1RxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
% ?6 [$ P4 L* N  ^        UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶+ P! l" i' v% H( D( O7 E  t9 M
        UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              
: m* i2 N6 `  M, Z( A6 a        UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      , b" ?8 V2 ]+ r$ @6 s( \' `: w+ G
        UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä" L4 w+ \# i/ m- Z* D
        UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä' G- ?$ h, W) }# i6 F: b3 B

  ~. P0 B- N3 r7 b        HAL_DMA_Init(&UART1RxDMA_Handler);
" Q! J# v5 x) `1 Q6 T! J0 p        __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);
1 L/ Q) y/ S8 b. R- s$ {2 B) \+ r4 B: @, h, W2 D- a
        __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
; o0 Q$ _- U8 t& m' e! |        __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);                //¿aÆô½óêÕÖD¶Ï7 m, Z/ A3 }& X- [2 N6 Q- q
        HAL_NVIC_EnableIRQ(USART1_IRQn);                                                        //ê1ÄüUSART1ÖD¶Ïí¨μà
# _' j+ {9 h1 A8 K! P2 M" u" l        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                                        //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3
  Z; k5 b: E5 v) O+ s# L* L$ L, E7 J: c+ h9 c! F' _2 f' e* Q
        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);              //开启了一次
; _  h* W8 i3 M8 @& E
1 I, R4 r. @" Y}  c' }" \- b9 I; e+ B0 [$ m

- s! P4 h& d: m; R接收中断函数6 f& ^% G: W9 |3 s9 [+ h' A

% o) J- Y1 s0 R4 _8 Zvoid USART1_IRQHandler(void)                        ' g( ~  T7 q' z' Q7 m0 a% G- Q
{
% M, B  |7 K+ Z3 [  n! X1 x/ lunsigned short y;6 I& A3 t& V, z' F+ L0 Q4 V) w
        8 c! Z- S9 H, i4 a% `9 _/ ~" i
        if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET)), O4 E7 N& `) z0 }2 v
        {
0 m" n' [: e' _# U                y = 400;1 h  ?/ ^, H/ S, f9 E
                LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");
- T2 p0 b$ M( r2 x( U+ m                LCD_ShowNum(180, y, RX_ADDR, 3, 16);6 b# e: z7 `5 ]8 B& d7 n$ i
               & ]/ T: }% D2 M+ ?9 I5 k
                rx_end = 1;7 V6 L, j+ ~: e/ l3 `3 U
               ! [$ {0 t; G' z) ]* y
                if(RX_ADDR < 900){
8 i6 O5 |* o& [  u. h: Q" x                        RX_ADDR++;1 e" M7 g2 Q. ?, P. z* N. f* L: u# `
                }
( O, j6 J( G9 L4 C7 G$ v' l. d4 Z                else{; o' X" ^+ m2 N; l
                        RX_ADDR = 0;' r7 }( ~3 P" f# U" m1 W$ X
                }( H' S* h0 V% @, q8 u
        }
! ?5 H5 T) c3 z4 L) [4 L
; v# \6 W0 G) j6 D$ ?7 R# R        HAL_UART_IRQHandler(&UART1_Handler);        5 v' w. t- m1 `8 S
}* Y% u) |( r& N! g

该用户从未签到

2#
发表于 2021-12-27 11:07 | 只看该作者
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。' x4 x3 d  t: ~0 Y0 Y
" b+ I9 A! P9 h- u" a
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
9 n( B8 w! z, ^) m  I4 G6 u) a: i5 j9 {) n
y= UART1_Handler.Instance->SR;
2 J. P# g/ @( _5 f1 i" Vy= UART1_Handler.Instance->DR;3 @: k# O' E/ O% M
& ^6 T& n- D. b, b0 s4 e
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 串口空闲中断函数 */- ]/ X5 p) L" k) x* L7 y: k4 s* ~& E# a1 Y
void HeaterComm_Callback(void)
8 ]# H" N9 |" `, L; c! n{
" B* v$ I6 |0 [. ~/ {. y  uint32_t TmpFlag = 0;) w- n9 u( F2 W$ ~6 v' I
  uint32_t TmpLength;
0 @, L  i- s9 ^8 N4 A3 X  
8 @1 K; N& `. B. t  TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);      
+ M' E1 y2 T8 L: [+ v0 V" s  if((TmpFlag != RESET))
: e! U# d1 S; ~- D8 Y  {; T: O8 a% M4 ]* Q" |2 r1 \7 D
    __HAL_UART_CLEAR_IDLEFLAG(&huart6);  6 C6 {% B6 k4 P0 X0 O: n
    //HAL_UART_AbortReceive_IT(&huart6);                             " O, @$ }! l! g' w
    HAL_UART_DMAStop(&huart6);      
+ X  t7 [3 u  Y0 ?# V+ d  L    TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);         
6 b7 L. G1 H) M: H    //TmpLength = hdma_usart6_rx.Instance->NDTR;
: I6 L/ y8 l: L- m& w    HeaterComm.DataLength = 32 - TmpLength;
- L+ O0 f; d4 ]; P4 p9 F0 \    osSignalSet (HeaterComm_TaskHandle, 1);                     //HeaterComm.ReceiveFlag = 1;
, }5 @7 u  _6 p% w, w, H4 z  }
# W' u9 n  @; s' U) H3 v}

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-20 17:48 , Processed in 0.093750 second(s), 23 queries , Gzip On.

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

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

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