STM32WL HAL_UARTEx_RxEventCallback无法触发问题求助
问题:STM32WL搭配SIM800L时UART DMA空闲检测回调不触发
我用STM32WL搭配SIM800L模块做通信,之前遇到UART缓冲区接收问题,遂改用带空闲线检测的UART DMA方案。现在能看到HAL_UARTEx_ReceiveToIdle_DMA执行后RxBuf数据有变化,但始终触发不了HAL_UARTEx_RxEventCallback回调函数,无法定位原因。以下是我的代码及UART、DMA配置:
应用代码
#define RxBuf_SIZE 60 #define MainBuf_SIZE 120 uint8_t RxBuf[RxBuf_SIZE]; uint8_t MainBuf[MainBuf_SIZE]; void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART1) { oldPos = newPos; // 复制新数据前更新上次位置 /* 如果数据量较大,当前位置+新数据长度超过主缓冲区大小,就绕回缓冲区开头 * 这是为了维护环形缓冲区,旧数据会被覆盖 */ if (oldPos+Size > MainBuf_SIZE) // 当前位置+新数据长度超过主缓冲区 { uint16_t datatocopy = MainBuf_SIZE-oldPos; // 计算主缓冲区剩余空间 memcpy ((uint8_t *)MainBuf+oldPos, RxBuf, datatocopy); // 把数据复制到剩余空间 oldPos = 0; // 指向缓冲区开头 memcpy ((uint8_t *)MainBuf, (uint8_t *)RxBuf+datatocopy, (Size-datatocopy)); // 复制剩余数据 newPos = (Size-datatocopy); // 更新当前位置 } /* 如果当前位置+新数据长度小于主缓冲区大小 * 直接复制数据并更新位置即可 */ else { memcpy ((uint8_t *)MainBuf+oldPos, RxBuf, Size); newPos = Size+oldPos; } /* 重新启动DMA接收 */ HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *) RxBuf, RxBuf_SIZE); __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); } /****************** 在这里处理数据 *********************/ /* 示例:检测接收数据中是否包含"OK"关键词 */ for (int i=0; i<Size; i++) { if ((RxBuf[i] == 'O') && (RxBuf[i+1] == 'K')) { isOK = 1; } } } /* USER CODE BEGIN 2 */ HAL_Delay(2000); sprintf(cmd,"AT\r\n"); HAL_UART_Transmit(&huart1,(uint8_t *)cmd,strlen(cmd),1000); HAL_Delay(1000); HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuf, RxBuf_SIZE); __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT); sprintf(cmd,"AT+SAPBR=3,1,Contype,GPRS\r\n"); HAL_UART_Transmit(&huart1,(uint8_t *)cmd,strlen(cmd),1000); /* USER CODE END 2 */
USART1初始化代码
static void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ }
DMA初始化代码
static void MX_DMA_Init(void) { /* DMA控制器时钟使能 */ __HAL_RCC_DMAMUX1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA中断初始化 */ /* DMA1_Channel1_IRQn中断配置 */ HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); }
内容的提问来源于stack exchange,提问作者Tryingtogetsome
相关产品推荐
相关产品推荐

