Skocz do zawartości

STM32 - wpisywanie słów do terminala


Pomocna odpowiedź

Napisano

Witam,

Mam problem z tym by wpisać całe słowo do terminala, Wciskam jedną literkę i juz terminal reaguje, nie czeka aż wpisze drugą czy trzecią literkę. Proszę poradźcie mi jak wpisać całe słowo np onlampy, aby załączyć diody. Nie chce by sie uruchamiały po jednej wklepanej literce. Problem jest z uartem na stm32. Korzystam z USART2.

to nie z uartem jest problem tylko z procedurą odbierającą. Uart działa tak jak działa, czyli wysyła bajt po bajcie aż wyśle wszystko co mu wysłać kazano. Musisz sobie napisać bufor po stronie odbiornika i poczekać aż wszystko zostanie odebrane i dopiero wtedy reagować. Wtedy nie będzie miało znaczenia z jaką prędkością wciskasz literki..

możesz zrobić to np. tak choć odradzam używania poolingu:
 

char bufor[8];

while(1){

	for(c = 0; c<8; c++){

		while(!UART_RX_RDY);
		bufor[c] = UART_REG;
		if(!bufor[c]) break;  // jeśli NULL czyli koniec stringa wyjdź z pętli for

	}

	if(!(strcmp((const char*)bufor, "onlampy"))){ // porównaj ze sysłą predefiniowaną

// włącz lampy

	}else if(!(strcmp((const char*)bufor, "costam"))){

// rób coś tam..

	}else{

// niepasujące polecenie, wyjdź lub podejmij najbardziej sensowne w tym kontekście działanie

	}

}

 

Dziękuję za odpowiedź, ale w kodzie atMegaTona wyrzuca mi błąd w dwóch linijkach i niestety nie działa:( Chodzi o te dwie linijki:

while(!UART_RX_RDY);

bufor[c] = UART_REG;

Nie wiem czemu nie działa, gdyby można było napisać co nie jest tak...

Cały kod programu wrzucam tutaj:

#include "stm32f10x.h"

#define MCP_IODIR        0x00
#define MCP_IPOL        0x01
#define MCP_GPINTEN        0x02
#define MCP_DEFVAL        0x03
#define MCP_INTCON        0x04
#define MCP_IOCON        0x05
#define MCP_GPPU        0x06
#define MCP_INTF        0x07
#define MCP_INTCAP        0x08
#define MCP_GPIO        0x09
#define MCP_OLAT        0x0a

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


uint8_t spi_sendrecv(uint8_t byte)
{
    // poczekaj az bufor nadawczy bedzie wolny
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI1, byte);

    // poczekaj na dane w buforze odbiorczym
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    return SPI_I2S_ReceiveData(SPI1);
}

void mcp_write_reg(uint8_t addr, uint8_t value)
{
    GPIO_ResetBits(GPIOC, GPIO_Pin_0);
    spi_sendrecv(0x40);
    spi_sendrecv(addr);
    spi_sendrecv(value);
    GPIO_SetBits(GPIOC, GPIO_Pin_0);


}

int main(void)
{
    volatile int dly;
    GPIO_InitTypeDef gpio;
    SPI_InitTypeDef spi;
    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_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    GPIO_StructInit(&gpio);
    gpio.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; // SCK, MOSI
    gpio.GPIO_Mode = GPIO_Mode_AF_PP;
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpio);

    gpio.GPIO_Pin = GPIO_Pin_6; // MISO
    gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &gpio);

    gpio.GPIO_Pin = GPIO_Pin_0; // CS
    gpio.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &gpio);
    GPIO_SetBits(GPIOC, GPIO_Pin_0);

     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 = 115200;
     USART_Init(USART2, &uart);

     USART_Cmd(USART2, ENABLE);


    SPI_StructInit(&spi);
    spi.SPI_Mode = SPI_Mode_Master;
    spi.SPI_NSS = SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
    SPI_Init(SPI1, &spi);
    SPI_Cmd(SPI1, ENABLE);

    mcp_write_reg(MCP_IODIR, ~0x0f);


    char bufor[8];

    while(1){

        for(int c = 0; c<8; c++){


            if(!bufor[c]) break;  // jeśli NULL czyli koniec stringa wyjdź z pętli for

        }

        if(!(strcmp((const char*)bufor, "onlampy"))){ // porównaj ze sysłą predefiniowaną

             mcp_write_reg(MCP_OLAT, 0x0f);
        }else if(!(strcmp((const char*)bufor, "oflampy"))){

            mcp_write_reg(MCP_OLAT, 0x00);

        }else{

    printf("Bledny komunikat\n");

        }

    }
}

