完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
问题描述; 开启了USART1的DMA接收和发送,开启了USART1的IDLE中断,IDLE中断正常,能成功接收到数据。通过仿真能看到接收缓冲区数组中的数据,但不能访问,如果不访问,再开启DMA接收能正常接收,并且在仿真状态下也能查看。只要访问一次这个数组,下一次开启DMA接收后就不能接收数据了。
原代码如下: if(rx_end == 1){ rx_end = 0; HAL_UART_DMAStop(&UART1_Handler); LCD_ShowString(300, 400, 200, 16, 16, "success!"); LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer); //这条不能执行,执行就不能再接收数据 //屏蔽掉这条在仿真状态下能观察aRxBuffer接收正常 HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE); } 配置原代码如下: { __HAL_RCC_DMA2_CLK_ENABLE(); //DMA2ʱÖÓʹÄÜ __HAL_RCC_GPIOA_CLK_ENABLE(); //ʹÄÜGPIOAʱÖÓ __HAL_RCC_USART1_CLK_ENABLE(); //ʹÄÜUSART1ʱÖÓ GPIO_Initure.Pin=GPIO_PIN_9; //PA9 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //¸´ÓÃÍÆÍìÊä³ö GPIO_Initure.Pull=GPIO_PULLUP; //ÉÏÀ GPIO_Initure.Speed=GPIO_SPEED_FAST; //¸ßËÙ GPIO_Initure.Alternate=GPIO_AF7_USART1; //¸´ÓÃΪUSART1 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //³õʼ»¯PA9 GPIO_Initure.Pin=GPIO_PIN_10; //PA10 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //³õʼ»¯PA10 UART1_Handler.Instance=USART1; //USART1 UART1_Handler.Init.BaudRate=9600; //²¨ÌØÂÊ UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B; //×Ö³¤Îª8λÊý¾Ý¸ñʽ UART1_Handler.Init.StopBits=UART_STOPBITS_1; //Ò»¸öֹͣλ UART1_Handler.Init.Parity=UART_PARITY_NONE; //ÎÞÆæżУÑéλ UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //ÎÞÓ²¼þÁ÷¿Ø UART1_Handler.Init.Mode=UART_MODE_TX_RX; //ÊÕ·¢Ä£Ê½ HAL_UART_Init(&UART1_Handler); //HAL_UART_Init()»áʹÄÜUART1 //Tx DMAÅäÖà UART1TxDMA_Handler.Instance = DMA2_Stream7; //Êý¾ÝÁ÷Ñ¡Ôñ UART1TxDMA_Handler.Init.Channel = DMA_CHANNEL_4; //ͨµÀÑ¡Ôñ UART1TxDMA_Handler.Init.Direction = DMA_MEMORY_TO_PERIPH; //´æ´¢Æ÷µ½ÍâÉè UART1TxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; //ÍâÉè·ÇÔöÁ¿Ä£Ê½ UART1TxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; //´æ´¢Æ÷ÔöÁ¿Ä£Ê½ UART1TxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //ÍâÉèÊý¾Ý³¤¶È:8λ UART1TxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //´æ´¢Æ÷Êý¾Ý³¤¶È:8λ UART1TxDMA_Handler.Init.Mode = DMA_NORMAL; //ÍâÉèÁ÷¿Øģʽ UART1TxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM; //ÖеÈÓÅÏȼ¶ UART1TxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE; UART1TxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; UART1TxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE; //´æ´¢Æ÷Í»·¢µ¥´Î´«Êä UART1TxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE; //ÍâÉèÍ»·¢µ¥´Î´«Êä // HAL_DMA_DeInit(&UART1TxDMA_Handler); HAL_DMA_Init(&UART1TxDMA_Handler); __HAL_LINKDMA(&UART1_Handler, hdmatx, UART1TxDMA_Handler); //Rx DMAÅäÖà UART1RxDMA_Handler.Instance = DMA2_Stream2; //Êý¾ÝÁ÷Ñ¡Ôñ UART1RxDMA_Handler.Init.Channel = DMA_CHANNEL_4; //ͨµÀÑ¡Ôñ UART1RxDMA_Handler.Init.Direction = DMA_PERIPH_TO_MEMORY; //´æ´¢Æ÷µ½ÍâÉè UART1RxDMA_Handler.Init.PeriphInc = DMA_PINC_DISABLE; //ÍâÉè·ÇÔöÁ¿Ä£Ê½ UART1RxDMA_Handler.Init.MemInc = DMA_MINC_ENABLE; //´æ´¢Æ÷ÔöÁ¿Ä£Ê½ UART1RxDMA_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //ÍâÉèÊý¾Ý³¤¶È:8λ UART1RxDMA_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; //´æ´¢Æ÷Êý¾Ý³¤¶È:8λ UART1RxDMA_Handler.Init.Mode = DMA_NORMAL; //ÍâÉèÁ÷¿Øģʽ UART1RxDMA_Handler.Init.Priority = DMA_PRIORITY_MEDIUM; //ÖеÈÓÅÏȼ¶ UART1RxDMA_Handler.Init.FIFOMode = DMA_FIFOMODE_DISABLE; UART1RxDMA_Handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; UART1RxDMA_Handler.Init.MemBurst = DMA_MBURST_SINGLE; //´æ´¢Æ÷Í»·¢µ¥´Î´«Êä UART1RxDMA_Handler.Init.PeriphBurst = DMA_PBURST_SINGLE; //ÍâÉèÍ»·¢µ¥´Î´«Êä HAL_DMA_Init(&UART1RxDMA_Handler); __HAL_LINKDMA(&UART1_Handler, hdmarx, UART1RxDMA_Handler); __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler); __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_RXNE); //¿ªÆô½ÓÊÕÖÐ¶Ï HAL_NVIC_EnableIRQ(USART1_IRQn); //ʹÄÜUSART1ÖжÏͨµÀ HAL_NVIC_SetPriority(USART1_IRQn, 3, 3); //ÇÀÕ¼ÓÅÏȼ¶3£¬×ÓÓÅÏȼ¶3 HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE); //开启了一次 } 接收中断函数 void USART1_IRQHandler(void) { unsigned short y; if((__HAL_UART_GET_FLAG(&UART1_Handler, UART_IT_RXNE) != RESET)) { y = 400; LCD_ShowString(30, y, 200, 16, 16, "UART_IT_RXNE"); LCD_ShowNum(180, y, RX_ADDR, 3, 16); rx_end = 1; if(RX_ADDR < 900){ RX_ADDR++; } else{ RX_ADDR = 0; } } HAL_UART_IRQHandler(&UART1_Handler); } |
|
相关推荐
10个回答
|
|
本帖最后由 j***boox 于 2018-3-8 11:23 编辑
你没有把DMA关闭。先把DMA关闭以后才可以访问DMA内存区域。另外一般读取串口数据都应该是在主循环里面,判断读取标志为1,不要在中断函数中处理读取到的内容。 __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler); y= UART1_Handler.Instance->SR; y= UART1_Handler.Instance->DR; HAL_UART_DMAStop(&UART1_Handler); |
|
|
|
60user61 发表于 2019-3-13 13:53 你好, 谢谢回复。 我的访问是在主程序中, IDLE中断函数中 rx_end = 1; 主函数中判断 rx_end==1 后 关闭DMA HAL_UART_DMAStop(&UART1_Handler); 访问数据 LCD_ShowString(230, 400, 200, 16, 16, aRxBuffer); 重启DMA HAL_UART_Receive_DMA(&UART1_Handler, aRxBuffer, RXBUFFERSIZE); y = UART1_Handler.Instance->ISR; y = UART1_Handler.Instance->RDR; HAL_UART_DMAStop(&UART1_Handler); 关闭DMA前加上那两条后 现象还是一样的 不能访问接收缓冲数组。 |
|
|
|
总是只能显示第一次的数据,访问后重启DMA,后面的数据就收不到了,仿真状态也是看不到缓冲数组中的数据
|
|
|
|
|
|
|
|
谢谢,非常像,因为当我不能查看到接收缓冲数据的时候,DMA接收数据的数量能够正确更新。 |
|
|
|
|
|
|
|
|
|
|
|
60user61 发表于 2019-3-13 15:13 谢谢回复。 我程序功能基本实现了,实际上是访问数据访问的Cache,DMA更新的是缓冲区,导致存储器内容不一致,读出数据给人感觉就是没收到数据一样。 |
|
|
|
/* USART6 串口空闲中断函数 */
void HeaterComm_Callback(void) { uint32_t TmpFlag = 0; uint32_t TmpLength; TmpFlag = __HAL_UART_GET_FLAG(&huart6, UART_FLAG_IDLE); if((TmpFlag != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&huart6); //HAL_UART_AbortReceive_IT(&huart6); HAL_UART_DMAStop(&huart6); TmpLength = __HAL_DMA_GET_COUNTER((DMA_HandleTypeDef *)&hdma_usart6_rx); //TmpLength = hdma_usart6_rx.Instance->NDTR; HeaterComm.DataLength = 32 - TmpLength; osSignalSet (HeaterComm_TaskHandle, 1); //HeaterComm.ReceiveFlag = 1; } } |
|
|
|
楼主您好,请问问题解决了吗?我现在也在调试,遇到了同样的问题,想请教一下您是怎么解决的
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
462 浏览 0 评论
2318 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
2121 浏览 3 评论
4752 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2264 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-29 06:08 , Processed in 1.812105 second(s), Total 59, Slave 53 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号