Я намагаюся дізнатися про DMA та його використання в платформі STM32L4S9VI. Мене бентежить одне, що пов'язує передачу DMA до будь-якого конкретного переривання? У наведеному нижче прикладі мені цікаво, який UART переривання запускає передачу наступного байта в регістр даних передачі, а також те, як DMA визначає, яке переривання з UART викликалося. Як я розумію, насправді існує лише одна загальна лінія переривання USART2, яка переходить до DMA, тож як DMA насправді знає, що переривання - це те, що сигналізує про те, що він готовий мати ще один байт, поміщений в реєстр даних передачі? Чи
HAL_UART_IRQHandler(&huart2);
подбати про це?
Приклад:
/* Private variables ---------------------------------------------------------*/
extern UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
char *msg = "Hello STM32 Lovers! This message is transferred in DMA Mode.\r\n";
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void DMATransferComplete(DMA_HandleTypeDef *hdma);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void) {
HAL_Init();
Nucleo_BSP_Init();
hdma_usart2_tx.Instance = DMA1_Channel7;
hdma_usart2_tx.Init.Request = DMA_REQUEST_2;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_tx.XferCpltCallback = &DMATransferComplete;
HAL_DMA_Init(&hdma_usart2_tx);
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
HAL_DMA_Start_IT(&hdma_usart2_tx, (uint32_t)msg, (uint32_t)&huart2.Instance->TDR, strlen(msg));
//Enable UART in DMA mode
huart2.Instance->CR3 |= USART_CR3_DMAT;
/* Infinite loop */
while (1);
}
void DMATransferComplete(DMA_HandleTypeDef *hdma) {
if(hdma->Instance == DMA1_Channel7) {
//Disable UART DMA mode
huart2.Instance->CR3 &= ~USART_CR3_DMAT;
//Turn LD2 ON
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
}
}