STM32F4
[STM32F4xx] UART1 DMA Receive Test (s/w test)
트라이문
2018. 9. 6. 22:02
지난 번의 IDLE IT 를 사용한 DMA 테스트는 UART2에서 한 테스트였고,
이번에는 UART1 에서 테스트를 해 봤다.
수정할 내용만 적어 보면 다음과 같다.
UART1 인터럽트함수의 코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ /* Check for IDLE flag */ if (USART1->SR & UART_FLAG_IDLE) { /* We want IDLE flag only */ /* This part is important */ /* Clear IDLE flag by reading status register first */ /* And follow by reading data register */ volatile uint32_t tmp; /* Must be volatile to prevent optimizations */ tmp = USART1->SR; /* Read status register */ tmp = USART1->DR; /* Read data register */ (void)tmp; /* Prevent compiler warnings */ __HAL_DMA_DISABLE(&hdma_usart1_rx); } return; /* USER CODE END USART1_IRQn 0 */ HAL_UART_IRQHandler(&huart1); /* USER CODE BEGIN USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */ } | cs |
UART1 의 DMA 인터럽트는 DMA2_Stream2_IRQHandler 함수를 사용한다.
코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | void DMA2_Stream2_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream2_IRQn 0 */ size_t len, tocopy; uint8_t* ptr; /* Check transfer complete flag */ if (DMA2->LISR & DMA_FLAG_TCIF2_6) { DMA2->LIFCR = DMA_FLAG_TCIF2_6; /* Clear transfer complete flag */ /* Calculate number of bytes actually transfered by DMA so far */ /** * Transfer could be completed by 2 events: * - All data actually transfered (NDTR = 0) * - Stream disabled inside USART IDLE line detected interrupt (NDTR != 0) */ len = DMA_RX_BUFFER_SIZE - DMA2_Stream2->NDTR; tocopy = UART_BUFFER_SIZE - Write; /* Get number of bytes we can copy to the end of buffer */ /* Check how many bytes to copy */ if (tocopy > len) { tocopy = len; } /* Write received data for UART main buffer for manipulation later */ ptr = DMA_RX_Buffer; memcpy(&UART_Buffer[Write], ptr, tocopy); /* Copy first part */ /* Correct values for remaining data */ Write += tocopy; len -= tocopy; ptr += tocopy; /* If still data to write for beginning of buffer */ if (len) { memcpy(&UART_Buffer[0], ptr, len); /* Don't care if we override Read pointer now */ Write = len; } /* Prepare DMA for next transfer */ /* Important! DMA stream won't start if all flags are not cleared first */ //DMA2->HIFCR = DMA_FLAG_DMEIF1_5 | DMA_FLAG_FEIF1_5 | DMA_FLAG_HTIF1_5 | DMA_FLAG_TCIF1_5 | DMA_FLAG_TEIF1_5; DMA2->LIFCR = DMA_FLAG_DMEIF2_6 | DMA_FLAG_FEIF2_6 | DMA_FLAG_HTIF2_6 | DMA_FLAG_TCIF2_6 | DMA_FLAG_TEIF2_6; DMA2_Stream2->M0AR = (uint32_t)DMA_RX_Buffer; DMA2_Stream2->NDTR = DMA_RX_BUFFER_SIZE; __HAL_DMA_ENABLE(&hdma_usart1_rx); //DMA1_Stream5->CR |= DMA_SxCR_EN; /* Start DMA transfer */ } return; /* USER CODE END DMA2_Stream2_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_usart1_rx); /* USER CODE BEGIN DMA2_Stream2_IRQn 1 */ /* USER CODE END DMA2_Stream2_IRQn 1 */ } | cs |
main() 함수 코드 내용은 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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_USART1_UART_Init(); /* USER CODE BEGIN 2 */ __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); HAL_UART_Receive_DMA(&huart1,DMA_RX_Buffer,DMA_RX_BUFFER_SIZE); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if (Read != Write) { __wfi(); // or __wfe(); //__HAL_UNLOCK(&huart2); //__HAL_LOCK(&huart2); while (!(USART1->SR & USART_SR_TXE)); /* Wait till finished */ USART1->DR = UART_Buffer[Read++]; //HAL_UART_Transmit(&huart2,(uint8_t *)UART_Buffer[Read++],1,1); //while (!(USART2->SR & USART_SR_TC)); /* Wait till finished */ //while (!(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE))){}; if (Read > UART_BUFFER_SIZE) /* Check buffer overflow */ { Read = 0; } } //while(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin) == GPIO_PIN_RESET); //while(HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin) == GPIO_PIN_SET); } /* USER CODE END 3 */ } | cs |