RS485 - Kommunikation

OP #896592
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
Gast #903604
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:
1
volatile uint8_t  cluster_address;
2
volatile uint8_t  send_counter;
3
volatile uint8_t  send_numbers;
4
volatile uint8_t  send_buffer[256];
5
volatile uint8_t  rx_data_buffer[256];
6
volatile uint8_t  rx_data_valid[256];
7
volatile uint8_t  rx_state;
8
volatile uint8_t  rx_data_counter;
9
volatile uint8_t  rx_data_sum;
Initialisierung:
1
void  init_comm ( void )
2
{
3
  //-- port directions --------------------------------------------
4
  DDRD  |=  (1<<PD4) | (1<<PD3);         // recv/send pin to output
5
  DDRB  |=  (1<<PB4) | (1<<PB6);         // bus send/recvd leds
6
  PORTB  |=  (1<<PB4) | (1<<PB6);         // switch off send/revc-led
7
  //-- uart registers ---------------------------------------------
8
  UBRR1H  =  0;
9
  UBRR1L  =  25;                         // 38.4kbaud @ 16MHz
10
  UCSR1A  =  (1<<MPCM);
11
  UCSR1B  =  (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) | (1<<UCSZ2);
12
  UCSR1C  =  (3<<UCSZ0);                 // 9bit mode
13
  //-- timer for timing surveillance ------------------------------
14
  TIMSK   |= (1<<TOIE0);
Funktion zum Senden von Frames:
1
void  send_packet  (  uint8_t  destination,
2
                      uint8_t  counts,
3
                      uint8_t  *data        )
4
{
5
  //-- local var's ------------------------------------------------
6
  uint8_t  loop     = 0x00;
7
  uint8_t  checksum = 0x00;
8
  //-- destination address ----------------------------------------
9
  send_buffer[ 0x00 ] =  destination;
10
  checksum            += destination;
11
  //-- source address ---------------------------------------------
12
  send_buffer[ 0x01 ] =  cluster_address;
13
  checksum            += cluster_address;
14
  //-- number of data bytes ---------------------------------------
15
  send_buffer[ 0x02 ] =  ( counts + 0x01 );
16
  checksum            += ( counts + 0x01 );
17
  //--wait until last transm finished -----------------------------
18
  while  ( send_counter != send_numbers );
19
  //-- fill data into send-buffer ---------------------------------
20
  for  ( loop = 0x00; loop <= counts; loop++ )
21
  {
22
    send_buffer[loop + 0x03] =  *data;
23
    checksum                 += *data;
24
    data++;
25
  }
26
  //-- calculate checksum -----------------------------------------
27
  send_buffer[loop + 0x03] = ( ~checksum + 1 );
28
  //-- preload values to sending ----------------------------------
29
  send_numbers = counts + 0x04;
30
  send_counter = 0x00;
31
  //-- state led: send data ---------------------------------------
32
  PORTB &= ~(1<<PB6);                    // switch on send-led
33
  PORTD |= (1<<PD4);                     // switch to bus send
34
  //-- enable transmitter int -------------------------------------
35
  UCSR1B &= ~(1<<RXCIE);                 // switch off receiver
36
  UCSR1B |= (1<<UDRIE);
37
}
38
ISR ( USART1_UDRE_vect )
39
{
40
  //-- wait until UDR is empty ------------------------------------
41
  while ( !( UCSR1A & (1<<UDRE)) );
42
  //-- first byte: mark as address --------------------------------
43
  if ( send_counter == 0x00 )
44
  {
45
    UCSR1B  |= (1<<TXB8);
46
  }
47
  else
48
  {
49
    UCSR1B  &=  ~(1<<TXB8);
50
  }
51
  UDR1 = send_buffer[send_counter];
52
  //-- still char's to send? --------------------------------------
53
  if  ( send_counter == send_numbers )
54
  {
55
    UCSR1B  &= ~(1<<UDRIE);
56
    UCSR1B  |=  (1<<TXCIE);
57
  }
58
  else
59
  {
60
    send_counter++;  
61
  }
62
}
63
ISR ( USART1_TX_vect )
64
{
65
  //-- switch off transmitter & back to recev ---------------------
66
  PORTB |=  (1<<PB6);                    // switch off send-led
67
  PORTD &= ~(1<<PD4);                  // switch to bus recv
68
  UCSR1B |=  (1<<RXCIE);                 // switch on receiver
69
  UCSR1B &= ~(1<<TXCIE);                 // switch off transmitter
70
}
Empfang von Frames
1
ISR ( USART1_RX_vect )
2
{
3
  uint8_t  temp;
4
  //-- fetch receiced data & store --------------------------------
5
  temp = UDR1;
6
  switch ( rx_state )
7
  {
8
  //-- address received -------------------------------------------
9
  case ( rx_state_idle ):
10
    //-- address match? ---------------------  
11
    if (    ( temp == cluster_address )
12
         || ( temp == 0xFF            )  )  // broadcast address
13
    {
14
      //-- start timing surveilance -------
15
      TIFR |= (1<<TOV0);                    // clear overflow flag
16
      TCNT0 = 0x00;                         // preload timer
17
      TCCR0 = (3<<CS00);                    // clk/32
18
      //-- data receive -------------------
19
      UCSR1A &= ~(1<<MPCM);                 // switch off mcpm
20
      //-- data counter & storage ---------
21
      rx_data_counter = 0x00;
22
      rx_data_sum = temp;
23
      rx_data_buffer[rx_data_counter] = temp;
24
      //-- state led: receive data --------
25
      PORTB &= ~(1<<PB4);                   // switch on recv-led
26
      //-- next state in state maschine ---
27
      rx_state = rx_state_receving;
28
    }
29
    break;
30
  //-- data received ------------------------------------------
31
  case ( rx_state_receving ):
32
    //-- restart timing surveilance ---------
33
    TIFR  |= (1<<TOV0);                      // clear overflow flag
34
    TCNT0 =  0x00;                           // preload timer
35
    TCCR0 =  (3<<CS00);                      // clk/32
36
    //-- data counter & storage -------------
37
    if ( rx_data_counter == 255 )            // packet overlength
38
    {
39
      //-- stopp timing surveilance -------
40
      TCCR0 = 0x00;
41
      //-- state led: receive data --------
42
      PORTB |= (1<<PB4);                     // switch off recv-led
43
      //-- prepare for new address --------
44
      UCSR1A = (1<<MPCM);                    // switch on mcpm
45
      rx_state = rx_state_idle;
46
    }
47
    else
48
    {
49
      rx_data_buffer[++rx_data_counter]  = temp;
50
      rx_data_sum += temp;
51
    }
52
    break;
53
  }
54
}
55
ISR ( TIMER0_OVF_vect )
56
{
57
  uint8_t  loop_counter = 0x00;
58
  //-- stopp timing surveilance -----------------------------------
59
  TCCR0 = 0x00;
60
  //-- state led: receive data ------------------------------------
61
  PORTB |=  (1<<PB4);                    // switch off recv-led
62
  //-- prepare for new address ------------------------------------
63
  UCSR1A   =  (1<<MPCM);                 // switch on mcpm
64
  rx_state =  rx_state_idle;             // reset state maschine
65
  //-- test recvd data for errors ---------------------------------
66
  if (    ( rx_data_buffer[2] + 3 == rx_data_counter )  // no data missing?,
67
       && ( (uint8_t) rx_data_sum == 0x00            ) )// checksum ok
68
  {
69
    //-- do public for application ----------
70
    for ( loop_counter = 0x00; loop_counter != rx_data_counter; loop_counter++)
71
    {
72
      rx_data_valid[loop_counter] = rx_data_buffer[loop_counter];
73
    }
74
  }
75
}

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.