Forum: Mikrocontroller und Digitale Elektronik Serielle Datenübertragung vom ATMega8 zum PC


von aspire (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich möchte über die UART-Schnittstelle des ATMega8 Daten über einen 
TTL/RS232 Pegelwandler an meinen PC Senden.

Das MC Programm ist fertig und die Daten empfange ich mit einem rxtx 
Java Programm. Die Daten Verlassen den TX Ausgang des MC korrekt siehe 
Scopebild. Der Wandler ist ein einfacher für 8€ von ebay. Wenn ich nun 
die Daten von mit meinem Java Programm empfange kommt statt dem ASCII 
Zeichen 1 ein q an und zwischendurch auch mal eine 1 (aber eher selten). 
Ich habe es jetzt bereits mit zwei verschiedenen Wandlern versuch bei 
beiden kommt es zum selben Ergebniss. Wo ist mein Fehler?

MC Code:
------------------------------------------------
#define FOSC 1000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
void main( void )
{
USART_Init ( MYUBRR );

while(1){
USART_Transmit('1')
_delay_ms(1000);
}
}
void USART_Init( 6 ) //hab ich einfach ausgerechnet und gleich 
eingesetzt
{
/* Set baud rate */
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void USART_Transmit( char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}

Der MC sendet das Signal perfekt. Scopebild vom TX Ausgang des Mega8 
liegt im Anhang. Die Einstellungen habe ich Überprüft es sind Startbit 
die 8Datenbits und die 2 Stoppbits zu sehen.

JAVA Code:
--------------------------------------------------------
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TwoWaySerialComm
{
    public TwoWaySerialComm()
    {
        super();
    }

    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = 
CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.out.println("Error: Port is currently in use");
        }
        else
        {
            CommPort commPort = 
portIdentifier.open(this.getClass().getName(),2000);

            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STO 
PBITS_2,SerialPort.PARITY_NONE);

                InputStream in = serialPort.getInputStream();
                OutputStream out = serialPort.getOutputStream();

                (new Thread(new SerialReader(in))).start();
            }
            else
            {
                System.out.println("Error: Only serial ports are handled 
by this example.");
            }
        }
    }

    /** */
    public static class SerialReader implements Runnable
    {
        InputStream in;

        public SerialReader ( InputStream in )
        {
            this.in = in;
        }

        public void run ()
        {
            byte[] buffer = new byte[1024];
            int len = -1;
            try
            {
                while ( ( len = this.in.read(buffer)) > -1 )
                {
                    System.out.print(new String(buffer,0,len));
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }
        }
    }

    public static void main ( String[] args )
    {
        try
        {
            (new TwoWaySerialComm()).connect("COM3");
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

von Floh (Gast)


Lesenswert?

aspire schrieb:
> #define FOSC 1000000// Clock Speed

interner RC-Taktgenerator?

von aspire (Gast)


Lesenswert?

ja ich nutze den internen Tacktgenerator mit 1MHz

von chick (Gast)


Lesenswert?

- Schon mal RX und TX des µC miteinander verbunden (auf der RS232-Seite 
natürlich)? Werden dann die korrekten Daten empfangen?
- Hält der interne Generator die UART-Specs ein?

von MoritzS (Gast)


Lesenswert?

Dann hast du dein Problem schon gefunden. Lies im Wiki zum Thema UART 
und dort insbesondere Taktquellen.

von spess53 (Gast)


Lesenswert?

Hi

>ja ich nutze den internen Tacktgenerator mit 1MHz

Vergiss es. Mit 1MHz hast du bei 9600Bd schon einen Fehler von 7%. Dazu 
kommt noch die Ungenauigkeit des Oszillators.

MfG Spess

von Sepp (Gast)


Lesenswert?

Der interne RC Oszillator ist zu ungenau!!!!

Damit stimmt deine Baudrate nicht mehr und es wird "Müll" empfangen.

--> Externen Quarz oder anderen Oszillator verwenden, Genauigkeit ca. 2% 
oder besser.

von aspire (Gast)


Lesenswert?

mit welcher baudrate kann ich denn noch arbeiten?

von Ralf G. (ralg)


Lesenswert?

aspire schrieb:
> mit welcher baudrate kann ich denn noch arbeiten?

Falsche Frage!
Richtig: Brauch ich unbedingt einen Quarz?
Ja! Und zwar einen mit 'krummer' Frequenz, auf die Übertragung 
abgestimmt.

Bei 1MHz gehen z.B. 300, 1200, 2400, 4800 mit unter 1% Genauigkeit. 
(9600 ergibt einen Fehler von 7%)
Wenn ich das Datenblatt richtig interpretiere, geht der interne 
Oszillator bei 1MHz mit bis zu 3% Abweichung......

von spess53 (Gast)


Lesenswert?

Hi

>mit welcher baudrate kann ich denn noch arbeiten?

Bei <=4800Bd liegt der Fehler bei 0,2%. Aber wie schon mehrmals gesagt 
ist der interne RC-Oszillator für eine stabile Verbindung ungeeignet.

MfG Spess

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Sepp schrieb:
> Der interne RC Oszillator ist zu ungenau!!!!
> Damit stimmt deine Baudrate nicht mehr und es wird "Müll" empfangen.

Dem schließ ich mich an - mit einem AAABER... ;-)

Es gibt Anwendungsfälle, bei denen ein externer Quarz nicht in Frage 
kommt. Dann bleibt als Ausweg immer noch, die Anzahl der Bits je Wort zu 
verringern. Beispiel:

Man nimmt eine Wortbreite von 4 Bits. (Falls eines der Geräte 4 Bits 
nicht als Wortbreite kennt, nimmt man eben 5 und lässt beim Senden das 
Bit 5 immer auf 1.) Zum Senden am besten zusätzlich "2 Stoppbits" 
einstellen.

Dadurch ist die Übertragung so robust, dass ihr Frequenzfehler von bis 
zu ca. 9 % nichts anhaben sollten. Wenns noch robuster sein soll: immer 
nur 2 Bits übertragen. Dazu sendet man am besten 8 Bits je Wort, wobei 
die Bits 2 bis 7 auf 1 gesetzt sein müssen. Den Empfang stellt man auf 4 
(oder 5) Bits je Wort. Hier werden sogar Fehler von bis zu 15% 
toleriert.

Natürlich ist eine solche Übertragung langsamer, weil auf der Leitung 
deutlich mehr Sync-Bits unterwegs sind. Aber wie gesagt - wenn mans 
braucht, ist es eine wunderbare Sache.

Markus

von Falk B. (falk)


Lesenswert?


von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Falk Brunner schrieb:
> http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
>
> Immer wieder das Gleiche, *gähn*

Ja, guter Artikel, aber dort steht nicht, wies trotzdem ohne Quarz geht. 
Würde vorschlagen, es zu ergänzen...

von Falk B. (falk)


Lesenswert?

@  Markus W. (m-w)

>Ja, guter Artikel, aber dort steht nicht, wies trotzdem ohne Quarz geht.

Wer lesen kann . . .

"Falls doch der interne Oszillator verwendet wird: Wurde er für die 
richtige Frequenz und Betriebsspannung kalibriert? "

von Karl H. (kbuchegg)


Lesenswert?

Markus W. schrieb:
> Falk Brunner schrieb:
>> http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
>>
>> Immer wieder das Gleiche, *gähn*
>
> Ja, guter Artikel, aber dort steht nicht, wies trotzdem ohne Quarz geht.
> Würde vorschlagen, es zu ergänzen...

Lieber nicht.

Klar. Man kann zur Not einen kaputten Auspuff auch mit Draht an die 
Hinterachse hängen. Aber vernünftig ist es nicht unbedingt.

von holger (Gast)


Lesenswert?

>Ja, guter Artikel, aber dort steht nicht, wies trotzdem ohne Quarz geht.

U2Xn = 1 kann man mal probieren. UBRRn muss natürlich dazu passen.
Ich plädiere aber auch lieber auf Quarz.

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.