Skocz do zawartości

STM32 Hal Usart przerwania wysyłanie danych


henryxxl

Pomocna odpowiedź

Witam.

Mam pewną zagwozdkę otóż wysyłając dane poprzez uart jedno po drugim gubi mi dane. Jak wstawię delay pomiędzy to wszystko działa poprawnie. Domyślam się że chodzi oto że chcę wysyłać następne dane a poprzednich jeszcze nie wysłało więc próbowałem z hal status i pętlą while ale niestety nie pomogło. Mogę prosić o wskazówki jak uniknąć używania delay? 

HAL_UART_Transmit_IT(&huart1,(uint8_t*) numer_, 9);
		 HAL_Delay(10);
HAL_UART_Transmit_IT(&huart1, (uint8_t*) at_apostrof,rozmiar);
		 HAL_Delay(10);
HAL_UART_Transmit_IT(&huart1, (uint8_t*) "\r", 2);

Pozdrawiam

Link do komentarza
Share on other sites

Używasz HAL_UART_Transmit_IT zamiast HAL_UART_Transmit, co oznacza, że korzystasz z wersji przerwaniowej, która nie blokuje wykonywania kodu - resztę możesz sobie sam dopowiedzieć 😉 Ale ułatwię - po prostu przerwanie wciąż się wykonuje, kiedy chcesz w tym samym momencie wywołać drugie 😉. Jeżeli nie zależy Ci na przerwaniach użyj zwykłego blokującego HAL_UART_Transmit i będzie dobrze. 

A jak zależy to podeślij więcej kodu, chociaż patrząc na kod to chyba jest komunikacja z użyciem komend AT. I przy okazji z tego co "mi się wydaje" to "\r" jest jednym bajtem a nie dwoma 😉 (0x0D)

Reference: tutaj (blocking) i tutaj (non-blocking)

  • Lubię! 1
Link do komentarza
Share on other sites

Ja używam następującej sekwencji
   

sprintf(msg, " %d %s\r\n", wartosc,buff );

                                HAL_UART_Transmit(&huart1, msg, strlen(msg), HAL_MAX_DELAY);

przy czym w Private variables musisz zdefiniować zmienne wartosc,msg,buff jako:

char buff [] = "dzisiaj przeczytam o sprintf";//przykładowo.
uint16_t wartosc ;//np.wartość z pomiarów ADC
    char msg[50];

Jak widać sprintf  tworzy wiadomość msg,która,w tym przykładzie, składa się z dwóch części wartosc oraz buff.Oczywiście może być dużo więcej składowych np wartosc1,warosc2,buff1,buff2,etc. %d , %s  są to specyfikatory o których też musisz poczytać bo są integralną częścią sprintf

strlen określa długość wiadomości msg, a w  msg jest  wiadomość , transmisja będzie realizowana przez uart1 .Natomiast HAL_MAX_DELAY  to limit czasu.Więcej na ten temat np. w UM1850.

STM32Cube ma niesamowite możliwości.Zbudowana karta pomiarowa multi ADC na STM32F103xxxx  to zaledwie kilkanaście linijek i nie ma znaczenia czy odczyt odbywa się przez UART czy USB ale dochodzenie do rozwiązań to trochę mi zajęło czasu.

 

 

Link do komentarza
Share on other sites

Dziękuję za odpowiedzi 😉

Mam jeszcze jedno pytanie w jaki sposób prasować i odczytać numer telefonu z takiej wiadomości? If z strncmp informuje mnie że mam połączenie ale czym "wyłuskać" numer 123456789. Kombinuje coś na zasadzie napotkania apostrofu, co o tym myślicie?

+CLIP: "123456789",129,,,,0

 

if (strncmp("+CLIP:", pBuf, 1) == 0){
			
	}
