Skocz do zawartości
Komentator

Kurs STM32 - #5 - Komunikacja z komputerem, UART

Pomocna odpowiedź

Mam zainstalowanego TeraTerma i po pacnięciu w entera dostaję tylko '\r'.

Poza tym program po wgraniu na płytkę zachowuje się w sposób oczekiwany, tj. reaguje tylko na on+enter i off+enter zmianą stanu diody, a wszystko inne jest kwitowane komunikatem z else. Zapewne łapie te nulle dzięki memsetowi, który wykonuje się po każdym wystawieniu komunikatu.

	while (1) {
	if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE)) {
		char c = USART_ReceiveData(USART2);
		my_buffer[buffer_index] = c;
		buffer_index++;

		if (buffer_index == my_buffer_size || c == '\r'  || c == '\n') {
			if (!strncmp(my_buffer, "on\r", 3) || !strncmp(my_buffer, "on\n", 3)) {
				send_string("Power on onboard LED.\r\n");
				GPIO_SetBits(GPIOA, GPIO_Pin_5);
			} else if (!strncmp(my_buffer, "off\r", 4) || !strncmp(my_buffer, "off\n", 4)) {
				send_string("Power off onboard LED.\r\n");
				GPIO_ResetBits(GPIOA, GPIO_Pin_5);
			} else {
				send_string("Not recognized command.\r\n");
			}
			memset(my_buffer, 0, my_buffer_size);
			buffer_index = 0;
		}

A takie rozwiązanie będzie prawidłowe, bez mącenia w pamięci? Działa wizualnie tak samo po wgraniu.

Udostępnij ten post


Link to post
Share on other sites

TeraTerm pozwala na konfigurację, więc można wybrać jakim znakiem kończy się linia. Gdybyś zmienił konfigurację byłoby to \n, albo \r\n. Teraz jest dużo lepiej.

Udostępnij ten post


Link to post
Share on other sites

Czy w przykładzie z kursu nie trzeba dołączać pliku nagłówkowego:

#include "stdio.h"

bo bez tego dostaję ostrzeżenie:

../src/main.c:64:3: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]

co oznacza ten komunikat?

Udostępnij ten post


Link to post
Share on other sites

Jak widać nie trzeba, ale powinno się 😉

Faktycznie lepiej byłoby więc dodać linijkę:

#include <stdio.h>

Udostępnij ten post


Link to post
Share on other sites

Hej Wszystkim. Super Kurs i mimo iż używam Nucleo f401 i f411 udaje mi się w pełni korzystać z tego kursu.

Niestety mam kilka problemów z implementacją i komunikacją poprzez UART z PC.

Konfiguruję go tak, aby po przyciśnięciu przycisku na płytce Nucleo zaświeciła się dioda i wysłał się znak 'Y' do PC. Gdy przycisk nie jest wciśnięty ma się wysyłać znak 'N'. W moim PC używam programu Termite, który poprawnie znajduje ST-Linka (podpięty poc COM3).

Tutaj cały kod który stworzyłem:

#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

Nie mogę rozwiązać tego problemu dlatego zgłaszam się o pomoc do bardziej doświadczonych kolegów.

Udostępnij ten post


Link to post
Share on other sites

Atikor, w komentarzach do kursu trzymajmy się układów F1. Jeśli masz problem z F4 załóż osobny temat w odpowiednim dziale. Tylko tak możemy uniknąć mieszania w głowach początkującym 🙂

Udostępnij ten post


Link to post
Share on other sites

Pobrałem Tera Term, ale po uruchomieniu programu zamiast "Hello World" na terminalu pojawia mi się coś takiego:

