[英]HAL_UART_Receive_DMA works only once. How can I fix it?
我正在使用 STM32F103RB 板,我想简单地将我通过串行端口从计算机收到的所有内容回显到该端口。 我必须使用 UART 和 DMA 来完成。 我已经在正常模式下使用 CubeMX 在 USART2_RX 上设置了 DMA。 我的问题是HAL_UART_RxCpltCallback
只被调用一次。 有趣的是,我在 PC 端得到了响应,但有额外0xFC
字节。 之后 controller 停止对通过串行端口发送的新数据做出反应,直到我将 controller 拔出并重新插入 usb 时才会这样做。这是回调和主要 function 的代码:
#define BUF_SIZE 16
uint8_t RX_BUF[BUF_SIZE] = {0};
uint8_t TX_BUF[BUF_SIZE] = {0};
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Transmit(&huart2, RX_BUF, BUF_SIZE, 1000);
HAL_UART_Receive_DMA(&huart2, RX_BUF, BUF_SIZE);
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_DMA(&huart2, RX_BUF, sizeof (RX_BUF));
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
编辑:我正在尝试通过 USB-C 加密狗在 Mac 上执行此操作。 这可能是问题所在吗?
在 ISR 中调用复杂函数不是一个好主意。 许多 HAL 函数使用系统节拍来测量超时,并且根据您的中断优先级,节拍可能会在您的 ISR 运行时被阻止。
最好将任何复杂的处理从您的 ISR 移到主 function 中。只需在 ISR 中设置一个标志以指示接收何时完成。 就像是:
static volatile bool uart_rx_done = false;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uart_rx_done = true;
}
int main()
{
// Initialisation stuff
for (;;)
{
uart_rx_done = false;
HAL_UART_Receive_DMA(&huart2, RX_BUF, BUF_SIZE);
while (!uart_rx_done)
;
HAL_UART_Transmit(&huart2, RX_BUF, BUF_SIZE, 1000);
}
}
首先,检查您是否正确配置了uart
和dma
中断。 在stm21f1xx_it.c
文件中,您应该会看到这些函数
void DMA1_Channel6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel6_IRQn 0 */
/* USER CODE END DMA1_Channel6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Channel6_IRQn 1 */
/* USER CODE END DMA1_Channel6_IRQn 1 */
}
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
以及main.c
文件中的MX_NVIC_Init()
function 中的uart2
配置。
但是你的主要错误是你根本没有激活uart
接收中断。 我建议暂时不要使用dma
,试试这个看看uart
中断是否被激活:
#define BUF_SIZE 16
bool uart_received = false;
uint8_t RX_BUF[BUF_SIZE] = {0};
uint8_t TX_BUF[BUF_SIZE] = {0};
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// HAL_UART_Transmit(&huart2, RX_BUF, BUF_SIZE, 1000);
uart_received = true;
HAL_UART_Receive_IT(&huart2, RX_BUF, BUF_SIZE);
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
//HAL_UART_Receive_DMA(&huart2, RX_BUF, sizeof (RX_BUF));
HAL_UART_Receive_IT(&huart2, RX_BUF, BUF_SIZE);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (uart_received) {
HAL_UART_Transmit(&huart2, RX_BUF, BUF_SIZE, 1000);
uart_received = false;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
如果这可行,那么您可以使用HAL_UARTEx_ReceiveToIdle_DMA
激活uart-dma
中断,并使用HAL_UARTEx_RxEventCallback
回调 function(假设已配置dam
中断)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.