Skocz do zawartości

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.

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.

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?

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.

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 🙂

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.

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.

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?

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");
	    }
             }
      }
}

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?

Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

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.