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

Zablokować odbiór czy przerwanie (Atmega16)

Spor_m 09 Gru 2009 22:58 1338 17
REKLAMA
  • #1 7368413
    Spor_m
    Poziom 10  
    Witam,

    Podłączyłem port RX i TX USART'a w jedną linie - czyli nadaję i odbieram za pomocą jednej lini (1-Wire)

    Teraz proszę o podpowiedz, używam przerwania i bufora 8 bajtowego do odbioru i nadawania i teraz nie wiem co zablokować by wysyłając nie dostać echa z RX'a?

    Próbowałem wyłączyć przed wysłaniem możliwość odbioru RXEN i wysłać, ale gdy włączyłem RXEN i chciałem coś odebrać w buforze były już śmieci.

    Przerwanie przy RX służy do tego by informować, że w UDR jest dana do odebrania, ale ja jej nie chcę i gdy włączę przerwanie dostaję daną zmagazynowaną w UDR :-(.

    Jak sprawnie przełączać odbiór i nadawanie bez konieczności ingerowania w zawartość bufora i jego licznika?

    Robiłem tak:
    0. przerwania włączone
    1. UCSRB ustawiony na tylko nadawanie
    2. wysyłam daną
    3. UCSRB przełączam na tylko odbiór
    4. czekam na daną po przez przerwanie
    i mam śmieci.

    Ps.
    Mogę tak:
          
    UCSRB=0xC8; // Tylko nadawanie z przerwaniami TX i RX
    while (count < 5) putchar(send[count++]);
    UCSRB=0xD0; // Tylko odbiór z przerwaniami TX i RX
    tmp = getchar();
    


    Po tym dostaję w tmp jeden bajt śmieci i czeka prawidłowo na kolejne dane z 1-wire.
  • REKLAMA
  • Pomocny post
    #2 7369041
    chudybyk
    Poziom 31  
    Witam!
    Wyłączenie odbiornika jednocześnie czyści bufor odbiorczy, więc jest to dobra droga.
    Za szybko włączasz odbiornik. Wysłanie ostatniego bajtu do bufora nadawczego powoduje, że program leci dalej (ale jednocześnie trwa wysyłanie bajtu z bufora) w tym czasie włączasz odbiór i dostajesz kawałek nadawanego bajtu.
    Żeby pozbyć się problemu, musisz po pętli wysyłającej dorzucić czekanie na opróżnienie bufora nadawczego - flaga UDRE.
    Pozdrawiam!
  • #3 7369210
    Spor_m
    Poziom 10  
    Dziękuję !! Niby takie oczywiste,a nie pomyślałem o tym ;-).

    Hmm nadal mi coś wraca.

    Napisałem krótki programik by zobaczyć co się dzieje - bez przerwań.

    
    void USART_Transmit( unsigned char data )
    {
    while ( !( UCSRA & (1<<UDRE)) );
    UDR = data;
    while ( ( UCSRA & (1<<TXC)) ); //<- sprawdziłem na dodatek czy wysłane
    }
    
    unsigned char USART_Receive( void )
    {
    while ( !(UCSRA & (1<<RXC)) );
    return UDR;
    }
    
    ....
    
    UCSRB = 0x08;
    USART_Transmit(0x25);
    UCSRB = 0x10;
    tmp = USART_Receive();
    
    

    W temp mam daną tą co wysłałem, a czasem jakiś śmieć.
    Proszę o pomoc bo tego już nie rozumiem :-/.
  • #4 7369721
    _Robak_
    Poziom 33  
    Moze po prostu odbierz dana zaraz po wyslaniu? Ja tak robie w takim przypadku i dziala perfekcyjnie :)
  • REKLAMA
  • #5 7369736
    Spor_m
    Poziom 10  
    Nie mogę tak bo czekam na echo od innego urządzenia. Jeśli echa nie dostane to wiem, że jest brak połączenia. Dlatego nie mogę dostawać takich śmieci :-/
  • #6 7369792
    chudybyk
    Poziom 31  
    Ale nie czekasz na pusty bufor przy odbieraniu, a tylko przy nadawaniu.
    Skopiuj "while ( !( UCSRA & (1<<UDRE)) ); " przed "tmp = USART_Receive();"
  • #7 7370016
    Spor_m
    Poziom 10  
    
    void USART_Transmit( unsigned char data )
    {
    while ( !( UCSRA & (1<<UDRE)) );
    UDR = data;
    while ( UCSRA & (1<<TXC) );
    }
    
    unsigned char USART_Receive( void )
    {
    while ( !( UCSRA & (1<<UDRE)) ); //<- Proszę czekam też na pusty bufor
    while ( !(UCSRA & (1<<RXC)) );
    return UDR;
    }
    
    ....
         while (count < 5) 
          {
            UCSRB = 0x08;
            USART_Transmit(send[count]);
            UCSRB = 0x10;
            tmp[count++] = USART_Receive();
          }
    


    Dostaję zwrot :-/.
  • #8 7370031
    kamyczek
    Poziom 38  
    Może napiszesz dokładniej do czego chcesz użyć takiej komunikacji ? i w czym właściwie przeszkadza to echo z nadajnika ?
  • REKLAMA
  • #9 7370067
    _Robak_
    Poziom 33  
    Oczywiscie zakladam ze przez tyle godzin zdazyles przeczytac datasheeta i wiesz ze jesli bufor jest pusty to UDRE jest 1 ?
  • #10 7370068
    Spor_m
    Poziom 10  
    :-) Dobrze.

    Więc za pomocą AVR'a chcę połączyć się z ECU autka.

    Tam jest transmisja za pomocą 1-wire.

    AVR wysyła najpierw sygnał (przy fastinit ISO 14230-2) bez uruchomienia USART'a
    _________............._____...........____..........____
    ..................\_____/...........\/\/\/\/.........\/\/\/\/
    300ms 25ms 25ms packet response

    (kropki to spacje ;-) post nie obsługuję spacji)

    gdzie 0-12V 1-0V.

    Teraz muszę wysłać "pobudkę" dla ECU najpierw TX'em jako zwykłym portem i przełączyć się na 10400 i wysłać pakiet danych 5bajtów, po tym dostaję echo tego pakietu i odpowiedź ecu.

    U mnie problem jest taki, że po każdym wysłaniu bajtu mam zwrot bajtu,ale już dziwnego :-/. Nie jestem podłączony do ECU, a tylko do oscyla i próbuję rozgryźć co i jak.

    Dodano po 2 [minuty]:

    _Robak_ napisał:
    wiesz ze jesli bufor jest pusty to UDRE jest 1 ?


    Dlatego
    while ( !( UCSRA & (1<<UDRE)) ); 
  • #11 7370100
    chudybyk
    Poziom 31  
    Pomyłka.
    Sprawdzać trzeba nie UDRE, ale TXC. W dodatku trzeba go kasować programowo, jeśli nie używasz przerwania Od TXC.
    Spróbuj tak:
    unsigned char USART_Receive( void )
    {
    while ( !( UCSRA & (1<<TXC)) );
    UCSRA = 0x40;
    while ( !(UCSRA & (1<<RXC)) );
    return UDR;
    }
  • #12 7370149
    Spor_m
    Poziom 10  
    Niestety teraz wysypały się przypadkowe bajty :-/
  • #13 7370172
    _Robak_
    Poziom 33  
    Wszystkie pieknie ladnie, ale wyslanie chara przy 9600bps zajmuje 1ms. Wiec nawet jak juz ostatni bajt opusci bufor, to jeszcze przez 1ms jest wysylany. Proponuje zebys pokombinowal troszke sam, a nie co kompilacje walil na forum ;)
  • #14 7370221
    Spor_m
    Poziom 10  
    No to po co są te flagi w procku? Jest flaga co mówi o tym, że zostało wysłane :-) więc? :-)
  • #15 7370542
    kamyczek
    Poziom 38  
    TXC informuje że transmisja jest kompletna i nie ma nic do wysłania ale w protokole KWP-2000 jest kilka zasadzek i zależności czasowych. osobiście pisałem taką transmisję ale w asemblerze.
  • REKLAMA
  • #16 7372669
    Spor_m
    Poziom 10  
    Ok poradziłem sobie.

    Teraz pytanie jak przerobić z ARM'a na AVR:

    
    //ustawia Break, TX = 0
    U1LCR |= 0x40;
    
    //ustawia "1" na 300ms
    U1LCR = (UART_8N1 & ~0x40);
    delayMs(300);
    
    // ustawia Break, TX = 0.
    U1LCR |= 0x40;
    delayMs(25);
    
    // TX = 1 na 25ms
    U1LCR = (UART_8N1 & ~0x40);
    delayMs(25);
    


    W AVR nie widziałem BREAK :-/

    Jak tego dokonać na AVR?
  • Pomocny post
    #17 7372727
    kamyczek
    Poziom 38  
    W avr ni ma break ;) masz całkowitą rację kolego trzeba go zrobić samodzielnie ;)
  • #18 7373856
    Spor_m
    Poziom 10  
    EDIT :-)

    Już po wszystkim i śmiga - Podziękowania dla Kamyczka :D
REKLAMA