ATmega328p und UART

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Meinst du die 3.5% Error, aber wieso geht es mit 9600Baud auch nicht ? Das sind es nur 0.2%.
Oder macht etwa das Terminalprogramm Mühe ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: ATmega328p und UART

Beitrag von siro »

Auf Seite 199 im Datenblatt steht ein Hinweis:

/* IMPORTANT: The Baud Rate must be set after the
transmitter is enabled */
UBRRn = baud;

kann das damit irgendwie zusammen hängen ?
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Ich habe da noch eine interessante Tabelle gefunden.
http://wormfood.net/avrbaudcalc.php

Aber lösen tut sie mein Problem nicht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Ich habe auf dieser Seite entdeckt, das die Baudrate anders berechnet wird.
http://www.avrfreaks.net/forum/tut-soft ... s?page=all

Grund-liegend würde es funktionieren, dafür habe ich jetzt ein ganz komischer Fehler, die meisten Buchstaben, Zahlen und Sonderzeichen (ASCII<128) werden richtig übertragen.
Der Teiler ist jetzt um den Faktor 8 daneben, das die überhaupt funktioniert.
Aber folgende Zeichen kommen immer falsch:

Code: Alles auswählen

a -> q    A -> Q
x -> |    X -> \
8 -> <    0 -> 4     
C -> ,    p -> t
P -> T    b -> B
! -> 1    space -> $
Ab und zu beim ersten drücken kommen auch diese Zeichen richtig.
Ich kann da keinen Zusammenhang feststellen.

Jemand eine Idee ?

Hier nochmals der Code, in einem Miniformat:

Code: Alles auswählen

program Project1;
{$o-}
 
  procedure sei; assembler;
  asm Sei end;
 
  procedure cli; assembler;
  asm Cli end;
 
const
  UCSZ01 = 2;           // Gibt es nicht in der Unit Atmega328p.
  CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
  Baud = 9600;          // Baudrate
//  teiler = CPU_Clock div (2 * Baud) - 1;
  teiler = CPU_Clock div (16 * Baud) - 1// neu
 
  procedure UARTInit;
  begin
    UBRR0 := teiler;
 
    UCSR0B := (1 shl TXEN0) or (1 shl RXEN0) or (1 shl RXCIE0);
    UCSR0C := (1 shl UMSEL0) or (%011 shl UCSZ0);
 
    DDRD := DDRD or (1 shl 4);
  end;
 
  procedure UART_RX_Empfang; public Name 'USART__RX_ISR'; interrupt;
  var
    b:Byte;
  begin
    b := UDR0;
    UDR0 := b;
  end;
 
begin
  cli;
  UARTInit;
  sei;
 
  repeat
  until 1 = 2;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: ATmega328p und UART

Beitrag von siro »

Ich glaube dein Uart arbeitet im Synchronmodus anstelle des Asynchron Modus.
nimm mal das 1 SHL UMSEL0 weg
oder schreib mal direkt eine 6 ins Register, das sollte dann Asynchron 8 Datenbits No Parity sein.

Code: Alles auswählen

// UCSR0C := (1 shl UMSEL0) or (%011 shl UCSZ0);
UCSR0C := 6;   
 


wart mal ich sortier die Bits noch.... geht gleich weiter... :?
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: ATmega328p und UART

Beitrag von Timm Thaler »

siro hat geschrieben:Auf Seite 199 im Datenblatt steht ein Hinweis:

/* IMPORTANT: The Baud Rate must be set after the
transmitter is enabled */
UBRRn = baud;


Das gilt nur für MSPIM Mode, wenn man Usart für Master SPI Mode verwendet.

Grundsätzlich würde ich mir aber an Stelle des TO schon seit Tagen Gedanken machen, warum bei ihm der Uart nur mit UMSEL0 gesetzt funktioniert, obwohl alle Welt und das Datenblatt sagen: Das muss so nicht.

Mathias hat geschrieben:Ich kann da keinen Zusammenhang feststellen.


Ich schon: https://de.wikipedia.org/wiki/Ascii#Zusammensetzung

Es sind - bis auf das C - immer 4, 16 oder 32 Zeichen, um die verschoben wird. Eindeutig ein Sampling-Fehler, ein low- oder high-bit wird im nächsten Frame statt im richtigen erkannt. Datenblatt Seite 183ff wird das mit dem Sampling erklärt.

Warum das falsch sampelt? Kann man schwer sagen. Kann sein, dass Dein Uart im SPI-Modus läuft (UMSEL?) und deswegen das Sampling zufällig immer mal passt und mal nicht. Dann würde ich allerdings mit mehr Fehlern rechnen. Kann sein, dass Deine Verbindung einfach Mist ist und die Signale zu sehr verschleift werden. Machst Du den Uart über den On-Board-Uart eines Arduino oder über einen Pegelwandler an einer RS232 eines Computers oder eines externen USB-seriell-Wandlers? Kann auch sein, dass Dein Quarz daneben liegt, oder der µC gar nicht auf dem 16MHz Quarz sondern auf dem internen RC-Oszillator läuft.

Ach noch was? Du empfängst die Zeichen und sendest die gleichen Zeichen wieder raus?

Dann kann es sein, dass Deine Baudrate völlig daneben liegt. Der AVR empfängt etwas völlig anderes, schickt es aber wieder mit der gleichen falschen Baudrate zurück und der Computer bastelt daraus wieder einigermaßen das Richtige zusammen.

Schick mal direkt eine Zeichenfolge wie 'ABC' vom AVR raus und schau, wie die ankommt.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: ATmega328p und UART

