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

[AVR][C] handshaking CTS/RTS

stanboleyn 10 Paź 2008 07:58 4783 6
REKLAMA
  • #1 5617319
    stanboleyn
    Poziom 10  
    Witam,

    Planuję podłączyć moją Atmegę do PC poprzez RS-232 wykorzystując sprzętowy USART. Zamierzam wykorzystać linie CTS/RTS do wstrzymywania wysyłania danych z PC (w momencie gdy bufor odbiorczy będzie pełny CTS na 0). Schemat podłączenia wygląda tak:

    [AVR][C] handshaking CTS/RTS

    Linie Tx Rx wiadomo gdzie podpiąć, ale co z RTS, CTS ? czy któreś piny Atmegi są dedykowane do tych sygnałów podobnie jak linie danych?

    pozdrawiam, stanboleyn
  • REKLAMA
  • REKLAMA
  • #3 5617368
    stanboleyn
    Poziom 10  
    Czyli muszę ustawić jeden z dowolnych pinów jako wejście dla RTS oraz jeden jako wyjście dla CTS ? Hmm mam już Atmege więć PIC odpada :)
  • REKLAMA
  • #5 5617392
    stanboleyn
    Poziom 10  
    hmm tylko ustawienie jednego z bitów poprzez

    DDRX = _BV(x)

    ustawi pin x rejestru X jako wyjście (CTS) czyli będzie on miał stan "1" ... a jak w takim razie zatrzymać transmisję? zmienić x na wyjście? wtedy będzie 0 ? czy są inne metody na zmianę stanu danego pinu?

    przepraszam, jeżeli pytam o rzeczy trywialne, ale dopiero się "wdrażam" :)

    Dodano po 2 [godziny] 14 [minuty]:

    od wartości wpisanej w który rejestr zależy fizyczny stan pinu Atmegi?

    aby zatrzymać transmisję z PC muszę ustawić pin Atmegi podpięty do linii CTS na 0, aby wznowić na 1

    z tego co rozumiem DDRx - rejestr kierunku danych czyli:

    ustawienie odpowiedniego bitu - wyjście
    skasowanie odpowiedniego bitu - wejście

    następnie rejestr PORTx - rejestr zapisu :

    wpisanie odpowiedniej wartości ustawia poszczególne piny na 1 lub 0

    i rejestr PINx - rejestr odczytu:

    wartość tego rejestru daje info o tym jakie wartości mają poszczególne piny

    czy dobrze wszystko rozumiem?

    Zakładając, że linia CTS jest na pinie PC1 i odczyt "1" z pinu PC2 ma zatrzymać transmisję, a odczyt "0" z PC2 ma ją wznowić, to:

    
    #include <avr/io.h> 
    
    int main (void) 
    { 
    
       DDRC &= ~_BV(PC1);     // pin PC1 jako wyjście linii CTS
       
       DDRC |= _BV(PC2);      // pin PC2 jako wejście
        
       PORTC |= _BV(PC1);     // stan początkowy linii CTS
        
       while (1) 
        
       { 
        
       if (PINC & (1<< PC2)) PORTC &= ~_BV(PC1); 
       else PORTC |= _BV(PC1); 
    
    
       } 
    } 
    


    dobrze kombinuje?
  • REKLAMA
  • #7 5617803
    stanboleyn
    Poziom 10  
    czyli teraz kod:

    
    #include <avr/io.h> 
    
    int main (void) 
    { 
    
       DDRC |= _BV(PC1);     // pin PC1 jako wyjście linii CTS
       
       DDRC &= ~_BV(PC2);      // pin PC2 jako wejście
        
       PORTC |= _BV(PC1);     // stan początkowy linii CTS
        
       while (1) 
        
       { 
        
       if (PINC & (1<< PC2)) PORTC &= ~_BV(PC1); 
       else PORTC |= _BV(PC1); 
    
       } 
    } 
    


    jest ok?

    Dodano po 20 [minuty]:

    bazując na poprzednim, wystukałem kod mający odbierać z PC dane a następnie odsyłać je spowrotem.

    Ustawienia: 9600bps, 8 bitów danych, brak parzystości, kontrola przepływu RTS/CTS

    Sprawdze jak wrócę do domu, mam nadzieję all ok :)

    
    #include <avr/io.h>
    
    
    #define USART_BAUDRATE 9600
    #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    
    
    int main (void)
    {
       char dane;
       
       DDRC |= _BV(PC1);       // pin PC1 jako wyjście linii CTS
       
       DDRC &= ~_BV(PC2);      // pin PC2 jako wejście linii RTS
        
    
       UCSR1B |= (1 << RXEN1) | (1 << TXEN1);   	 
       UCSR1C |= (1 << URSEL1) | (1 << UCSZ10) | (1 << UCSZ11); 
    
       UBRR1L = BAUD_PRESCALE; 
       UBRR1H = (BAUD_PRESCALE >>8 ) ; 
    
       for (;;) 
       {
       
    	  if (PINC & (1<< PC2)) PORTC &= ~_BV(PC1);   // Sterowanie wysyłaniem z PC
          else PORTC |= _BV(PC1); 
       
          while ((UCSR1A & (1 << RXC1)) == 0) {};     // Odbiór z PC
          dane = UDR1; 
    
          while ((UCSR1A & (1 << UDRE1)) == 0) {};    // Wysyłanie do PC
          UDR1 = dane; 
       
       }   
    } 
    
REKLAMA