logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega128][C i VB] krzaki w komunikacji

owenpe 09 Sty 2010 19:33 1821 9
REKLAMA
  • #1 7510750
    owenpe
    Poziom 17  
    Udało mi się nawiązać komunikację między Atmega128 i PC (Hyper Terminal), ale niestety pojawiają się krzaki na kompie i nie bardzo wiem co z tym zrobić:/

    Sprawa wygląda następująco:
    1. mam liczbę "uint8_t a" i zamieniam ja na "unsigned char b" za pomocą polecenia:
    b=(unsigned char)a;
    2. wysyłam ją z atmegi przy użyciu USARTa:
    void wyslij(unsigned char data)
    {
    while((UCSR0A&(1<<UDRE)) == 0);
    UDR0 = data;
    }
    i w rezultacie na kompie pojawiają się krzaki.

    Na czym polega mój błąd? Jakaś podpowiedź?? :)
  • REKLAMA
  • #2 7511029
    mietekn
    Poziom 35  
    Typy "uint8_t" i "unsigned char" oznaczają dokładnie to samo więc nie jest to problem konwersji. Czy aby na pewno i na komputerze i w uC ustawione są te same parametry transmisji 8 bitów danych, prędkość transmisji itp ?
  • REKLAMA
  • #3 7511213
    owenpe
    Poziom 17  
    mietekn napisał:
    Typy "uint8_t" i "unsigned char" oznaczają dokładnie to samo więc nie jest to problem konwersji.


    Tak mi się też właśnie wydawało, ale nie byłem pewien :)

    mietekn napisał:
    Czy aby na pewno i na komputerze i w uC ustawione są te same parametry transmisji 8 bitów danych, prędkość transmisji itp ?


    Tak, mam. Dla potwierdzenia, od strony atmegi wygląda to tak:

    unsigned int ubrr;

    #define f_proc 11059200
    #define baud 57600
    #define MYUBRR f_proc/16/baud-1

    void rs232_init(unsigned int ubrr)
    {
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    UCSR0C = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSR0B = (1<<RXEN)|(1<<TXEN);
    }

    a od strony HyperTerminala tak:
    [ATmega128][C i VB] krzaki w komunikacji
  • #4 7511588
    Terminator
    Poziom 23  
    Chciałbym Ci przypomnieć że Atmega128 ma 2 uarty więc kod
    void wyslij(unsigned char data)
    {
    while((UCSR0A&(1<<UDRE)) == 0);
    UDR0 = data;
    }

    jest błędny. Rejestr UCSR0A nie ma takiego pola jak UDRE ale UDRE0 (strona 189 datasheet). Jeśli to nie pomoże, zamieść schemat elektryczny, może tam jest błąd.
  • #5 7511826
    kacperpk
    Poziom 14  
    tak napisana procedura wysyła wartość do komputera gdzie ta wartość przerabiana jest na znaki według tablicy ASCII, tej procedury nie możesz wykorzystywać do wysyłania liczb a jedynie cyfr od 0-9 ale wtedy jej wywołanie powinno wyglądać:
    wyslij(5+'0'); // wyświetli cyfrę 5
  • REKLAMA
  • #6 7512550
    owenpe
    Poziom 17  
    Terminator napisał:
    Chciałbym Ci przypomnieć że Atmega128 ma 2 uarty więc kod
    void wyslij(unsigned char data)
    {
    while((UCSR0A&(1<<UDRE)) == 0);
    UDR0 = data;
    }

    jest błędny. Rejestr UCSR0A nie ma takiego pola jak UDRE ale UDRE0 (strona 189 datasheet). Jeśli to nie pomoże, zamieść schemat elektryczny, może tam jest błąd.


    No faktycznie:) poprawiłem nazwy rejestrów, ale też nie działa:/

    Dodano po 7 [minuty]:

    kacperpk napisał:
    tak napisana procedura wysyła wartość do komputera gdzie ta wartość przerabiana jest na znaki według tablicy ASCII


    Ale gdzie ona jest przerabiana na ASCII? jeszcze przed wysłaniem w kontrolerze czy już po odebraniu na kompie? Docelowo zamiast Hyper Terminala chce korzystać z Visual Basica. Czy w takim razie to co odbiorę można przekonwertować na liczbę?

    Jak w takim razie mogę przesłać liczbę 8bitową?
  • REKLAMA
  • #7 7513161
    kacperpk
    Poziom 14  
    Hyper Terminal przerabia to co dostanie na znaki zgodnie z tablicą ASCII

    Wywołanie wyslij(5+'0'); przerabia poprawnie cyfry od 0-9 na kody ASCII tak by poprawnie zostały wyświetlone na terminalu jako odpowiednie cyfry.

    Aby wyświetlić unsigned char na terminalu możesz skorzystać z takiej funkcji:
    
    void wyslij_Value_as_Digits( unsigned char value )
    {
        unsigned char digit;
        
        digit = '0';
        while( value >= 100 )                // Still larger than 100 ?
        {
            digit++;                         // Increment first digit
            value -= 100;
        }
        
        wyslij( digit );                  // Send first digit
        
        digit = '0';
        while( value >= 10 )                 // Still larger than 10 ?
        {
            digit++;                         // Increment second digit
            value -= 10;
        }
        
        wyslij( digit );                  // Send second digit
        
        wyslij( '0' + value );            // Send third digit
    }

    Funkcja działa poprawnie dla liczb 8 bitowych bez znaku.

    Jednak do wysyłania danych do pisanego przez Ciebie programu na PC odradzam takiego kłopotliwego schematu przesyłania danych. Wtedy wysyłasz liczbę w taki sposób jak to robiłeś na samym początku bez przekodowywania na ASCII ale po stronie PC musisz ją odpowiednio interpretować. VB Ci nie pomogę niestety go nie znam.
  • #8 7513706
    Terminator
    Poziom 23  
    A nie prościej
    void wyslij(char *x)
    {
    	while( *x )
    	{
               while((UCSR0A&(1<<UDRE0)) == 0);
               UDR0 = *x;
               x++;
    	}
    }


    Jeśli chodzi o liczby to wysłanie liczby 0 wiąże się z dodaniem d niej wartości 48 (czy też inaczej '0') aby była w ASCII (jak już wspomnieli koledzy wyżej).

    a w main() piszesz
    int main()
    {
          InitUSART(...);
          ....
          wyslij("napis jakis");
          return 0;
    }
  • #9 7513949
    henxa
    Poziom 11  
    Proponuje Tobie użyć bray terminal ma on większe możliwości niż hyper terminal z Windowsa. Możesz w nim podglądać wysyłane znaki jako liczby hex-a oraz wysyłać za jego pomocą ciągi znaków. Ma również wiele innych funkcji które się przydają podczas testowania takiej komunikacji.
    bray terminal
  • #10 7518300
    owenpe
    Poziom 17  
    Cały weekend nie miałem możliwości korzystania z neta i dlatego sam coś wymyśliłem:) Rozkładam liczbę na poszczególne bity i w zależności czy jest to 1 czy 0, to wysyłam odpowiednia wartość kodu ASCII. Wygląda to tak:

    void wyslij(unsigned char data)
    {
    while((UCSR0A&(1<<UDRE0)) == 0);
    UDR0 = data;
    }

    void chartobit(uint8_t z)
    {
    int i, j;
    for(i=7;i>=0;i--)
    {
    j=z;
    j=(j>>i)&0x01;
    if(j==0x00)wyslij(0x30);
    if(j==0x01)wyslij(0x31);
    }
    }

    Działa tak jak chciałem:) Po zastąpieniu Hyper Terminala Visual Basic-em odebraną wartość wstawiam w TextBox-a. Dzięki temu mam od razu wartość binarną w polu tekstowym :)
REKLAMA