Beitrag von siro »

ich glaub da muss ne 6 ins register

UCSR0C := 6;

Ach noch was? Du empfängst die Zeichen und sendest die gleichen Zeichen wieder raus?

Das was er empfängt sendet er wieder, ich denke das soll so ein. Eine Echo Funktion zum Testen.

Wenn Du ein Oszilloskop hättest, könnte man ja gucken was da für eine Baudrate kommt.
Ein Ossi ist immer mein treuer Begleiter beim Programmieren. :D
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

nimm mal das 1 SHL UMSEL0 weg
An dies hätte ich nicht mehr gedacht.
Jetzt funktioniert es, anscheinend hat es mit UMSEL0 die falsche Baudrate zum Teil kompensiert.

So wie es scheint, habe ich wieder mal einen Fehler gegoogelt. :evil:

Code: Alles auswählen

const
  UCSZ01 = 2;           // Gibt es nicht in der Unit Atmega328p.
  CPU_Clock = 16000000; // Taktfrequenz Arduino, default 16MHz.
  Baud = 9600;          // Baudrate
  teiler = CPU_Clock div (16 * Baud) - 1;
 
  procedure UARTInit;
  begin
    UBRR0 := teiler;
 
    UCSR0A := (0 shl U2X0);
    UCSR0B := (1 shl TXEN0) or (1 shl RXEN0) or (1 shl RXCIE0);
    UCSR0C := %011 shl UCSZ0;
 
    DDRD := DDRD or (1 shl 4);
  end;


Es sind - bis auf das C - immer 4, 16 oder 32 Zeichen, um die verschoben wird. Eindeutig ein Sampling-Fehler, ein low- oder high-bit wird im nächsten Frame statt im richtigen erkannt. Datenblatt Seite 183ff wird das mit dem Sampling erklärt.
Ich denke das wird so etwas gewesen sein.

Danke an alle die geholfen haben.

Muss ich nur noch das Tutorial anpassen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Das was er empfängt sendet er wieder, ich denke das soll so ein. Eine Echo Funktion zum Testen.

Ja es war ein Test, man sagt ja immer man sollte ein Programm au minimum abspecken, wen etwas nicht geht.

Wenn Du ein Oszilloskop hättest, könnte man ja gucken was da für eine Baudrate kommt.
Ein Ossi ist immer mein treuer Begleiter beim Programmieren. :D

Ein KO hätte ich, aber ob er geholfen hätte.
Vor allem muss man noch wissen wie man den sauber bedient. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: ATmega328p und UART

Beitrag von Timm Thaler »

siro hat geschrieben:Das was er empfängt sendet er wieder, ich denke das soll so ein. Eine Echo Funktion zum Testen.


Das kann aber grob schiefgehen. Mal angenommen der Uart läuft mit doppelter Baudrate. Wir schicken ein 'A', also hex 41, binär 0100 0001. Der AVR sampelt das wegen der doppelten Baudrate zu zwei Zeichen 0011 0000 und 0000 0011. Also was völlig anderes. Jetzt schickt er die zwei Zeichen wieder raus, und da sie auch mit doppelter Baudrate abgehen, kommen sie beim Empfänger wieder als 0100 0001, also einem 'A' an. Nur wird manchmal, wenn der Flankenwechsel etwas jittert, ein Bit falsch gesampelt und dann kommen einige Buchstaben falsch zurück.

Das würde auch erklären, warum der TO darauf besteht, dass der Uart bei ihm nur mit UMSEL gesetzt funktioniert, denn soweit ich das sehe geht das eigentlich nur im synchronen Modus. Man kann ähnliche Fehler im asynchronen Modus haben, aber dann äußert sich das gravierender, wegen der falschen Start- und Stopbits.

Und das würde auch erklären, warum die Berechnung der Quarzfrequenz so weit daneben liegt.

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Jetzt funktioniert es ohne das DDR, ursprünglich brauchte es dies, wieso auch immer ?
Irgendwie hängt dies auch mit UMSEL zusammen,

Code: Alles auswählen

//    DDRD := DDRD or (1 shl 4);


Hauptsache, das es klappt, das Tutorial ist angepasst. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Im Wiki habe ich folgende Nachricht bekommen, ich habe es mit Google übersetzt, aber ich werde nicht schlau.
Mathias, please follow the conventions on naming of this wiki. The title of the articles should be in English and have a language suffix (except English).
For example:
Simple Change Indicator/de instead Einfacher Wechselblinker
If you want to specify German article title, you can do it inside article.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ATmega328p und UART

Beitrag von af0815 »

Die Wiki hat folgende Konventionen. Die Namen der Titel ist immer in Englisch zu halten, die anderen Sprachen haben einen suffix.

Statt 'Einfacher Wechselblinker' muss man 'Change indikator/de' verwenden. Das /de ist die Sprache, die kann nur bei Englisch entfallen.
Wenn du deutsche Titel willst,m dann innerhalb des Artikels.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ATmega328p und UART

Beitrag von Mathias »

Ich habe die Seite nach http://wiki.freepascal.org/Einfacher_Wechselblinker/de, ich hoffe dies ist richtig.

Ups, ich habe gerade gesehen, das ich mich im Thread geirrt habe, die hätte in AVR-Tutorial gehört. :oops:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: ATmega328p und UART

Beitrag von af0815 »

Nochmal, der Titel sollte immer in Englisch sein. Somit Sollte es 'Change_Indicator/de' oder 'Simple_Changeindicator/de' lauten !!

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten