PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART - Bluetooth Übertragungsfehler



robo_tom_24
21.05.2012, 19:55
Hallo
Ich bekomm keine richtigen Zeichen gesendet über BT auf meinen PC
Egal welche Zeichen ich versende, das kommt: "ðððððððððððððððððððððððððððððððð"
Was noch ist: es kommt nicht jedes Zeichen direkt, immer so 50 auf einmal alle 25 sec.

Code:
#define BAUD 19200 // Baudrate
#define F_CPU 8000000

// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.

#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate groesser 1% und damit zu hoch!
#endif



//-------------- INCLUDES
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>



void USART_Init( void )
{
UCSR0B |= (1<<TXEN0); //UART TX (Transmit - senden) einschalten
UCSR0C |= (3<<UCSZ00); //Modus Asynchron 8N1 (8 Datenbits, No Parity, 1 Stopbit)

UBRR0H = 0; //Highbyte ist 0
UBRR0L = (F_CPU/(BAUD*16))-1; //Lowbyte ist 103 (dezimal) -> (Frequenz_in_Hz / (Baudrate * 16)) - 1 <- Quarfrequenz = 16*1000*1000 Hz!!!!
}

void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) );


/* Put data into buffer, sends the data */
UDR0 = data;
}

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) );

/* Get and return received data from buffer */
return UDR0;
}


int main(void)
{
DDRC |= 1<<PINC0; //LED init
PORTC &= ~(1<<PINC0);
DDRB |= 1<<PINB6;
PORTB |= 1<<PINB6;


USART_Init(); // USART einstellen

_delay_ms(250);
PORTB &= ~(1<<PINB6); //LED aus

while(1)
{
USART_Transmit('t'); //Send thomas
USART_Transmit('h');
USART_Transmit('o');
USART_Transmit('m');
USART_Transmit('a');
USART_Transmit('s');

PORTC ^= 1<<PINC0; //toggle LED (red)

_delay_ms(250);
}

}//end main

Habt ihr da eine Idee?

Bumbum
22.05.2012, 06:38
Guten Morgen,

folgendes fällt mir dazu ein:

- Es ist auf jeden Fall ein Quarz nötig, um den USART zu betreiben, ohne habe ich das noch nie stabil zum laufen gebracht. Ist die Quarz-Frequenz tatsächlich genau 8000000? (Manche "8MHz" meinen ja auch z.B. 8388608).

- Ist vielleicht die CDIV/8 Fuse gesetzt?

- Ist die Berechnung des Compiles für UBRR0 richtig? Hast du hier mal manuelle Werte probiert?

- Möchte das BT-Modul überhaupt mit 19200 Baud angesprochen werden? Hast du dieses mal an den PC gehängt und per Hyper-Terminal getestet?

- Sind die Stop-Bits und Parität richtig konfiguriert?

- Ist das Signal vielleicht aus versehen Invertiert am BT-Modul angeschlossen? (Hatte ich schon mal durch einen selbst gebauten Pegel-Wandler)

- Dass irgendwann alle Zeichen auf einmal kommen könnte ein gesetzter Buffer im BT-Modul sein. Hast du dir hier mal die Konfiguration angeschaut?

Viele Grüße
Andreas

robo_tom_24
22.05.2012, 07:52
Hallo
So einfach Quarz rein, bzw. BTM an PC geht nicht. das Modul ist in eine Platine integriert. Das mit der Fuse könnte aber sein. Als Taktgeber hab ich den internen 8MHz Resonator ausgewählt. Invertiert ist es auch nicht, da das Modul ein Fertigmodul ist, und von anderen auch in. Verwendung ist. Meiner Meinung nach müsste es an einem Software Fehler liegen.
Das mit den vielen Zeichen auf einmal hab ich aber schon weggebracht indem ich ein anderes Terminal Programm verwendet habe (Realterm)

sternst
22.05.2012, 09:37
Die Berechnung des UBRR-Wertes ist fehlerhaft wegen eines fehlenden "UL".

robo_tom_24
22.05.2012, 15:13
Hallo
Also die Fuses sind so gesetzt:

BODLEVEL = 1V8
RSTDISBL = [ ]
DWEN = [ ]
SPIEN = [X]
WDTON = [ ]
EESAVE = [X]
BOOTSZ = 256W_3F00
BOOTRST = [X]
CKDIV8 = [ ]
CKOUT = [ ]
SUT_CKSEL = INTRCOSC_8MHZ_6CK_14CK_65MS

EXTENDED = 0xFE (valid)
HIGH = 0xD6 (valid)
LOW = 0xE2 (valid)


Hoffe das ist rchtig ;)

Ich hab jetzt nach der Frequenz "UL" geschrieben - doch dann sendet er gar nichts mehr :(
Muss ich dann noch die Berechnung ändern oder so etwas?

sternst
22.05.2012, 16:21
Ich hab jetzt nach der Frequenz "UL" geschrieben Falsche Stelle. Das hier ist der Knackpunkt:

#define BAUD 19200

... (BAUD*16) ...Das läuft über, weil es in int berechnet wird.

robo_tom_24
22.05.2012, 18:47
Wenn ich das aber so schreibe gehts nicht :(
Nichts mehr vom Modul, egal wo ich es hinschreibe...

#define F_CPU 8000000
#define BAUD 19200UL // Baudrate

__________________________________________________ __________________________________________________ __________
Edit:
Ich habs :D
Das Problem war das der Compiler das UL falsch interpretiert hat, ich habs jetzt mit der langen Version der expliziten Datentypkonvertierung aausgetauscht und siehe da, es funktioniert

#define F_CPU 8000000
#define BAUD (unsigned long)19200 // Baudrate

danke für die Hilfe :)
Jetzt gehts mal ans Daten empfangen und dann an die Steuerung

Bumbum
23.05.2012, 06:19
Prima. Aber falls du noch keinen Quarz gesetzt hast, würde ich auf jeden Fall einen Empfehlen. Spätestens wenn sich die Temperatur wieder ändert wirst du irgendwann Probleme bekommen, da die Baudrate mit dem interenen Oszilator nicht stabil genug ist.

Viele Grüße
Andreas

robo_tom_24
23.05.2012, 20:16
Wie gesagt, wird nicht all zu leicht werden, da das eine fertige Platine ist, und ich erst den Anschluss herausführen muss.
Kann ich eigentlich den Oszillator im Programm kalibrieren? Sozusagen ich messe mit einem KTY81 oä. die Temperatur und je nachdem ändere ich etwas?