Skocz do zawartości
Komentator

Kurs STM32 - #5 - Komunikacja z komputerem, UART

Pomocna odpowiedź

html_mig_img
W poprzedniej części kursu STM32 nauczyliśmy się używać linii I/O do komunikacji z otoczeniem. Nadszedł czas na poznanie pierwszego interfejsu, który pozwoli na większą interakcję ze światem.UART posłuży nam do przesyłania komunikatów między STM32, a komputerem PC.

UWAGA, to tylko wstęp! Dalsza część artykułu dostępna jest na blogu.

Przeczytaj całość »

Poniżej znajdują się komentarze powiązane z tym wpisem.

Udostępnij ten post


Link to post
Share on other sites
Boże, jak ja się cieszę, że robicie ten kurs! Wdzięczny jestem niesamowicie 🙂

Przyłączam się do podziękowań, zawsze znajdzie się coś ciekawego na co człowiek wcześniej nie zwrócił uwagi 🙂

Mam tylko jedno pytanie: czy można zrealizować w analogiczny sposób komunikację PC z makietką STM32F4 Discovery Disco? Próbowałem na kilka sposobów ale komputer wykrywa tylko programator STLink, który sam w sobie nie jest widoczny dla terminalu Tera Term jako port szeregowy. Czy konieczne jest zastosowanie w tym przypadku konwertera UART TTL z USB lub, w przypadku komputera z RS232, układu MAX232?

Pozdrawiam

Udostępnij ten post


Link to post
Share on other sites

Niestety programatory płytek Discovery nie mają wbudowanego konwertera USB-UART. Konieczne jest więc zastosowanie dodatkowej przejściówki.

Udostępnij ten post


Link to post
Share on other sites
Mam tylko jedno pytanie: czy można zrealizować w analogiczny sposób komunikację PC z makietką STM32F4 Discovery Disco? Próbowałem na kilka sposobów ale komputer wykrywa tylko programator STLink, który sam w sobie nie jest widoczny dla terminalu Tera Term jako port szeregowy. Czy konieczne jest zastosowanie w tym przypadku konwertera UART TTL z USB lub, w przypadku komputera z RS232, układu MAX232?

Dodam jeszcze, że brak przejściówek UARTUSB był jednym z powodów, przez które zrezygnowaliśmy z zestawów Discovery i wybraliśmy Nucleo 🙂

Udostępnij ten post


Link to post
Share on other sites

Jak dla mnie początkującego w 32 bitowcach ten cykl jest pierwszym , który zachęca do dalszego eksperymentowania z nimi.

Ośmielę się zapytać jak zrobić aby po podłączeniu się do STM32 za pomocą terminala z PC otrzymać na powitanie jakiś tekst tak automatycznie?

W arduino dało to się wykonać coś takiego : while(Serial1.available()>0) .

Udostępnij ten post


Link to post
Share on other sites

O ile rozumiem Serial.available() zwraca liczbę odebranych bajtów.

Odpowiednikiem byłoby więc:

if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE))

Nie daje to co prawda automatycznego powitania - najpierw trzeba coś wysłać, dopiero wtedy dostaniemy powitanie. Ale działać powinno tak samo.

Żeby zrealizować faktycznie automatyczne powitanie, należałoby wykorzystać dodatkowe linie RS232, np RTS i CTS. Za ich pomocą można byłoby wykrywać samo podłączenie wtyczki. Niestety jest to nieco bardziej skomplikowane niż się wydaje - wiele przejściówek nie dostarcza tych sygnałów, programy emulujące terminal też nie zawsze prawidłowo nimi sterują. Więcej o pełnym RS232 można poczytać na wikipedii: https://pl.wikipedia.org/wiki/RS-232

Udostępnij ten post


Link to post
Share on other sites

Jak rozumiem dotyczy to Leonardo i konwertera USB. Ja znalazłem coś takiego: https://www.arduino.cc/en/Serial/Available

Niestety w przypadku stm32 i Nucleo nie mamy dodatkowych informacji jakie daje CDC, więc nie wykryjemy podłączenia tak łatwo. Jest to cecha samego interfejsu RS232, a nie STM32, czy Arduino.

W przypadku Leonardo, dostajemy informacje bezpośrednio z USB, dlatego mamy więcej możliwości.

Udostępnij ten post


Link to post
Share on other sites

Mam pytanie z innej beczki próbuje skonfigurować USART w STM32F103RTB6 z obsługą przerwań oraz buforem cyklicznym. USART podłączony jest do SN75176 ( transceiver RS485) schemat poniżej:

Mój problem jest taki że procesor w ogóle nie wchodzi do przerwania USART1_IRQHandler oraz wygląda jakby się zawiesił. Dodatkowo jeśli wysyłam w taki sposób USART_SendData(USART1, 'X'); zamiast USART_Puts( USART1, "485 test!\n" ); to transmisja działa. Wychodzi więc, że błąd jest gdzieś w funkcji SendChar lub w konfiguracji ale niestety nie potrafię go znaleźć. Chciałbym prosić bardziej doświadczonych forumowiczów o pomoc w rozwiązaniu problemu.

