Skocz do zawartości

[C] [STM32F4] Komunikacja pomiędzy Nucleo F401 a PC


Atikor

Pomocna odpowiedź

Witajcie.

Jakiś czas temu postanowiłem przesiąść się z AVR na STM32. Zakupiłem płytkę NUCLEO z mikrokontrolerem STM32f401. Miała sporo fajnych peryferii i niezłe taktowanie. Pobawiłem się trochę GPIO i ADC (czysto testowo) i jakoś uczelnia wzięła górę więc odłożyłem Nucleo na bok.

Trafiłem ostatnio całkiem przypadkiem na kurs STM32 oparty na F103 i postanowiłem wyciągnąć moje Nucleo z szafki. Kilka różnic między f103 a f401 jest ale szperając trochę w internecie udawało mi się przenieść kod po kilku zmianach na F4. Jednak problem pojawił się gdy próbowałem skomunikować moją płytkę Nucleo z PC. Nie mogę w żaden sposób przesłać jakiejkolwiek danej do komputera (nawet śmieci nie dostaję). Przeszukałem sporą cześć internetu gdzie poruszany był temat USARTu na F4 i nie doszedłem z tym do ładu.

Używam środowiska AC6 do programowania mojego Nucleo tak jak w kursie, na PC używam Termite bo ma przyjazny sposób ustawiania opcji i próbuję komunikacji wykorzystując USART2 identycznie jak w kursie. Już nawet sprawdzałem w trybie Debugu jak się zachowują rejestry i nic nie znalazłem.

Z racji, że nie mam za dużego doświadczenia proszę o pomoc bardziej doświadczonych kolegów.

Poniżej mój kod:

#include "stm32f4xx.h" 

void delay(int czas) 
{ 
   int i=0; 
   for(i=0; i<czas*2000; i++); 
} 

//Ustawienie dla diody LED na płytce Nucleo 
void GPIOA_LED_init(void) 
{ 
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
   GPIO_InitTypeDef gpio; 
   gpio.GPIO_Pin = GPIO_Pin_5; 
   gpio.GPIO_Mode = GPIO_Mode_OUT; 
   gpio.GPIO_OType = GPIO_OType_PP; 
   gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; 
   gpio.GPIO_Speed = GPIO_Speed_100MHz; 
   GPIO_Init(GPIOA, &gpio); 

} 

//Ustawienia dla przycisku USER na płytce Nucleo 
void GPIOC_BUTTON_init(void) 
{ 
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 
   GPIO_InitTypeDef gpio; 
   gpio.GPIO_Pin = GPIO_Pin_13; 
   gpio.GPIO_Mode = GPIO_Mode_IN; 
   gpio.GPIO_OType = GPIO_OType_PP; 
   gpio.GPIO_PuPd = GPIO_PuPd_UP; 
   gpio.GPIO_Speed = GPIO_Speed_100MHz; 
   GPIO_Init(GPIOC, &gpio); 
} 

//Ustawienie USART1 
void USART2_init(void) 
{ 
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 

   GPIO_InitTypeDef gpio; 
   //PIN2 to TX 
       gpio.GPIO_Pin = GPIO_Pin_2; 
       gpio.GPIO_Mode = GPIO_Mode_AF; 
       gpio.GPIO_OType = GPIO_OType_PP; 
       gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; 
       gpio.GPIO_Speed = GPIO_Speed_100MHz; 
       GPIO_Init(GPIOA, &gpio); 
       GPIO_PinAFConfig(GPIOA, GPIO_Pin_2, GPIO_AF_USART2); 
   //PIN3 to RX 
       gpio.GPIO_Pin = GPIO_Pin_3; 
       gpio.GPIO_Mode = GPIO_Mode_AF; 
       gpio.GPIO_OType = GPIO_OType_OD; 
       gpio.GPIO_PuPd = GPIO_PuPd_UP; 
       gpio.GPIO_Speed = GPIO_Speed_100MHz; 
       GPIO_Init(GPIOA, &gpio); 
       GPIO_PinAFConfig(GPIOA, GPIO_Pin_3, GPIO_AF_USART2); 
   USART_InitTypeDef usart; 
   //Konfiguracja usarta 
       usart.USART_BaudRate = 9600; 
       usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 
       usart.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; 
       usart.USART_Parity = USART_Parity_No; 
       usart.USART_StopBits = USART_StopBits_1; 
       usart.USART_WordLength = USART_WordLength_8b; 
       USART_Init(USART2, &usart); 
   USART_Cmd(USART2, ENABLE); 

} 

//Wysyłanie znaku przez UART2 
void USART2_send_char( uint8_t znak) 
{ 
   while( USART_GetFlagStatus(USART2, USART_FLAG_TXE)==RESET ); //jesli bufor pusty 
       USART_SendData(USART2, znak); 
} 

int main(void) 
{ 
   GPIOA_LED_init(); 
   GPIOC_BUTTON_init(); 
   USART2_init(); 
   for(;;) 
   { 
       if( GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13)==RESET ) 
       { 
           GPIO_SetBits(GPIOA, GPIO_Pin_5); 
           USART2_send_char('Y'); 
       } 
       else 
       { 
           GPIO_ResetBits(GPIOA, GPIO_Pin_5); 
           USART2_send_char( 'N'); 
       }//if 
   }//for 
}//main 
Link do komentarza
Share on other sites

Dzięki Elvis, pomogło.

Teraz Nucleo komunikuje się z PC ale przesyła jakieś śmieci. Macie może tez jakiś pomysł na to?

Zarówno w Nucleo jak i w programie Termite mam ustawione te same parametry:

Baudrate = 9600

8 bitów danych

0 bit parzystości

1 bit stopu

Poniżej zrzut śmieci które trafiają do PC.

EDIT:

Ok, układ zaczął działać poprawnie ale tylko wtedy gdy w Nucleo F401 ustawiłem Baudrate na 115200, a w termite na 38400. Z prostej matematyki widać 3 krotną różnicę. Możliwe, żeby rejestr BRR był źle ustawiany przez bibliotekę STPeriph? Ewentualnie coś jest nie tak z zegarem dla USARTa.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.