Регистр HAL UART DMA NDTR

Я работаю с stm32f4xx для использования операций UART DMA Tx-Rx.

У меня есть эта строка во-первых:

HAL_UART_Receive_DMA(&huart2,(uint8_t*)dma_rx_buf,DMA_BUF_SIZE);

Затем я проверяю регистр NDTR с помощью кода ниже: (я останавливаю DMA до того, как доберусь до этих строк)

valueNDTR = __HAL_DMA_GET_COUNTER(huart->hdmarx);

Иногда currentValueCDTR возвращает 0.

И я пробовал ниже строки, я ожидал значение NDTR = DMA_BUF_SIZE, но я получаю 0.

HAL_UART_DMAStop(&huart2);
valueNDTR = __HAL_DMA_GET_COUNTER(huart->hdmarx);

По какой причине значение NDTR возвращает 0, DMA переполнен или по другой причине?

Ответы (1)

NDTR == 0означает, что передача DMA завершена. Я не знаю, как вы обрабатываете буфер приема USART, но NDTR == 0регистр, вероятно, указывает на ошибку. Это может произойти, если в приемнике USART окажется больше байтов, чем вы ожидали, прежде чем вы их обработаете. В этом случае DMA останавливается (что на самом деле хорошо, потому что предотвращает переполнение DMA данными куда-то еще), а байты в буфере RX неполные или повреждены.

NDTR == DMA_BUF_SIZE(при условии передачи 1 байта) означает, что с момента включения DMA ни один байт не был получен.

Обычно буфер RX и DMA NDTR настраиваются в соответствии с максимальным ожидаемым размером пакета/кадра. Например, для реализации протокола Modbus должно хватить 256 байт.

Затем вы настраиваете прерывание обнаружения незанятой линии или прерывание тайм-аута Modbus для обнаружения конца кадра. В USART ISR вы отключаете DMA и DMA_BUF_SIZE - NDTRвыдает количество полученных байтов. Затем вы обрабатываете буфер RX и снова включаете RX DMA.