W tym poście opiszę w jaki sposób wykonać włączenie przesyłania informacji przez port szeregowy UART.
Projekt
Podobnie jak poprzednio należy rozpocząć od wybrania płytki w programie CubeMx. Po operacji okno programu powinno prezentować się następująco.
Rys. 1. Okno programu
W kolejnym kroku należy włączyć zegar zewnętrznych oraz wprowadzić ustawienia dla częstotliwosci taktowania które będą dostępne w zakładce Clock Configuration.
Rys. 2. Włączenie zegara
Dalej należy włączyć np. USART2 po którym będzie następowała komunikacja z komputerem. Po włączeniu trybu asynchronicznego piny po których nastąpi komunikacja zostaną podświetlone na zielono. Dla USART2 będzie to PA2 dla TX oraz PA3 dla RX. Jeśli zachodzi potrzeba przemapowania pinów to należy przytrzymać klawisz CTRL i lewy przycisk myszy na dany pin.
Rys. 3. Włączenie USART2.
Po tych operacjach należy przejść do zakładki Configuration, gdzie należy odpowiednio dobrać ustawienia dla sposobu transmisji poprzez wejście do ustawień USART2.
Rys. 4. Zakładka Configuration
Rys. 5. Parametry do ustawienia
Co do rzeczy jakie można ustawić w tej zakładce to do dyspozycji jest:
- Baud rate - czyli prędkość transmisji.
- Word Length - ilość bitów danych jakie będą wysyłanie.
- Parity - wybranie wykorzystywania bitu parzystości, który odpowiada za informacje dotyczącą przesłania wszystkich danych
- Stop Bits - jeden bit stopu pomiędzy przesyłanymi danymi.
- Data Direction - czyli sposób transmisji, czy tylko wysyłanie, odbieranie bądź wykorzystywanie obu sposobów transmisji.
- Over Sampling - czyli nadpróbkowanie, oznacza pobieranie stanu określonego bitu więcej niż jeden raz.
Po ustawieniu głównych parametrów należy przejść do następnej zakładki umożliwiającej wybranie trybu pracy. Do wyboru jest blokujący, z wykorzystaniem przerwań bądź DMA.
Aby włączyć przerwania należy przejść do zakładki NVIC Settings i załączenie zakładki Enabled. Ta część jest potrzeba do projektu drugiego, w którym wykorzystywane są przerwania.
Rys. 6. Włączenie przerwań
Gdy już całość została włączona to należy wygenerować projekt.
Funkcja przedstawiająca wygenerowany kod inicjalizacji USART-u wygląda następująco:
Funkcja przedstawiająca wygenerowany kod inicjalizacji USART-u wygląda następująco:
void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 9600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); }
Ustawienia pinów znajdują się w pliku stm32f4xx_hal_msp.c.
void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct; if(huart->Instance==USART2) { /* USER CODE BEGIN USART2_MspInit 0 */ /* USER CODE END USART2_MspInit 0 */ /* Peripheral clock enable */ __USART2_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE END USART2_MspInit 1 */ } }
Aby nawiązać komunikację w jedną stronę należy podać tekst jaki ma być przesyłany, można to wykonać w tablicy:
uint8_t tab[] = "Wyslany tekst";
Następnie należy wysłać tablicę za pomocą funkcji HAL_UART_Transmit(), z następującymi parametrami:
HAL_UART_Transmit(&huart2, tab, 13, 1000);
Po odpowiednim przygotowaniu programu odbierającego np. Terminal można odczytać wysyłany tekst.
Projekt 2
Drugi program będzie wykorzystywał przerwania od UART-u. Aby wymuszać przerwania cykliczne należy odpowiednio skonfigurować timer np. tim10. Wykonuje się to w następujący sposób:
Rys. 7. Włączenie TIM10.
W kolejnym kroku należy przejść do konfiguracji:
Rys. 8. Konfiguracja TIM10
Do wyboru są następujące parametry:
- Prescaler - czyli wartość dzielnika dla zegara
- Counter Mode - wybranie trybu zliczania, góra czy dół
- Counter Period - do jakiej wartości licznik będzie wykonywał zliczanie
- Internal Clock Division - dodatkowy dzielnik, pozwalający na dzielenie sygnału taktującego.
Po ustawieniu parametrów licznika, należy włączyć przerwanie w NVIC Settings.
Rys. 9. TIM10 włączenie przerwania
Po dołożeniu dodatkowych ustawień należy w CubeMx należy ponownie wygenerować projekt. Następnie w głównej części trzeba zdefiniować zmienną wykorzystywaną w przerwaniu, która będzie informowała o kolejnych wywołaniach pętli i ponownym wysłaniu wiadomości.
//Licznik wywolania funkcji i wyslania wiadomosci volatile uint16_t licznik = 0;
Kolejną częścią jest funkcja obsługująca wywołane przerwanie od licznika:
/* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { //Tablica z tekstem uint8_t dane[100]; //Rozmiar wiadomosci jaka bedzie wyslana uint16_t romiar = 0; //Sprawdzenie czy licznik jest parzysty if(( licznik % 2 ) == 0) { //Zwiekszenie zmiennej licznik, przetworzenie i wyslanie wiadomosci ++licznik; romiar = sprintf(dane, "Wiadomosc: %d.\n\r", licznik); HAL_UART_Transmit_IT(&huart2, dane, romiar); } else { //To samo co w if tylko dla nieparzystych ++licznik; romiar = sprintf(dane, "Przykladowy tekst konwersja: %f. \n\r", 5.6342); HAL_UART_Transmit_IT(&huart2, dane, romiar); } } /* USER CODE END PFP */
Ostatnim elementem jest włączenie licznika w funkcji main za pomocą:
HAL_TIM_Base_Start_IT(&htim10);
W drugiej części tego artykułu zajmę się opisem programu, który będzie wysyłał i dane z komputera na mikrokontroler.