AVR atmega324p UART

Gast #2486727
Lesenswert?

Ich habe ein Problem und zwar kann ich mit dem atmega324p kein UART 
programmieren bzw. ich habe es noch nicht hingekriegt. Im Anhang ist 
mein Programmcode. Kann mir jemand sagen, was ich falsch programmiert 
habe. Ich will mit der Baudrate von 9600 senden und empfangen.

Mit freundlichen Grüssen

Reiner Zufall
Angehängte Dateien:
Gast #2486775
Lesenswert?

Reiner Zufall schrieb:
> Ich will mit der Baudrate von 9600 senden und empfangen.

Das ist bei einer seriellen Datenübertragung aber nicht die ganze 
Wahrheit.
Was ist mit: Anzahl Datenbits, Parity, Anzahl Stopbits?

Dann in deiner .c :
Am Anfang:
1
void uart_init(void)
2
{
3
  //UCSR0A=0;                            //Register UCSR0A auf Null setzten
4
  //UCSR0B=0;                            //Register UCSR0B auf Null setzten
5
  //UCSR0C=0;                            //Register UCSR0C auf Null setzten
6
  UBRR0H = (unsigned char)0;                    //Baudrate setzten
7
  UBRR0L = (unsigned char)129;                  //Baudrate setzten
8
  UCSR0C |= 0x86;                          //8 Bit Datentransfer
9
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);                  //RxD0 & TxD0 aktivieren
10
  UCSR0A |= (1<<U2X0);                      //Doublespeed aktivieren
11
}

und am Ende nochmal?:
1
void set_baudrate(void)
2
{
3
  UCSR0B = 0x00;                          //Setzt Register UCSR0B auf Null
4
  UBRR0H = ((((((long)MCU_CLOCK)*2)/(8*((long)1000000))+1)/2-1)>>8)&0xff;//Baudrate setzten
5
  UBRR0L = (((((long)MCU_CLOCK)*2)/(8*((long)1000000))+1)/2-1)&0xff;//Baudrate setzten
6
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);                  //RxD0 & TxD0 aktivieren
7
  UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);                //8 Bit Datentransfer
8
  UCSR0A |= (1<<U2X0);                      //Doublespeed aktivieren
9
}
Gast #2486799
Lesenswert?

Eigentlich ist U2X0 auf eins. Ich habe zwei UART-Eingänge. Ich muss 
zuerst mit dem Computer über rs232 kommunizeren können bis ich mit dem 
vnc1l weiterfahre.

void set_baudrate(void)
{
  UCSR0B = 0x00;                          //Setzt Register UCSR0B auf 
Null
  UBRR0H = 
((((((long)MCU_CLOCK)*2)/(8*((long)1000000))+1)/2-1)>>8)&0xff;//Baudrate 
setzten
  UBRR0L = 
(((((long)MCU_CLOCK)*2)/(8*((long)1000000))+1)/2-1)&0xff;//Baudrate 
setzten
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);                  //RxD0 & TxD0 
aktivieren
  UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);                //8 Bit Datentransfer
  UCSR0A |= (1<<U2X0);                      //Doublespeed aktivieren
}

Dieser Programmcode wäre für später. Habe ihn von irgendwo 
abgeschrieben.
Gast #2486837
Lesenswert?

> Eigentlich ist U2X0 auf eins.

..ich stelle die Frage anders: Warum setzt du U2X0? Die 129 in 
uart_init() güldet für normale Geschwindigkeit.
Und ich wiederhole die andere: Wie lautet eine ∗genaue∗ 
Fehlerbeschreibung?
Und eine füg ich noch hinzu: Was ist das Ergebnis aus der 
UART-Checkliste?

HTH
Gast #2486877
Lesenswert?

> weil es bei der übertragung immer einen Fehler gibt

? Was für einen? Woran erkennst du ihn? Was sollte passieren? Was 
passiert stattdessen? Was hast Du schon alles probiert? Warum hast Du 
das, was Du probiert hast, probiert? Warum hat es nicht funktioniert? 
Woran hast Du erkannt, dass es nicht funktioniert hat?