````Á'řř````Á''''''''''ř````Á'''řř``Á'''''''''''

Z czym jest problem?

Kod jest 100% dobry, więc chyba coś z terminalem.

Udostępnij ten post


Link to post
Share on other sites

ArczerMX, ustawiłeś prędkość transmisji (oraz pozostałe parametry)?

Udostępnij ten post


Link to post
Share on other sites

Problem rozwiązany 🙂

Wystarczyło zmienić prędkość transmisji na 10000.

Dzięki za pomoc

Udostępnij ten post


Link to post
Share on other sites

dlaczego po while() jest ; a nie {} ??

W:

while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);

USART_SendData(USART2 , c);

?????????????????

Udostępnij ten post


Link to post
Share on other sites

porousstructure, Bo to while jednolinijkowy którego linijka składa się z niczego. Tak można, ale niektórzy uważają to za nieczytelne. Mogłoby być:

while(test) action();

To samo działa dla ifa i fora.

Udostępnij ten post


Link to post
Share on other sites

Witam serdecznie. Zauważyłem, że w bibliotece StdPeriph występują podobne funkcje:

USART_GetFlagStatus()

oraz

USART_GetITStatus()

Po zgrubnej analizie kodu biblioteki wydaje mi się, że różnica między nimi polega na tym, że ta druga funkcja dodatkowo sprawdza czy przerwanie związane z flagą jest włączone. I jeśli jest, to wynik działania powinien być taki sam, przy czym ta druga wykonuje sporo dodatkowych operacji.

Stąd moje pytanie, czy można użyć tej pierwszej w przerwaniu do sprawdzania flag, czy może jednak ta druga robi coś ważnego, co przeoczyłem?

Udostępnij ten post


Link to post
Share on other sites

Hej wszystkim mam taki problem ze wygląda na to że w bufferze zapisuje sie tylko pierwsza przesłana litera, pytanie brzmi dlaczego ? I jak zmusić STM32 żeby zapisywał w nim kazda kolejną daną az do zapelnienia buferu? Prosze o pomoc.

#include "stm32f10x.h"

volatile int buffer[5];
volatile int timer_ms = 0;
volatile int i = 0;

void SysTick_Handler()
{
if(timer_ms)
{
	timer_ms--;
}
}

void delay_ms(time)
{
time = timer_ms;
while(time > 0){}
}

void send_char(char c)
{
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, c);
}

void send_string(const char* s)
{
while (*s)
	send_char(*s++);
}

int main(void)
{
GPIO_InitTypeDef gpio;
USART_InitTypeDef uart;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

SysTick_Config(SystemCoreClock/1000);

GPIO_StructInit(&gpio);
gpio.GPIO_Pin = GPIO_Pin_2;
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &gpio);

gpio.GPIO_Pin = GPIO_Pin_3;
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &gpio);

USART_StructInit(&uart);
uart.USART_BaudRate = 9600;
USART_Init(USART2, &uart);

USART_Cmd(USART2, ENABLE);



while (1) {
	if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE)) {
	    char c = USART_ReceiveData(USART2);
	    buffer[i] = c;
	    i++;
	    send_string("smth \n \r");
	    if(c == 0x0D)
	    {
	    	send_string(buffer); send_string("\n \r");
	    }
             }
      }
}

Udostępnij ten post


Link to post
Share on other sites

Witam, jadę z kursem ale napotkałem na pewien problem. Chodzi o funkcję printf.

Jeśli piszę stały ciąg znaków wszystko jest OK, ale jeśli chcę wstawić zmienną to procek się zawiesza i na terminalu już nie pojawia się linia ze zmienną. Tak jakby formatowanie tekstu nie działało. Poniżej testowy program:

#include "stm32f4xx.h"
#include <stdio.h>

void send_char(char c)
{
   while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
   USART_SendData(USART2, c);
}

int __io_putchar(int c)
{
if (c=='\n')
send_char('\r');
send_char(c);
return c;
}

int main(void)
{
int a=123;
GPIO_InitTypeDef gpio;
USART_InitTypeDef uart;

   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |RCC_AHB1Periph_GPIOB |RCC_AHB1Periph_GPIOC| RCC_AHB1Periph_GPIOD, ENABLE);

   GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
   GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
   gpio.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;  // Konfiguracja RS232
   gpio.GPIO_Mode = GPIO_Mode_AF;
   gpio.GPIO_OType = GPIO_OType_PP;
   gpio.GPIO_PuPd = GPIO_PuPd_UP;
   gpio.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOA, &gpio);

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

   USART_StructInit(&uart);
   uart.USART_BaudRate = 115200;
   USART_Init(USART2, &uart);
   USART_Cmd(USART2, ENABLE);

printf("Hello World!\n");
printf("Zmienna a = %d \n", a);
while(1){
	printf("Napis 2!\n");
}
}

Program zawiesza się po wypisaniu na terminal "Hello World!". Napisu "Napis 2!" już w ogóle nie wyświetla. Jeżeli usunę linię:

printf("Zmienna a = %d \n", a);

to program wchodzi do pętli while(1).

Korzystam z płytki STM32F4 - discovery z konwerterem USB<-->RS232. Program przerobiony pod tą płytkę. Ktoś pomoże?

Udostępnij ten post


Link to post
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...