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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
问题描述;  开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。
' d/ U. r4 q2 e& O% T" n. u6 k* ~" v* m/ S
原代码如下:0 H7 d) _  @9 K8 H, I; `2 M

/ a1 {  n; s, @                if(rx_end == 1){
+ S% I2 o; |0 ?4 K9 m5 @. h                        rx_end = 0;
5 U7 r  X7 R2 L" Q5 p9 f/ Z                        
3 T4 t$ O+ B) B& c6 z5 s. g4 G2 D% V2 z                        HAL_UART_DMAStop(&UART1_Handler);: j; L$ Z9 ^) S" j+ W
. y7 G: l& @+ @0 _0 q  i3 o# M
                        LCD_ShowString(300, 400, 200, 16, 16, "success!");+ C. F. c. ]+ s& ?+ K0 F
                        LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer);            //这条不能执行,执行就不能再接收数据  
& n5 I% k( f- ?) c! x* ~                                                                                                                     //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常& Z5 Y1 y' W) F, n
                        5 G& k, I8 y& b6 f7 b
                        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);
! y0 N: A7 N% }3 H                }        7 n4 M' F  d4 {3 j: F

6 z  s8 V: j9 S0 h) r( [
: k7 [. U4 l/ ?: B9 R配置原代码如下:
1 ]% B, D8 i+ C9 Y5 r) ^. Y0 S. R: k* g  z) \
{& V. s' s! ]5 q* c
        __HAL_RCC_DMA2_CLK_ENABLE();                        //DMA2ê±Öóê1Äü        5 T# G2 F& N/ x% L, E, `+ L; Y! G
        __HAL_RCC_GPIOA_CLK_ENABLE();                        //ê1ÄüGPIOAê±Öó
! n- l) i4 e- ^9 T+ s# `) S8 l& p        __HAL_RCC_USART1_CLK_ENABLE();                        //ê1ÄüUSART1ê±Öó% g7 j; y5 P0 A( |. S' j

; N4 l  z7 u% P- _& t" Q        GPIO_Initure.Pin=GPIO_PIN_9;                        //PA9
: h0 d! i' u. y) @6 n- l: O+ o* K        GPIO_Initure.Mode=GPIO_MODE_AF_PP;                //¸′óÃíÆíìêä3ö8 q& V0 B8 `) b' N; }5 y% R& t
        GPIO_Initure.Pull=GPIO_PULLUP;                        //éÏà-9 `$ N" o& w/ F- z2 Q
        GPIO_Initure.Speed=GPIO_SPEED_FAST;                //¸ßËù8 z  `% P. j+ u% q
        GPIO_Initure.Alternate=GPIO_AF7_USART1;        //¸′óÃÎaUSART1( s3 |& q( a9 a
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA9
. W# k% a0 [3 ^4 I/ w3 c9 q! W! x0 j6 D* Z8 \! l
        GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10( z: f5 ?4 S5 Z+ N1 |" E; y( L
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);                   //3õê¼»ˉPA10
6 K  ?2 Q* h6 L9 c; E        - z8 F, J, B- V
        UART1_Handler.Instance=USART1;                                            //USART1
, l, k7 T1 M5 J# _6 l* q        UART1_Handler.Init.BaudRate=9600;                                    //2¨ìØÂê5 E$ V& x  z, i3 c; b
        UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //×Ö3¤Îa8λêy¾Y¸ñê½
# K3 _9 ~! Q: j1 O! m% Y        UART1_Handler.Init.StopBits=UART_STOPBITS_1;            //ò»¸öí£Ö1λ
7 M6 J7 n& O9 B: V' c        UART1_Handler.Init.Parity=UART_PARITY_NONE;                    //ÎTÆæÅ¼D£Ñéλ
5 U0 w( a! R6 ~        UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //ÎTó2¼tá÷¿Ø
+ w" o, l* S3 C9 z/ y        UART1_Handler.Init.Mode=UART_MODE_TX_RX;                    //êÕ·¢Ä£ê½
' d$ K2 W( n) w$ i& O5 }        HAL_UART_Init(&UART1_Handler);                                            //HAL_UART_Init()»áê1ÄüUART1
; P# M2 q. f$ _* i" a- d  Y* O9 p5 D
    //Tx DMAÅäÖÃ
0 L& m0 P& ~( d9 C0 ]$ w$ P        UART1TxDMA_Handler.Instance = DMA2_Stream7;                           //êy¾Yá÷Ñ¡Ôñ
! S8 \( ?' Y4 }# r, l) t( [        UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ1 n6 {( I9 F- c
        UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;             //′æ′¢Æ÷μ½íaéè
" O8 c" U) ^) R3 T# c7 u8 l        UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½2 S- w1 P8 v  U
        UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½