Jako terminala uzywam TERATERM

@rizone1234 witam na forum! Pamiętaj, aby kody programów umieszczać za pomocą odpowiedniej opcji w edytorze. Tym razem poprawiłem to za Ciebie 🙂

20 godzin temu, rizone1234 napisał:

Mam problem z tym by wpisać całe słowo do terminala, Wciskam jedną literkę i juz terminal reaguje, nie czeka aż wpisze drugą czy trzecią literkę.

Trochę nie rozumiem... czy Tobie chodzi o problem z programem na PC? Chodzi Ci o to, że chciałbyś, aby dane wysyłały się ciągiem dopiero po wciśnięciu "Enter", a nie po każdym napisanym znaku? To nie ma nic wspólnego z kodem na STM32 - kwestia ustawień terminala na PC 😉

OK. Postaram się poprawić. Właśnie o to mi chodzi, żeby dane były wysyłane cięgiem po wciśnięciu ENTER. Próbowałem dane wysłać za pomocą  Broadcast Command, ale nie wyszło. Jak mógłbyś mi pomóc jak to trzeba poustawiać w Teraterm.

(edytowany)
20 godzin temu, rizone1234 napisał:

Dziękuję za odpowiedź, ale w kodzie atMegaTona wyrzuca mi błąd w dwóch linijkach i niestety nie działa:( Chodzi o te dwie linijki:

Musisz sobie przypisać do tego makra własne odniesienie, skąd mam wiedzieć czego używasz jako odniesienia dla aktywności uarta?

coś w tym stylu:

#define UART_RX_RDY (... twoje odniesienie)  // np,  (REJESTR & BIT)  lub zmienna, lub zawartość wskaźnika, lub jakieś porównanie.

Ten if MUSI tam być bo inaczej będzie się bez sensu kręcić w pętli. W rejestrze uarta musi być flaga odbioru i właśnie ją sobie przypisz do tego makra i tyle.

Ten UART_REG to też tylko przykładowa nazwa jako odniesienie do rejestru odbiorczego ale może to być równie dobrze pole struktury frameworka albo adres do tego rejestru/pola. 

@rizone1234 jeśli nie rozumiesz jak to funkcjonuje to poczytaj sobie o uarcie w dokumentacji i polecam poszerzyć wiedzę dot. języka C.

Panowie, nie ma znaczenia jak te dane będą wysyłane czy po jednej literce na sekundę czy 1000, odbiornik uarta i tak odbiera po jednej ramce. O to jak mają być buforowane dane odbierane trzeba zadbać samemu, czy to korzystając z możliwości sprzętu czy też pisząc bufor samemu.

@rizone1234 daj znać jak sobie poradzisz z problemem.

Pozdrawiam

Edytowano przez Gość

Jeszcze raz to samo tylko po Twojemu:

char bufor[8];

while(1){

	for(c = 0; c<8; c++){
        
        while(!USART_GetFlagStatus(USART2, USART_FLAG_RXNE));
		bufor[c] = (char)USART_ReceiveData(USART2);
		if(!bufor[c]) break;  // jeśli NULL czyli koniec stringa wyjdź z pętli for

	}

	if(!(strcmp((const char*)bufor, "onlampy"))){ // porównaj ze sysłą predefiniowaną

// włącz lampy

	}else if(!(strcmp((const char*)bufor, "costam"))){

// rób coś tam..

	}else{

// niepasujące polecenie, wyjdź lub podejmij najbardziej sensowne w tym kontekście działanie

	}

}

  

Lepiej jednak zastosować do tego przerwanie niż tego whila ale do sprawdzenia starczy.

https://www.st.com/content/ccc/resource/technical/document/user_manual/59/2d/ab/ad/f8/29/49/d6/DM00023896.pdf/files/DM00023896.pdf/jcr:content/translations/en.DM00023896.pdf

str.608

  • 3 tygodnie później...
(edytowany)

Przepraszam, że nie odpowiadałem, ale nie miałem czasu. Wszystko gra, przerzucam się teraz na discovery. Cały cza zgłębiam język C oraz stm32.

Edytowano przez rizone1234

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