Forum: Haus & Smart Home RS485 - Kommunikation


von Franz M. (fmessner)


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

von Matthias L. (Gast)


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
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.