Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

RS485 sterowany przez transoptory

mgradzki 08 Mar 2009 11:47 1413 0
  • #1
    mgradzki
    Poziom 16  
    Witam, mam problem, nad którym spędziłem całą noc i im dłużej siedzę tym mniej wiem.

    Mam układ, w którym MAX485 jest odseparowany od ATMEGA8 przez transoptory. MAX485 ma zasilanie (na schemacie zaznaczona jako) VCC_M i GND_M, procesor VCC i GND, rezystory po 510R. Port PD2 służy do przełączania MAXa485 pomiędzy nadawaniem i odbiorem.

    RS485 sterowany przez transoptory


    Problem jest w tym, że kiedy wyślę jakiś bajt z procesora generuje mi się przerwanie od RX - procesor próbuje odebrać bajt, którego nie ma, więc odbiera wartość 0x00. Przypuszczam, że jakieś opóźnienie na transoptorach powoduje, że wykrywany jest bit startu na linii RX.

    Oglądałem przebiegi na oscyloskopie - przesunięcia czasowe pomiędzy przebiegami po obu stronach transoptorów wynoszą pojedyncze mikrosekundy.

    Program uprościłem na ile się dało:
    Code:

    #include <avr/io.h>
    #include <math.h>
    #include <avr/interrupt.h>
    #define F_CPU 1000000
    #include <util/delay.h>

    #define PARITY_NONE 0
    #define PARITY_EVEN (1<<UPM1) 
    #define PARITY_ODD ((1<<UPM1)|(1<<UPM0))
    #define STOP_BITS_1 0
    #define STOP_BITS_2 (1<<USBS)
    #define DATA_BITS_5 0
    #define DATA_BITS_6 (1<<UCSZ0)
    #define DATA_BITS_7 (1<<UCSZ1)
    #define DATA_BITS_8 ((1<<UCSZ1)|(1<<UCSZ0))
    #define DATA_BITS_9 ((1<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0))



    void waitms(unsigned int ms)
    {
    unsigned int i;
    for (i=0;i<ms;i++)
       {
     _delay_ms(1);
       }
    }


    void UART_SendChar(char s) {
       PORTD|=_BV(2);
       waitms(1);
       while ( !( UCSRA & (1<<UDRE)) );
       UDR=s;
       while (bit_is_clear(UCSRA,TXC));
       UCSRA|=_BV(TXC);
       PORTD&=~_BV(2);

     
     
    void UART_Init( void )
      {
       UBRRH = 0x00;
       UBRRL = 0x0c;
       UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN);
       UCSRC = (1 << URSEL) | DATA_BITS_8 | PARITY_EVEN | STOP_BITS_1;
      }
     


    SIGNAL (SIG_UART_RECV)
      {

      char rcv=UDR;
      UART_SendChar(66);
      PORTD^=_BV(5);
      }
     


    int main()
    {
    DDRB=0xff;
    DDRC=0xff; 
    DDRD=0b11111111; 
    PORTD=0b11111011;
    waitms(200);
    UART_Init();
    sei();
       
      while(1)
      {

      }
       
    }

    i po otrzymaniu jakiegoś bajtu zaczyna bez przerwy wysyłać ASCII 66.

    Kiedyś robiłem jakiś podobny układ i nie miałem z tym problemu z czymś takim.

    Może ktoś wie, o co chodzi, bo mi się już pomysły skończyły (kilka godzin temu).

    Pozdrawiam



    EDIT:
    Zaczyna się klarować
    Z tabel stanów lgicznych wynika, że jeśli na wejście !RE podamy stan wysoki to wyjście odbiornika przechodzi w stan wysokiej impedancji - więc nie wysterowuje diody trsnsoptora i na procesor wystawiany jest stan niski.
    Sprubuję to jakoś podciągnąć do zasilania, żeby w stanie wysokiej impedsncji nadajnika na procesor podawany był stan wysoki odpowiadający wolnej linii.

    EDIT 2:
    ZGADŁEM
    Po podciągnięciu wyjścia odbiornika do zasilania zadziałało !!!