poniedziałek, 21 listopada 2016

[7] STM32F4 - CubeMx - USART przez DMA

W tym poście chciałbym przedstawić sposób wykonania transmisji poprzez USART z wykorzystaniem DMA. Wykorzystam do tego celu środowisko Cube Mx oraz biblioteki Hal'a. 

Cały proces włączenia USART'a oraz przesyłania dany z wykorzystaniem DMA za pomocą CubeMx jest bardzo prosty i bezproblemowy.

CubeMx


Proces przygotowania układu można zacząć od wyczyszczenie wszystkich przypisanych pinów. Jeśli wybrany został projekt z płytki, a nie sam mikrokontroler. Wykonuje się to poprzez Pinout -> Clear pinout.

Rys. 1. Wyczyszczenie przypisanych pinów

Teraz włączam odpowiednio RCC z HSE, oraz jeden z USART-ów. Po włączeniu elementów i ustawieniu zegara w sekcji na odpowiednią wartość, ja ustawiłem max czyli 168MHz.

W sekcji Configuration ustawiony zostaje USART na takie parametry jak na rysunku 2.

Rys. 2. Ustawienie USARTU

Na rysunku trzecim przedstawiłem sposób włączania dwóch dostępnych trybów dla DMA. tzn. ciągły i pojedynczy. W pierwszym z nich dane przesyłane są ciągle w kółko. Natomiast dla drugiego trybu dane przesłane są tylko raz.

Program


Po wygenerowaniu projektu, jak już wcześniej wspomniałem, do podstawowego działania już właściwinie potrzeba tylko jakichś danych oraz funkcji przesyłającej. Ponieważ wszystkie elementy są już ustawione i wstępnie zainicjalizowane z przedstawionymi danymi. 

Dane wysyłane są przez funkcję:

  1. HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

Wywołanie tej funkcji wygląda następująco:

  1. HAL_UART_Transmit_DMA(&huart1, buffer_to_send, sizeof(buffer_to_send));

Buffor z danymi powinien być typu 8 bitowego uint8_t albo char. Przesłanie wygląda tak że, dane wprowadza się do bufora po czym są one cyklicznie przesyłane poprzez DMA do komputera.

  1. /* USER CODE BEGIN Includes */
  2. uint8_t buffer_to_send[512];
  3. uint16_t i = 0;
  4. /* USER CODE END Includes */
  5. /* Private variables ---------------------------------------------------------*/
  6. UART_HandleTypeDef huart1;
  7. DMA_HandleTypeDef hdma_usart1_tx;
  8. /* USER CODE BEGIN PV */
  9. /* Private variables ---------------------------------------------------------*/
  10. /* USER CODE END PV */
  11. /* Private function prototypes -----------------------------------------------*/
  12. void SystemClock_Config(void);
  13. void Error_Handler(void);
  14. static void MX_GPIO_Init(void);
  15. static void MX_DMA_Init(void);
  16. static void MX_USART1_UART_Init(void);
  17. /* USER CODE BEGIN PFP */
  18. /* Private function prototypes -----------------------------------------------*/
  19. /* USER CODE END PFP */
  20. /* USER CODE BEGIN 0 */
  21. /* USER CODE END 0 */
  22. int main(void)
  23. {
  24.   /* USER CODE BEGIN 1 */
  25.   /* USER CODE END 1 */
  26.   /* MCU Configuration----------------------------------------------------------*/
  27.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  28.   HAL_Init();
  29.   /* Configure the system clock */
  30.   SystemClock_Config();
  31.   /* Initialize all configured peripherals */
  32.   MX_GPIO_Init();
  33.   MX_DMA_Init();
  34.   MX_USART1_UART_Init();
  35.   /* USER CODE BEGIN 2 */
  36.     for(i=0;i<512;i++)
  37.     {
  38.         buffer_to_send[i] = 'a';
  39.     }
  40.     HAL_UART_Transmit_DMA(&huart1, buffer_to_send, sizeof(buffer_to_send));
  41.   /* USER CODE END 2 */
  42.   /* Infinite loop */
  43.   /* USER CODE BEGIN WHILE */
  44.   while (1)
  45.   {
  46.   /* USER CODE END WHILE */
  47.   /* USER CODE BEGIN 3 */
  48.   }
  49.   /* USER CODE END 3 */
  50. }