Hallo zusammen,
ich habe einen Schaltungsaufbau auf dem Steckbrett mit einem Atmega328P,
der diesem entspricht:
http://www.mikrocontroller.net/wikifiles/2/2f/Btm222_sch.png
Das BTM-222 funktioniert prinzipiell - d.h. ich kann eine
Bluetooth-Verbindung zu dem Modul aufbauen. Die an das Modul
angeschlossenen LED's "zeigen" den Verbindungsaufbau - Dann kann ich
ebenso erfolgreich Bytes an das Modul schicken - Das Modul gibt dieses
Byte dann auch richtig auf der Tx-Leitung weiter bis zum PD0/Rx-Pin vom
Atmega328 - dies konnte ich mit einem Logic-Analyzer nachprüfen - s.
Screenshot "Rx.png" ("Rx direct" ist hier direkt am Pin vom BTM-222 und
"Rx Atmel" ist direkt am PD0/Rx-Pin vom Atmega).
Allerdings scheint der Atmega328 dies nicht zu erkennen -
1 | received = USART_Receive();
|
wartet für immer...Die Receive-Funktion sieht wie folgt aus:
1 | unsigned char USART_Receive( void )
|
2 | {
|
3 | //Wait for data to be received
|
4 | while ( !(UCSR0A & (1<<RXC0)) )
|
5 | ;
|
6 | //Get and return received data from buffer
|
7 | return UDR0;
|
8 | }
|
Des weiteren funktioniert auch das Senden nicht - im Hauptprogramm
versuche ich Testweise als allererstes ein Byte zu senden. Das Signal,
das am PD1/Tx-Pin vom Atmega328 rauskommt, sieht immer wie 0x80 aus egal
welches Byte man der Sendefunktion übergibt - s. Screenshot "Tx.png"
Das BTM-222 sendet dieses 0x80 dann übrigens auch korrekt weiter...
Die Transmit-Funktion sieht wie folgt aus:
1 | void USART_Transmit( unsigned char data )
|
2 | {
|
3 | //Wait for empty transmit buffer
|
4 | while ( !( UCSR0A & (1<<UDRE0)) )
|
5 | ;
|
6 | //Put data into buffer, sends the data
|
7 | UDR0 = data;
|
8 | }
|
und die Init-Funktion für den USART (bei der ich den Fehler noch
vermute) sieht wie folgt aus:
1 | void USART_Init( unsigned int ubrr)
|
2 | {
|
3 | //Set baud rate
|
4 | if ( ubrr & 0x8000 )
|
5 | {
|
6 | UCSR0A = (1<<U2X0); //Enable 2x speed
|
7 | ubrr &= ~0x8000;
|
8 | }
|
9 |
|
10 | //Set baud rate
|
11 | UBRR0H = (unsigned char)(ubrr>>8);
|
12 | UBRR0L = (unsigned char)ubrr;
|
13 |
|
14 |
|
15 | //Enable receiver and transmitter
|
16 | UCSR0B = (1<<RXEN0)|(1<<TXEN0);
|
17 | //Set frame format: 8data, 1stop bit
|
18 | UCSR0C = (3<<UCSZ00);
|
19 | }
|
Ich habe hier im Forum schon das Tutorial über den UART durchgelesen und
das Datenblatt des Atmega328P gewälzt (die USART-Funktionen sind
größtenteils daraus übernommen).
Ebenso hab ich hier im Forum nach dem Fehler gesucht und anhand des
Forum-Beitrags Beitrag "USART sendet nur 0x80" die Fuses
bzw. "SUT_CKSEL" vom internen Taktgeber auf "Ext. Crystal Osc. 8.0-..."
gesetzt, so dass der Atmega nun auch den externen Oszillator verwendet.
Allerdings hat dies keinen Erfolg gebracht.
Ich kann im Schaltungsaufbau nirgends einen Fehler entdecken und die
Aufnahmen mit dem Logic-Analyzer (s. Screenshot) legen nahe, dass es
sich um ein falsches Handling bzw. die Software vom USART des Atmegas
handeln sollte.
Im Anhang die komplette main.c - ich hoffe es erkennt jemand den Fehler.
Bin froh um jeden noch so kleinen Hinweis ;)
Danke und mfG,
Daniel