Link do komentarza
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

 char *token;
	 token = strtok(pBuf,"\"");
	 uint8_t liczba_petli=0;
	 while(token != NULL)
	 {
		 liczba_petli++;
	  // printf("%s\n", token);
		 if (strncmp("123456789", token, 1) == 0  ){
			    if (liczba_petli==2){
			    			 HAL_UART_Transmit(&huart1, token, strlen(token), HAL_MAX_DELAY);
			    					 HAL_UART_Transmit(&huart1, "\n \r", strlen("\n \r"), HAL_MAX_DELAY);
			    					 LCD_GoTo(0,0);
			    					 			    LCD_WriteText("Pawel dzowni");
			    		 }
		 	}
   token = strtok(NULL, "\"");
	 }

W ten sposób rozpoznaję numer, kolego @szymonw nie mam pomysłu jak użyć do tego sprintf

Link do komentarza
Share on other sites

W moich rozwiązaniach robię to tak jak napisałem w pierwszym poście.Przecież ten Twój ciąg znaków trafia do jakiegoś bufora.Niech się nazywa bul[]. Wystarczy zatem  przeczytać odpowiednie komórki bufora.W związku z tym  będzie to tak:bul[8] bul[9],bul[10],bul[11],bul[12],bul[13],bul[14],bul[15],bul[16].

Jak masz STlink  to uruchom  STMStudio załaduj odpowiedni plik .elf  i pobaw się wybieraniem  odpowiednich komórek z bufora .To samo możesz zrobić używając debuggera w STM32Cubeide o ile dobrze działa.

sprintf(msg, " %d %d %d %d %d %d %d %d %d \r\n",bul[8],bul[9],bul[10],bul[11],bul[12],bul[13],bul[14],bul[15],bul[16]);

Im prościej tym lepiej.

Link do komentarza
Share on other sites

Też jestem zdania że im prościej tym lepiej dlatego pytam o rozwiązania bo sam jestem amatorem co do programowania.

sprintf wycina ale jakieś dziwne dane nie odpowiadające temu ciągu znaków.

 

forbot.png

Link do komentarza
Share on other sites

Widzę,że ktoś lubi strzelać z działa okrętowego do muchy...

#include <cstdlib>
#include <iostream>
#define START_INDEX 8

using namespace std;

char* getNumber(char* msg)
{
    char* returnData = (char*) calloc(9, sizeof(char));
    for(int n = START_INDEX; n < START_INDEX + 9; n++)
    {
        returnData[n - START_INDEX] = msg[n];
    }
    return returnData;
}

int main()
{
    char* clip = "+CLIP: \"123456789\",129,,,,0";
    char* number = getNumber(clip);
    cout << number;
    free(number);

    return 0;
}

Lub ulepszona wersja 😉 

#include <cstdlib>
#include <iostream>
#include <cstring>
  
using namespace std;

int lastIndexOf(char* array, char character)
{
    int length = strlen(array);
    for(int i = length - 1; i >= 0; i--)
        if(array[i] == character) return i;
    
    return -1;
}

int firstIndexOf(char* array, char character)
{
    int length = strlen(array);
    for(int i = 0; i < length; i++)
        if(array[i] == character) return i;
  
    return -1;
}

char* betterGetNumber(char* msg)
{
    int start = firstIndexOf(msg, '"') + 1;
    int end = lastIndexOf(msg, '"');
    int size = end - start;
  
    char* returnData = (char*) calloc(size + 1, sizeof(char));
    returnData[size] = '\0';
    for(int n = start; n < start + size; n++)
    {
        returnData[n - start] = msg[n];
    }

    return returnData;
}

int main()
{
    char* clip = "+CLIP: \"123456789\",129,,,,0";
    char* number = betterGetNumber(clip);
    cout << number;
    free(number);

    return 0;
}

Naprawdę nie ma co strzelać z sprintf'a do tak prostego zadania 😉 

P.S. pisane było na komputerze, więc trzeba trochę poprawić pod STM 😉 

Edytowano przez H1M4W4R1
Link do komentarza
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ę »
×
×
  • 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.