7 ^& s; x5 K+ E: k* E* G        UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
! J/ |2 J. I$ }" g) ^5 Z        UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ4 d0 Y5 x1 R7 D+ [7 z! x
        UART1TxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½0 y0 _- v# f: c$ v( V9 _
        UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
, t% w. Y( \) F' R5 {5 K. L        UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              ( ^. j/ M$ o; ]
        UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      % m. g# X& }; M# e* T$ i: ^
        UART1TxDMA_Handler.Init.Memburst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
5 m1 u) F/ l3 ~* v. C        UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä
7 S5 _1 c, Z0 f0 g3 q2 l% u) e
+ T" `5 v+ j4 F% S7 g4 P//    HAL_DMA_DeInit(&UART1TxDMA_Handler);   
. c5 ~( H- J. P; D        HAL_DMA_Init(&UART1TxDMA_Handler);
1 {) E* N+ {) h% J' |& H        __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler);$ S/ U5 d7 h. q' N; V

: H" _8 J8 |+ Q+ }$ H% l* u& `    //Rx DMAÅäÖÃ
* @! y5 p7 M9 D4 X( A9 x        UART1RxDMA_Handler.Instance = DMA2_Stream2;                           //êy¾Yá÷Ñ¡Ôñ8 v" a, w8 }3 S3 Q: ~& t
        UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4;                      //í¨μàÑ¡Ôñ
- q2 `' l- M. A1 ~. F& Y& @/ Y        UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY;             //′æ′¢Æ÷μ½íaéè: n6 i. V1 D% x1 s  n/ ^$ [4 q
        UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE;                 //íaéè·ÇÔöá¿Ä£ê½
7 v7 j( c1 H4 k4 c8 }; c        UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE;                     //′æ′¢Æ÷Ôöá¿Ä£ê½; w" q! i$ A& F9 {+ R" M
        UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;    //íaéèêy¾Y3¤¶è:8λ
7 o! r0 c" y: ^) [: ~1 X5 ?        UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;       //′æ′¢Æ÷êy¾Y3¤¶è:8λ- Z# P" S6 x3 B  j$ ^
        UART1RxDMA_Handler.Init.Mode = DMA_NORMAL;                            //íaéèá÷¿ØÄ£ê½
+ ?  C5 `  M# _% w* s1 K        UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM;               //ÖDμèóÅÏè¼¶
* j8 c# X! {& u; v+ J# Q( }: a        UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              / [& v; K/ \$ S6 I2 J# `. c1 ~
        UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;      * J6 n' _! k3 }5 B" g
        UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE;                 //′æ′¢Æ÷í»·¢μ¥′Î′«êä
2 a* ?& D6 X3 A. s        UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE;              //íaéèí»·¢μ¥′Î′«êä) h( r# {. l% j
, r( p5 ^* |9 j4 [
        HAL_DMA_Init(&UART1RxDMA_Handler);
3 n! y6 ?/ z% |/ S+ \7 v# A        __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler);8 w3 e# r1 |8 E; ]; U
. m/ L) Q; l1 t& d: B; b# p3 r
        __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);
) s2 m6 b3 X( z2 |$ N        __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE);                //¿aÆô½óêÕÖD¶Ï
4 y/ ]7 J5 b) m7 d6 p        HAL_NVIC_EnableIRQ(USART1_IRQn);                                                        //ê1ÄüUSART1ÖD¶Ïí¨μà
9 h- h- U- E5 [) f/ m7 m" i        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);                                        //ÇàÕ¼óÅÏè¼¶3£¬×óóÅÏè¼¶3. ]& p. u3 m. b9 f9 n6 x
) {7 }/ [) y8 z/ p8 v& V
        HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE);              //开启了一次, m2 F" u+ m6 D* Y( z$ `: T

