问题描述; 开启了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.Direc
tion = 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);
}
谢谢回复。
我程序功能基本实现了,实际上是访问数据访问的Cache,DMA更新的是缓冲区,导致存储器内容不一致,读出数据给人感觉就是没收到数据一样。
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;
}
}
一周热门 更多>