Wstęp
Mikrokontroler znajdujący się na płytce Nucleo wyposażono w 3 interfejsy USART. Na płytce także znajduje się konwerter USART na USB. Dzięki temu nie trzeba wykorzystywać dodatkowego zewnętrznego urządzenia.
Obsługa USART2 - wbudowany konwerter
USART2 został podłączony do wcześniej wspominanego konwertera. Jego wyprowadzenia znajdują się na pinie PA2 oraz PA3. Odpowiednio są to piny TX oraz RX.
Linia PA2, po której będą wysyłane dane z mikrokontrolera musi zostać skonfigurowana w trybie funkcji alternatywnej, jako wyjście push pull. Natomiast linia PA3 z niej są odbierane dane przez układ. Musi ona zostać skonfigurowana w trybie wejścia o wysokiej impedancji.
#include "stm32f10x.h" void GPIOInit(void); void USARTInit(void); void USART_Send(volatile char*); void Delay(int); int main(void) { GPIOInit(); USARTInit(); USART_Send("Przed petla!\n"); while (1) { } } void GPIOInit(void) { GPIO_InitTypeDef GPIOInit; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //PA2 Tx GPIO_StructInit(&GPIOInit); GPIOInit.GPIO_Pin = GPIO_Pin_2; GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; GPIOInit.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIOInit); //PA3 Rx GPIOInit.GPIO_Pin = GPIO_Pin_3; GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; GPIOInit.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIOInit); } void USARTInit(void) { USART_InitTypeDef USARTInit; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Ustawienie prędkości transmisji 9600bps USARTInit.USART_BaudRate = 9600; //Ustawienie dlugosci slowa USARTInit.USART_WordLength = 8; //Ustawienie bitu stopu USARTInit.USART_StopBits = USART_StopBits_1; //Brak kontroli parzystosci USARTInit.USART_Parity = USART_Parity_No; //Kontrola przepływu danych USARTInit.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Tryb pracy TX i RX USARTInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USARTInit); USART_Cmd(USART2, ENABLE); } void USART_Send(volatile char *c) { //Pętla działa do czasu wyslania ostatniego znaku while(*c) { //Sprawdza czy rejestr danych został opróżniony while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); //Prześlij dane, USART_SendData(USART2, *c); *c++; } } void Delay(int time) { int i; for (i = 0; i < time * 5000; i++) { } }
Obsługa zewnętrznego USARTU
Obsługa zewnetrznego USARTU polega właściwie dokładnie na tym samym. Jedynym wyjątkiem jest deklaracja innych pinów jako TX i RX oraz zmiana parametru USART na inny wykorzystywany. No i oczywiście należy podłączyć zewnętrzny konwerter UART na USB.
Do wyboru jest USART1, USART2 oraz USART3:
- USART1 TX - PA9 RX - PA10
- USART2 TX - PA2 RX - PA3
- USART3 TX - PB10 RX - PB11
Możliwe jest także prze mapowanie pinów. Wtedy możliwe jest następujące ustawienie:
- USART2 TX - PB6 RX - PB7
- USART2 TX - PD5 RX - PD6
- USART3 TX - PC10 RX - PC11
- USART3 TX - PD8 RX - PD9
Wysyłanie danych
Do wysłania danych z komputera na mikrokontroler wykorzystywana jest funkcja USART_ReceiveData(USART2).
USARTGetc pozwala na wyslanie odebranej danej w formacie char z mikrokontrolera na komputer.
#include "stdio.h" #include "stm32f10x.h" void GPIOInit(void); void USARTInit(void); void USARTSend(volatile char*); void SendCharc(volatile char); int main(void) { GPIOInit(); USARTInit(); USARTSend("Przed petla!\n"); while (1) { if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE)) { char c = USART_ReceiveData(USART2); SendCharc(c); } } } void GPIOInit(void) { GPIO_InitTypeDef GPIOInit; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //PA2 Tx GPIO_StructInit(&GPIOInit); GPIOInit.GPIO_Pin = GPIO_Pin_2; GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; GPIOInit.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIOInit); //PA3 Rx GPIOInit.GPIO_Pin = GPIO_Pin_3; GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; GPIOInit.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIOInit); } void USARTInit(void) { USART_InitTypeDef USARTInit; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Ustawienie prędkości transmisji 9600bps USARTInit.USART_BaudRate = 9600; //Ustawienie dlugosci slowa USARTInit.USART_WordLength = 8; //Ustawienie bitu stopu USARTInit.USART_StopBits = USART_StopBits_1; //Brak kontroli parzystosci USARTInit.USART_Parity = USART_Parity_No; //Kontrola przepływu danych USARTInit.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Tryb pracy TX i RX USARTInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USARTInit); USART_Cmd(USART2, ENABLE); } void SendCharc(volatile char c) { while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, c); } void USARTSend(volatile char *c) { //Pętla działa do puki będzie jakiś znak do wysłania while(*c) { //Sprawdza czy rejestr danych został opróżniony while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); //Prześlij dane, USART_SendData(USART2, *c); *c++; } }
Funckja printf
Tym razem zastosuje funkcję printf do przesyłania danych. Nie będę się tu za bardzo rozpisywał, ponieważ zostało to prze zemnie opisane przy mikrokontrolerze F411RE.
W związku z tym wrzucam od razu program. Ważniejsze rzeczy zostały opisałem w komentarzach w programie.
#include "stdio.h" #include "stm32f10x.h" void GPIOInit(void); void USARTInit(void); void USARTSend(volatile char*); void SendCharc(volatile char); int __io_putchar(int c); int main(void) { GPIOInit(); USARTInit(); USARTSend("Przed petla!\n"); printf("Funckja Printf!\n"); while (1) { } } void GPIOInit(void) { GPIO_InitTypeDef GPIOInit; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //PA2 Tx GPIO_StructInit(&GPIOInit); GPIOInit.GPIO_Pin = GPIO_Pin_2; GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; GPIOInit.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIOInit); //PA3 Rx GPIOInit.GPIO_Pin = GPIO_Pin_3; GPIOInit.GPIO_Speed = GPIO_Speed_50MHz; GPIOInit.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIOInit); } void USARTInit(void) { USART_InitTypeDef USARTInit; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //Ustawienie prędkości transmisji 9600bps USARTInit.USART_BaudRate = 9600; //Ustawienie dlugosci slowa USARTInit.USART_WordLength = 8; //Ustawienie bitu stopu USARTInit.USART_StopBits = USART_StopBits_1; //Brak kontroli parzystosci USARTInit.USART_Parity = USART_Parity_No; //Kontrola przepływu danych USARTInit.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Tryb pracy TX i RX USARTInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USARTInit); USART_Cmd(USART2, ENABLE); } void SendCharc(volatile char c) { while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, c); } int __io_putchar(int c) { SendCharc(c); return c; } void USARTSend(volatile char *c) { //Pętla działa do puki będzie jakiś znak do wysłania while(*c) { //Sprawdza czy rejestr danych został opróżniony while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); //Prześlij dane, USART_SendData(USART2, *c); *c++; } }