konfiguracja USART1 9600 8e1:

void RS485_Configuration(uint32_t baudrate, uint16_t parity)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_DeInit(USART1);

#ifdef  VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif

/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // USART1_IRQn
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Config DE/nRE */
/* Configure (PA.11) as Output push-pull */
GPIO_InitStructure.GPIO_Pin = DO_485;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure USART1 Tx (PA.9) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;

if( (parity != USART_Parity_Even) && (parity != USART_Parity_Odd) )
{
	parity = USART_Parity_No;
}
USART_InitStructure.USART_Parity = parity ;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_ClockInitStructure.USART_Clock  = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;


/* Configure the USART1 */
USART_Init(USART1, &USART_InitStructure);
USART_ClockInit(USART1,&USART_ClockInitStructure);

/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);

/* Send RS485 in Rece Mode */
SendMode(FALSE);
}

Funkcja SendChar:

void USART_SendChar(USART_TypeDef* USARTx, uint8_t Char)
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Char));

/* Fill Tx buffor */
uint8_t tmp_head;
tmp_head = (Buffer.TxBeg+1) & TX_BUF_MASK;
while(tmp_head == Buffer.TxEnd) {}
Buffer.TxBuf[tmp_head]=Char;
Buffer.TxBeg=tmp_head;

/* Turn On Tx Interrupt / Starting transmit */
USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);
}

Funkcja Puts

void USART_Puts( USART_TypeDef* USARTx, char *s )
{
register uint8_t c;
while ((c = *s++)) USART_SendChar( USARTx, c );
}

Udostępnij ten post


Link to post
Share on other sites
A zegary do GPIO i AFIO kolega podłącza?

TAK

void RCC_Config(void)
{
ErrorStatus HSEStartUpStatus;  //zmienna opisujaca rezultat uruchomienia HSE

RCC_DeInit();	                                         //Reset ustawien RCC
RCC_HSEConfig(RCC_HSE_ON);                               //Wlaczenie HSE
HSEStartUpStatus = RCC_WaitForHSEStartUp();		         //Odczekaj az HSE bedzie gotowy
if(HSEStartUpStatus == SUCCESS)
{
	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//
	FLASH_SetLatency(FLASH_Latency_2);                   //ustaw zwloke dla pamieci Flash; zaleznie od taktowania rdzenia
                                                    	 //0:<24MHz; 1:24~48MHz; 2:>48MHz
    RCC_HCLKConfig(RCC_SYSCLK_Div1);                     //ustaw HCLK=SYSCLK
    RCC_PCLK2Config(RCC_HCLK_Div1); 					 //ustaw PCLK2=HCLK
    RCC_PCLK1Config(RCC_HCLK_Div2);					     //ustaw PCLK1=HCLK/2
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //ustaw PLLCLK = HSE*9 czyli 8MHz * 9 = 72 MHz
    RCC_PLLCmd(ENABLE);                                  //wlacz PLL
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  //odczekaj na poprawne uruchomienie PLL
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);           //ustaw PLL jako zrodlo sygnalu zegarowego
    while(RCC_GetSYSCLKSource() != 0x08);                //odczekaj az PLL bedzie sygnalem zegarowym systemu

	/*Tu nalezy umiescic kod zwiazny z konfiguracja sygnalow zegarowych potrzebnych w programie peryferiow*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//wlacz taktowanie portu GPIO A	enkoder
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//wlacz taktowanie portu GPIO B	led
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//wlacz taktowanie USART1			uart
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

} else {}
}

Udostępnij ten post


Link to post
Share on other sites

Źródło problemu częściowo zostało znalezione. Jest to wina IDE używałem System Workbench for STM32 polecanego w kursie i ku mojemu zaskoczeniu kod po przekopiowaniu do Keil uVision5 działa bez zarzutu. W System Workbench for STM32 USART działał w moim kodzie tylko gdy używam go bez obsługi przerwań. Czy ktoś Was spotkał się z takim problemem? Nie ukrywam, że bardziej przyzwyczajony jestem do Eclipse i brakuje mi kilku udogodnień w Keilu.

Udostępnij ten post


Link to post
Share on other sites

simoon87, czy oba środowiska korzystają z tej samej biblioteki standardowej? Może masz gdzieś dwie różne wersje i stąd problemy?

Udostępnij ten post


Link to post
Share on other sites
simoon87, czy oba środowiska korzystają z tej samej biblioteki standardowej? Może masz gdzieś dwie różne wersje i stąd problemy?

Nie, korzystają z tej samej wersji (StdPeriph_Lib_V3.5.0). Sprawdzałem 😉 Poza tym System Workbench for STM32 samo pobiera sobie biblioteki StdPeriph w trakcie tworzenia projektu wiec nie ma mowy o pomyłce prędzej mógłbym się pomylić dodając ręcznie biblioteki do uVision.

Treker, używałeś w tym IDE Usartu z obsługą przerwań? Chciałbym ustalić czy jest to problem u mnie czy coś innego?

Udostępnij ten post


Link to post
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ę »

×