Gibt Dir doch bitte mal ein bisschen mehr Mühe.
#2486878
Lesenswert?

Einen Fehler ????

Der erste Schritt ist jeweils vom Controller mit einem Timer einen 
Buchstaben zu senden, zB 0xC5, und dann mit dem Scope zu pruefen, ob der 
auch rauskommt. Wenn der rauskommt, dann den Tx auf den Rx und pruefen 
ob der auch das 0xC5 empfaengt. Dann den PC anschliessen. Wenn der Muell 
bringt ist die Baudrate nicht genau genug.

usw.
Gast #2486978
Lesenswert?

Wenn ich das Ausgangssignal wieder in den Eingang vom uC leite, empfängt 
er das richtige Zeichen. Es kommt also etwas auf dem uC und der uC kann 
auch etwas empfange. Ich kann aber vom PC aus nichts senden oder 
empfangen, ohne eine Fehler.
Gast #2487127
Lesenswert?

Lieber Reiner

du hattest 1,2 Fehler drin
ich weiss nicht wo du programieren gelernt hast...

DIESER CODE GEHT

void set_baudrate(void)
{
  UCSR0B = 0x00;                          //Setzt Register UCSR0B auf
Null
  UBRR0H =
((((((long)MCU_CLOCK)*2)/(8*((long)1000000))+1)/2-1)>>8)&0xff;//Baudrate
setzten
  UBRR0L =
(((((long)MCU_CLOCK)*2)/(8*((long)1000000))+1)/2-1)&0xff;//Baudrate
setzten
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);                  //RxD0 & TxD0
aktivieren
  UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);                //8 Bit Datentransfer
  UCSR0A |= (1<<U2X0);                      //Doublespeed aktivieren
}
Gast #2488454
Lesenswert?

Meine Kommunikation zwischen dem PC und dem uC gibt mysteriöse Zeichen 
aus. Wenn ich vom PC aus ein Signal sende und dieses vom uC wieder 
zurücksende bekomme ich völlig andere Zeichen zurück. Wenn ich nur vom 
uC über eine Tastatur die Zeichen einlese und diese dann dem PC sende, 
gibt es auch Fehler, weil das Zeichen nicht korrekt übertragen wird.
Gast #2488537
Lesenswert?

Ich glaube ich habe meinen Fehler gefunden, ich weiss allerdings nicht 
wie ich ihn beheben kann. Ich benutze den Atmega324p und einen externen 
Oszillator mit 20MHz. Ich vermute, dass ich bei der Taktfrequenz etwas 
falsch gemacht habe. Ausserdem weis ich nicht ob ich eine Fuse clkdiv 
habe und ob ich diese richtig eingestellt habe. Ich habe einen aufbau 
gemacht, wo ein LED im Sekundentakt blinken soll, die LED blinkt aber 
viel langsamer. Vielleicht liegt das Problem beim aufbau auf der 
Lochplatte aber ich glaube eher, dass ich die Taktfrequenz falsch 
eingestellt habe.
Gast #2488559
Lesenswert?

und wieviel langsamer ist das?
und wenn das zu schwer ist, dann compiliere den blinkcode soooolange mit 
unterschiedlichen FCPU bis der Blinktakt stimmt.
1,2,4,5,8,10Mhz könnten mögliche frequenzen sein.
Gast #2488975
Lesenswert?

hallo reini
ich bin noch ein anfänger im programmieren und bin im zweiten lehrjahr 
als Elektroniker...
Kann mir jemand erklären was ISP ist?
Liebe Grüsse cédi51    [www.display-magazin.ch/ REINSCHAUEN UND 
ABONIEREN]
Gast #2489473
Lesenswert?

> Wenn ich die Taktfrequenz zwischen 2.5-2.6 MHz einstelle, ist es
> ungefähr eine Sekunde.

Klingt verdächtig nach CKDIV8 (-> Datenplatt lesen, CKDIV8 löschen).

Hättest Du übrigens gestern ab 10:17 Uhr schon feststellen können wenn 
Du die bereits da verlinkte Checkliste durchgegangen wärst.

Nix für ungut

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren