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.

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.

  • 2 tygodnie później...

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?

  • 1 miesiąc później...

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.

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 🙂

  • 3 tygodnie później...

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.

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.

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?

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

  • 1 miesiąc później...

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?

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...