Serielle Datenübertragung vom ATMega8 zum PC

Gast #2569758
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();
        }
    }
}
Angehängte Dateien:
Gast #2569777
- 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?
Gast #2569783
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
Gast #2569787
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.
#2569823
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......
Gast #2569825
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
(Firma: guloshop.de) #2570829
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
#2570890
@  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? "
#2570946
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.
Gast #2570955
>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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.