Hallo zusammen,
ich habe mal wieder zwei kleine Probleme.
Prozessor: ATMEGA328P
Eclipse + AVRGCC
Ich verwende die Routine von Peter
Beitrag "AVR-GCC: UART mit FIFO" um eine Kommunikation
über RS485 mit mehreren anderen Platinen aufzubauen.
Damit die Empfänger wissen, an welcher Stelle die Nachricht beginnt,
verwende ich 9n1 als UART-Protokoll.
Die Adresse des Slave wird mit gesetztem 9Bit versendet, s.h. Beispiel.
1 | ISR (USART_TX_vect)
|
2 | {
|
3 | if( tx_in == tx_out ) // nothing to sent
|
4 | {
|
5 | UCSR0B &= ~( 1 << TXCIE0 ); // disable TX interrupt
|
6 | return;
|
7 | }
|
8 | UCSR0B &= ~( 1 << TXB80 );
|
9 | if ( tx_buff[tx_out] & 0x0100 )
|
10 | {
|
11 | UCSR0B |= ( 1 << TXB80 );
|
12 | }
|
13 | UDR0 = tx_buff[tx_out];
|
14 | ROLLOVER( tx_out, TX0_SIZE );
|
15 | }
|
Aber leider kommt sie beim Slave mit nicht gesetztem 9Bit an.
1 | ISR (USART_RX_vect)
|
2 | {
|
3 | uint8_t i = rx_in;
|
4 | uint8_t data, res;
|
5 |
|
6 | ROLLOVER( i, RX0_SIZE );
|
7 | if( i == rx_out ) // buffer overflow
|
8 | {
|
9 | UCSR0B &= ~( 1 << RXCIE0 ); // disable RX interrupt
|
10 | return;
|
11 | }
|
12 |
|
13 | /* Get 9th bit, then data from buffer */
|
14 | res = UCSR0B;
|
15 | if ( res & ( 1 << RXB80 ) )
|
16 | {
|
17 | data = UDR0;
|
18 | ATOMIC_BLOCK(ATOMIC_FORCEON)
|
19 | {
|
20 | rx_buff[rx_in] = ( data | 0x0100 );
|
21 | }
|
22 | }
|
23 | else
|
24 | {
|
25 | data = UDR0;
|
26 | rx_buff[rx_in] = data;
|
27 | }
|
28 | rx_in = i;
|
29 | }
|
Desweiteren funktioniert das Versenden nur dann, wenn ich nachdem
setzten des Interrupt-Flags TXCIE0 auch noch UDR0 = 0 sende.
Ich habe den gesamten Code mal soweit zusammengestrichen, dass das
Problem nachvollzogen werden kann.
Ich hoffe es kann mir jemand den Fehler zeigen, weil ich da schon ne
ganze Weile dran sitze.
Gruß
Frank