Hallo,
ich möchte UART an einem atmega8 nutzen. Der folgende Code soll dabei
alle einkommenen Zeichen zurücksenden. Ich nutze ein fertiges Board von
"myavr", Quarz ist, ~3,68 MHz.
Leider funktioniert das ganze nicht und finde keinen Fehler im
Quellcode:
1
#include<avr\io.h> // AVR Register und Konstantendefinitionen
2
#include<util\delay.h> // Bibliothek mit Warteroutinen
3
#include<stdint.h>
4
#define F_CPU 3686400 // Taktfrequenz des myAVR-Boards
Stefan B. schrieb:
> Was meint dein Datenblatt deines Atmega8 zu dem Bit URSEL in dieser> Initialisierungsequenz?
• Bit 7 – URSEL: Register Select
This bit selects between accessing the UCSRC or the UBRRH Register. It
is read as one whenreading UCSRC. The URSEL must be one when writing the
UCSRC.
Tim schrieb:
> Und was kann ich jetzt mit der Information anfangen vor der Hintergrund,> dass das Bit URSEL in meinem Code nicht vorkommt?
IM DATENBLATT NACHLESEN, WAS DAS BIT URSEL MACHT!!!!!!!!!!!!!!!!! HASTES
JETZT?
Tim schrieb:
> Und was kann ich jetzt mit der Information anfangen vor der Hintergrund,> dass das Bit URSEL in meinem Code nicht vorkommt?seufz schau doch einfach, was beim USCRC-Register steht, wie es
gesetzt wird...ist Lesen denn so schwer?
Hallo Tim,
das habe ich im Datenblatt auf Seite 152 gefunden:
The UBRRH Register shares the same I/O location as the UCSRC Register.
Therefore some special consideration must be taken when accessing this
I/O location.
When doing a write access of this I/O location, the high bit of the
value written, the USART Register. Select (URSEL) bit, controls which
one of the two registers that will be written. If URSEL is zero during a
write operation, the UBRRH value will be updated. If URSEL is one, the
UCSRC setting will be updated.
The following code examples show how to access the two registers.
1
/* Set UBRRH to 2 */
2
UBRRH=0x02;
3
...
4
/* Set the USBS and the UCSZ1 bit to one, and */
5
/* the remaining bits to zero. */
6
UCSRC=(1<<URSEL)|(1<<USBS)|(1<<UCSZ1);
7
...
Sprich wenn du in dein UCSRC Register schreiben willst, musst du erst
das Bit URSEL auf 1 setzen. Sonst schreibst du in UBRRH (und veränderst
dadurch deine Baudrate -> da bin ich mir jetzt nicht so sicher, als
lyncht mich nicht sofort.)
Nicht richtig.
// Set frame format to 8 data bits, no parity, 1 stop bit
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);
Du hast bei dieser Initialisierung nicht 8-Datenbits und nicht 1
Stoppbit.
Mit solchen Fragen 1 Min. später ohne jegliche Initiative selbst im
Datenblatt zu lesen machst du dich nicht beliebt.
// Set frame format to 8 data bits, no parity, 1 stop bit
UCSRC = (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
Over and out.
übrigens ist 8N1 oft die standardeinstellung, die der AVR von sich aus
nach dem anlegen der betriebsspannung einnimmt. wenn man also nichts
anderes braucht erübrigt sich eine änderung dieser werte.
Tim schrieb:
> Danke, leider funktioniert es weiterhin nicht:
Du sendest am Anfang ein einzelnes 'A'.
Siehst du das auf der anderen Seite?
Was ist wenn du den µC einfach mal ständig 'A' senden lässt? Kommen die
auf der anderen Seite richtig an?
Und bitte: Zieh den Code doch nicht so in die Länge! Code wird nicht
übersichtlicher, wenn man mehr Leerzeilen einfügt. Er zieht sich nur in
die Länge und sonst gar nichts. Wenn du Übersicht haben willst, dann
kümmere dich um die Einrückungen.
Nein, es kommt rein gar nichts an. Weder die As, noch die
Repeater-Funktion.
Ich mache das ganze übrigens mit hterm unter Windows Vista, da ich kein
anderes Betriebssystem zu Verfügung habe.
Andreas Guter schrieb:
> Nein, es kommt rein gar nichts an. Weder die As, noch die> Repeater-Funktion.> Ich mache das ganze übrigens mit hterm unter Windows Vista, da ich kein> anderes Betriebssystem zu Verfügung habe.
Dann solltest du fürs erste den Repeater zur Seite legen und dich nur
auf das Senden konzentrieren (eine Fehlerquelle weniger).
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
Insebsondere könntest du mit dem vorletzten Punkt im Abschnitt "Sonstige
Fehlerquellen bei UART/USART" anfangen und zunächst feststellen ob die
Hardware-Kette vom µC zum PC in Ordnung ist, bzw. ob das Kabel korrekt
ausgekreuzt ist. Diesen Test würde ich dir zur Sicherheit sowieso
empfehlen. Solange dieser Test nicht einwandfrei klappt, hat es keinen
Sinn nach anderen Ursachen zu fahnden.
Also: Mega8 aus dem Sockel raus. RX/TX im Sockel mit einem Stück Draht
verbinden und im hTerm drauflosklimpern. Alles was du tippst, muss im
hTerm auch aufscheinen. Gegentest machen: Drahtbrücke entfernen. Jetzt
darf Getipptes im hTerm nicht mehr aufscheinen.
Das Programm im Anhang ist dein neustes Programm leicht geändert für
einen Test mit Attiny2313 @ 8 MHz. Dein Programm funktioniert. Ich
vermute daher ein Hardwareproblem.
Prüfe dein RS232-Kabel.
Bei dem myAVR Board MK1 LPT endet TXD des Atmega auf Pin 3 des
DB9-Anschlusses.
http://shop.myavr.de/index.php?ws=download_file.ws.php&dlid=44&filename=produkte/myavr_board_mk1/techb_schaltplan-myavr-board-mk1-lpt.png
D.h. das Board ist beschaltet sich wie ein PC (DTE Data Terminal
Equipment). Zur Verbindung zweiter DTEs also myAVR<->PC brauchst du ein
sog. Nullmodemkabel mit gekreuzten Leitungen.
Bei dem myAVR Board MK2 USB, Version 2.1 ist das im Schaltplan nicht
offensichtlich. Ich vermute aber, es ist genauso wie beim MK1
implementiert.
Zusätzlich kannst du noch auf dem myAVR Board CTS/RTS per Jumper
brücken. Wenn der PC auf Hardwareflusskontrolle eingestellt wäre, würde
das helfen. Und wenn er nicht auf Hardwareflusskontrolle eingestellt
ist, schadet es nicht.
Die Übertragungsstrecke (Buchsen, Kabel, MAX232) kannst du ausserdem so
prüfen: Atmega8 in den Dauerreset versetzen (z.B. Drahtjumper RESET nach
GND). RXD und TXD sind dann als Eingang geschaltet. Dann Drahtjumper
zwischen RXD und TXD anbringen. Jedes vom PC aus gesendete Zeichen
sollte jetzt als Echo zurückkommen. Die drei Buchsen für die Jumper
sitzen unmittelbar am Atmega8.