mikrocontroller.net

Forum: Haus & Smart Home RS485 - Kommunikation


Autor: Franz Messner (fmessner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Bin neu hier im Forum!

hat jemand von Euch einn Sourcecode in C für die Umsetzung einer 
Ansteuerung
Master - Multislave Lösung zwischen AVR Controller?

Ich möchte mir anhand eines Beispiels die Umsetzung von RS485 ansehen.

Leider habe ich hier im Forum noch nichts gefunden an Beispielen..

Vielen dank für Eure Hilfe
Charly

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mal was mit mehreren AVR aufgebaut.
Die Komm. erfolgt im Multi-Prozessor-Comm.-Mode mit RS422.
Weiß nicht ob es dir was nützt:

Variablen:
volatile uint8_t  cluster_address;
volatile uint8_t  send_counter;
volatile uint8_t  send_numbers;
volatile uint8_t  send_buffer[256];
volatile uint8_t  rx_data_buffer[256];
volatile uint8_t  rx_data_valid[256];
volatile uint8_t  rx_state;
volatile uint8_t  rx_data_counter;
volatile uint8_t  rx_data_sum;
Initialisierung:
void  init_comm ( void )
{
  //-- port directions --------------------------------------------
  DDRD  |=  (1<<PD4) | (1<<PD3);         // recv/send pin to output
  DDRB  |=  (1<<PB4) | (1<<PB6);         // bus send/recvd leds
  PORTB  |=  (1<<PB4) | (1<<PB6);         // switch off send/revc-led
  //-- uart registers ---------------------------------------------
  UBRR1H  =  0;
  UBRR1L  =  25;                         // 38.4kbaud @ 16MHz
  UCSR1A  =  (1<<MPCM);
  UCSR1B  =  (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);
  UCSR1C  =  (3<<UCSZ0);                 // 9bit mode
  //-- timer for timing surveillance ------------------------------
  TIMSK   |= (1<<TOIE0);  
Funktion zum Senden von Frames:
void  send_packet  (  uint8_t  destination,
                      uint8_t  counts,
                      uint8_t  *data        )
{
  //-- local var's ------------------------------------------------
  uint8_t  loop     = 0x00;
  uint8_t  checksum = 0x00;
  //-- destination address ----------------------------------------
  send_buffer[ 0x00 ] =  destination;
  checksum            += destination;
  //-- source address ---------------------------------------------
  send_buffer[ 0x01 ] =  cluster_address;
  checksum            += cluster_address;
  //-- number of data bytes ---------------------------------------
  send_buffer[ 0x02 ] =  ( counts + 0x01 );
  checksum            += ( counts + 0x01 );
  //--wait until last transm finished -----------------------------
  while  ( send_counter != send_numbers );
  //-- fill data into send-buffer ---------------------------------
  for  ( loop = 0x00; loop <= counts; loop++ )
  {
    send_buffer[loop + 0x03] =  *data;
    checksum                 += *data;
    data++;
  }
  //-- calculate checksum -----------------------------------------
  send_buffer[loop + 0x03] = ( ~checksum + 1 );
  //-- preload values to sending ----------------------------------
  send_numbers = counts + 0x04;
  send_counter = 0x00;
  //-- state led: send data ---------------------------------------
  PORTB &= ~(1<<PB6);                    // switch on send-led
  PORTD |= (1<<PD4);                     // switch to bus send
  //-- enable transmitter int -------------------------------------
  UCSR1B &= ~(1<<RXCIE);                 // switch off receiver
  UCSR1B |= (1<<UDRIE);
}
ISR ( USART1_UDRE_vect )
{
  //-- wait until UDR is empty ------------------------------------
  while ( !( UCSR1A & (1<<UDRE)) );
  //-- first byte: mark as address --------------------------------
  if ( send_counter == 0x00 )
  {
    UCSR1B  |= (1<<TXB8);
  }
  else
  {
    UCSR1B  &=  ~(1<<TXB8);
  }
  UDR1 = send_buffer[send_counter];
  //-- still char's to send? --------------------------------------
  if  ( send_counter == send_numbers )
  {
    UCSR1B  &= ~(1<<UDRIE);
    UCSR1B  |=  (1<<TXCIE);
  }
  else
  {
    send_counter++;  
  }
}
ISR ( USART1_TX_vect )
{
  //-- switch off transmitter & back to recev ---------------------
  PORTB |=  (1<<PB6);                    // switch off send-led
  PORTD &= ~(1<<PD4);                  // switch to bus recv
  UCSR1B |=  (1<<RXCIE);                 // switch on receiver
  UCSR1B &= ~(1<<TXCIE);                 // switch off transmitter
}
Empfang von Frames
ISR ( USART1_RX_vect )
{
  uint8_t  temp;
  //-- fetch receiced data & store --------------------------------
  temp = UDR1;
  switch ( rx_state )
  {
  //-- address received -------------------------------------------
  case ( rx_state_idle ):
    //-- address match? ---------------------  
    if (    ( temp == cluster_address )
         || ( temp == 0xFF            )  )  // broadcast address
    {
      //-- start timing surveilance -------
      TIFR |= (1<<TOV0);                    // clear overflow flag
      TCNT0 = 0x00;                         // preload timer
      TCCR0 = (3<<CS00);                    // clk/32
      //-- data receive -------------------
      UCSR1A &= ~(1<<MPCM);                 // switch off mcpm
      //-- data counter & storage ---------
      rx_data_counter = 0x00;
      rx_data_sum = temp;
      rx_data_buffer[rx_data_counter] = temp;
      //-- state led: receive data --------
      PORTB &= ~(1<<PB4);                   // switch on recv-led
      //-- next state in state maschine ---
      rx_state = rx_state_receving;
    }
    break;
  //-- data received ------------------------------------------
  case ( rx_state_receving ):
    //-- restart timing surveilance ---------
    TIFR  |= (1<<TOV0);                      // clear overflow flag
    TCNT0 =  0x00;                           // preload timer
    TCCR0 =  (3<<CS00);                      // clk/32
    //-- data counter & storage -------------
    if ( rx_data_counter == 255 )            // packet overlength
    {
      //-- stopp timing surveilance -------
      TCCR0 = 0x00;
      //-- state led: receive data --------
      PORTB |= (1<<PB4);                     // switch off recv-led
      //-- prepare for new address --------
      UCSR1A = (1<<MPCM);                    // switch on mcpm
      rx_state = rx_state_idle;
    }
    else
    {
      rx_data_buffer[++rx_data_counter]  = temp;
      rx_data_sum += temp;
    }
    break;
  }
}
ISR ( TIMER0_OVF_vect )
{
  uint8_t  loop_counter = 0x00;
  //-- stopp timing surveilance -----------------------------------
  TCCR0 = 0x00;
  //-- state led: receive data ------------------------------------
  PORTB |=  (1<<PB4);                    // switch off recv-led
  //-- prepare for new address ------------------------------------
  UCSR1A   =  (1<<MPCM);                 // switch on mcpm
  rx_state =  rx_state_idle;             // reset state maschine
  //-- test recvd data for errors ---------------------------------
  if (    ( rx_data_buffer[2] + 3 == rx_data_counter )  // no data missing?,
       && ( (uint8_t) rx_data_sum == 0x00            ) )// checksum ok
  {
    //-- do public for application ----------
    for ( loop_counter = 0x00; loop_counter != rx_data_counter; loop_counter++)
    {
      rx_data_valid[loop_counter] = rx_data_buffer[loop_counter];
    }
  }
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.