8 R, \, a) j- l, J0 z# ~1 {# x}
, ^; b, ~9 p) ^3 E! v( x" P: o1 `% @, {6 j% F
接收中断函数# \% R7 }+ L; f2 F5 w4 e
, A+ \# h/ u0 y& R
void USART1_IRQHandler(void)                        7 s( @) J1 ^. ^$ g
{( L* l& }: {; x. z9 Y
unsigned short y;
2 C/ O* b* W; x/ ?' A) B5 y7 q        
& S6 s. [2 D' M0 T1 ^2 P7 l        if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET))
, {: o  W( R3 e5 V9 a8 H' @7 `        {
! @- B: }2 f5 c7 K& \5 }! L8 Y4 ?3 {. l                y = 400;
& F. O6 f- V) x                LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE");# V# J* x* {) U$ d6 ]
                LCD_ShowNum(180, y, RX_ADDR, 3, 16);
; V* c0 I, ^% m  N* r$ u               
: V9 T/ _, W4 s- E: ?                rx_end = 1;6 P& w  @$ u1 |6 I! n4 i
               7 H7 G8 _# @0 Q5 R% e
                if(RX_ADDR < 900){8 N8 s" o* t7 D
                        RX_ADDR++;
6 q0 \; n% S0 y: e" i: z                }' B5 ~7 L! A. @
                else{( b8 r) i  g# I2 q7 l! l; f0 M- T
                        RX_ADDR = 0;
1 v! b  X" A) Y* Q3 E9 a; g, n) d                }( @8 L' B- m) C6 f2 P- G
        }
9 {5 ~2 Q1 f8 ]* u, l2 A) e
0 h) g# V% E, e2 V7 Y' f# |        HAL_UART_IRQHandler(&UART1_Handler);        2 ^& {) @4 m& S
}
$ }: [2 W% ?) ^8 S

该用户从未签到

2#
发表于 2021-12-27 11:07 | 只看该作者
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。: _% a4 j- a: q5 \- ^8 c! W0 G
3 p2 S2 S# N6 ^. f  A9 X
__HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);: {9 T3 z5 j7 t; n& G
7 [- H$ g1 L! m: @0 E8 {+ |+ X
y= UART1_Handler.Instance->SR;
7 m, K7 v' e) s' K* \y= UART1_Handler.Instance->DR;2 X0 G; u/ {7 x0 T! J( Q. W
' S. K' m" I) Q: J  `1 u8 I' W
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 串口空闲中断函数 *// _) h/ m& r0 ]9 r. R. m
void HeaterComm_Callback(void)8 X; y6 Y  A3 ]& g7 \! Z$ n
{  m+ u# u3 ]  l- K
  uint32_t TmpFlag = 0;
5 m0 E8 ~4 o# ]$ X# n# ?( }4 U  uint32_t TmpLength;0 K" S1 N, C% P3 u
  
/ J. q' ]6 Y: N( g; P4 O  TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE);      
+ N# m8 C' W. A1 p' V/ l: Z  if((TmpFlag != RESET))
# W! Z1 \4 a9 k3 T. I. E  {
, ]( ^# j5 |9 Z( A6 x0 ?    __HAL_UART_CLEAR_IDLEFLAG(&huart6);  
8 S9 r! t3 i, J* l6 t% p    //HAL_UART_AbortReceive_IT(&huart6);                             , L# l# @  D. a  v5 Q; b0 {5 q" D
    HAL_UART_DMAStop(&huart6);      
; t6 [' z2 a& r8 G    TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx);         $ U/ a# y: T" k4 I
    //TmpLength = hdma_usart6_rx.Instance->NDTR;: ^4 |; M- A% }0 Z* l  Q) R, D
    HeaterComm.DataLength = 32 - TmpLength;& m  M- W7 V" u, ^* e% w: I
    osSignalSet (HeaterComm_TaskHandle, 1);                     //HeaterComm.ReceiveFlag = 1;9 N4 D1 R' G, U2 Y: q/ K
  }, h9 f  U7 K' p9 S. i
}

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-8-3 13:51 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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