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

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • 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.