У меня есть следующий код, большая часть которого генерируется STM32CubeMX. (Я исключил огромное количество сгенерированных комментариев, чтобы сделать его читаемым.)
volatile int txDoneFlag = 0;
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
txDoneFlag = 1;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART1_UART_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
while (1)
{
LD2_GPIO_Port->BSRR = (uint32_t)LD2_Pin;
HAL_UART_Transmit_DMA(&huart1, (uint8_t*)"1: on \n", 16);
while(!txDoneFlag);
txDoneFlag = 0;
HAL_UART_Transmit_DMA(&huart2, (uint8_t*)"2: on \n", 16);
while(!txDoneFlag);
txDoneFlag = 0;
HAL_UART_Transmit_DMA(&huart3, (uint8_t*)"3: on \n", 16);
while(!txDoneFlag);
txDoneFlag = 0;
HAL_Delay(100);
LD2_GPIO_Port->BSRR = (uint32_t)LD2_Pin << 16U;
HAL_UART_Transmit_DMA(&huart1, (uint8_t*)"1: off \n", 16);
while(!txDoneFlag);
txDoneFlag = 0;
HAL_UART_Transmit_DMA(&huart2, (uint8_t*)"2: off \n", 16);
while(!txDoneFlag);
txDoneFlag = 0;
HAL_UART_Transmit_DMA(&huart3, (uint8_t*)"3: off \n", 16);
while(!txDoneFlag);
txDoneFlag = 0;
HAL_Delay(100);
}
}
DMA был настроен в генераторе STM32CubeMX, поэтому он должен быть правильным.
Когда я запустить этот код, он застревает в бесконечном l oop в первом while(!txDoneFlag);
, подразумевая, что HAL_UART_TxCpltCallback()
никогда не вызывается.
Это заставляет меня думать, что мне нужно сделать что-то еще, чтобы включить DMA.
Как заставить HAL_UART_Transmit_DMA()
работать?
Я уже пытался изменить порядок сгенерированных вызовов MX...
, чтобы MX_DMA_Init()
вызывался до ...UART_Init()
s.
-
Обновление: запрошенный код. Все три функции MX_USARTn_UART_Init()
имеют идентичные тела (за исключением номера UART.
/**
* @brief USART3 Initialization Function
* @param None
* @retval None
*/
static void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
/* DMA1_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
/* DMA1_Channel7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
}