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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.