Hey! Ich wollte grade mal eine einfache UART Kommunikation zw. Atmega8
und PC machen, allerdings bekomme ich nichts raus...
Als Hardware benutze ich das myAVR board mit dem mysmartUSB-Programmer.
Aufm PC verwede ich Putty für die COM-Schnittstelle (mangels
Hyperterminal unter Win7)...
Das Testprogramm hab ich aus dem Netz, weshalb ich noch frustrierter
bin, dass es nicht klappt!
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
/* Prototypes */
5
voidInitUART(unsignedcharbaudrate);
6
unsignedcharReceiveByte(void);
7
voidTransmitByte(unsignedchardata);
8
9
/* Main - simple program that recieves a character then
10
transmits back the next character. An example would be if you send in an A, the chip will return a B */
11
int
12
main(void)
13
{
14
unsignedchari;
15
InitUART(95);/* Set the baudrate to 2400 bps using a 3.6864MHz crystal */
16
while(1)
17
{
18
TransmitByte(ReceiveByte()+1);/* Echo the received character + 1. Example send in A then send out B */
19
//for (i = 0; i < 200; i++);
20
}
21
}
22
23
24
/* Initialize UART */
25
void
26
InitUART(unsignedcharbaudrate)
27
{
28
/* Set the baud rate */
29
UBRRL=baudrate;
30
31
/* Enable UART receiver and transmitter */
32
UCSRB=(1<<RXEN)|(1<<TXEN);
33
34
/* 8 data bits, 1 stop bit */
35
UCSRC=(1<<UCSZ1)|(1<<UCSZ0);
36
37
}
38
39
/* Read and write functions */
40
unsignedchar
41
ReceiveByte(void)
42
{
43
/* Wait for incomming data */
44
while(!(UCSRA&(1<<RXC)));
45
46
/* Return the data */
47
returnUDR;
48
}
49
50
void
51
TransmitByte(unsignedchardata)
52
{
53
/* Wait for empty transmit buffer */
54
while(!(UCSRA&(1<<UDRE)));
55
56
/* Start transmittion */
57
UDR=data;
58
}
Das Programm soll halt einfach nur einen empfangenen Char erhöhen und
zurückgeben! Ich bekomme aber immer nur ein NULL zurück....
Was mach ich falsch?! Ich bin am Verzweifeln...
Greetz
sry für den Double Post! Hab aber was vergessen:
An dem Programmer liegt es nicht, ich stelle den PID Schalter so ein,
dass ich die Serielle Kom. erzwinge. Wenn ich mit Putty eine Eingabe
sende, kommt diese (lt. LED) auch mindestens beim
Programmer/Pegelwandler an...
nun aber
Stimmt die Taktfrequenz?
Der Code wie du ihr gepostet hast sieht einen 3.6864MHz crystal vor.
Wenn dein Atmega nicht mit 3.6864Mhz läuft, musst du den Wert für die
InitUART(Wert) Funktion anpassen. Dafür gibts genügend Tabellen für alle
erdenklichen Taktraten im Datenblatt des ATmega.
Liebe Grüße,
Nico
maini schrieb:> Das Testprogramm hab ich aus dem Netz, weshalb ich noch frustrierter> bin, dass es nicht klappt!
Nicht alles was man 'irgendwo' im Netz findet, ist auch korrekt.
Anstatt irgendwo, schau lieber im AVR-GCC-Tutorial nach. Die dort
angegebenen Codestückchen wurden getestet und wenn es Besonderheiten bei
bestimmten Prozessoren gibt, dann wird auch darauf hingewiesen.
> /* 8 data bits, 1 stop bit */> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
Gratuliere.
Damit ist die vorhergehende Einstellung der Baudrate überschrieben und
nicht mehr gültig.
> Was mach ich falsch?!
Du klaust Codestückchen (oder ganze Programme), ohne sie zu verstehen
und vor allen Dingen die Konfiguration mit dem Datenblatt deines
Prozessors zu kontrollieren bzw. anzupassen.
> Ich bin am Verzweifeln...
musst du nicht. Einfach nicht jedem Code aus dem Netz trauen.
AVR-GCC-Tutorial ist ein guter Anlaufpunkt für erste Codeteile, da
dieses Tutorial rigoros von einer großen Cummunity kontrolliert wird.
Und ansonsten: die einzige Autorität ist das Datenblatt zu deinem
Prozessor.
Hey! Die Checkliste bin ich mal eben durchgegangen, allerdings konnte
ich dort keinen Fehler finden. Die Takfrequenz lässt sich mit dem dort
geposteten Testprogramm als richtig einschätzen (die LED blinkt im
Sekundentakt)!
Muss ich unter WIN im Gerätemanager auch die Richtige Baud für den COM
Port einstellen? Hatte dies schon versucht, führte aber auch zu keinem
Ergebnis...
maini schrieb:> /* Set the baud rate */> UBRRL = baudrate;>> /* Enable UART receiver and transmitter */> UCSRB = (1 << RXEN) | (1 << TXEN);>> /* 8 data bits, 1 stop bit */> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);Karl Heinz Buchegger schrieb:> Gratuliere.> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und> nicht mehr gültig.
Wieso? Das sind doch unterschiedliche Register?! Oder was meinst du?
Gruß Knut
maini schrieb:> Muss ich unter WIN im Gerätemanager auch die Richtige Baud für den COM> Port einstellen?
Na sicha ;-)
maini schrieb:> Hatte dies schon versucht, führte aber auch zu keinem> Ergebnis...
Hast du ma oszillographiert was aus dem Pin rauskommt?
Knut
I. L. schrieb:> maini schrieb:>> /* Set the baud rate */>> UBRRL = baudrate;>>>> /* Enable UART receiver and transmitter */>> UCSRB = (1 << RXEN) | (1 << TXEN);>>>> /* 8 data bits, 1 stop bit */>> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);>> Karl Heinz Buchegger schrieb:>> Gratuliere.>> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und>> nicht mehr gültig.>> Wieso? Das sind doch unterschiedliche Register?!
No, sind sie nicht.
Im Datenblatt die Beschreibung des URSEL Bit im UCSRC nachlesen!
Der Mega8 hat ein UBRRH und ein URSEL Bit im UCSRC.
Und
Karl Heinz Buchegger schrieb:> Im Datenblatt die Beschreibung des URSEL Bit im UCSRC nachlesen!
[Zitat]
• Bit 7 – URSEL: Register Select
This bit selects between accessing the UCSRC or the UBRRH Register. It
is read as one when
reading UCSRC. The URSEL must be one when writing the UCSRC.
[/]
Gilt doch nur für das UBRRH-Register. Er beschreibt doch aber das
UBRRL-Register. Oder was übersehe ich grade?
Gruß Knut
I. L. schrieb:> The URSEL must be one when writing the UCSRC.
Jo, dass is es. Aber warum überschereibe ich denn UBRRL??? Im DB steht
ich überschreiben dann das UBRRLH!
Karl Heinz Buchegger schrieb:>> /* 8 data bits, 1 stop bit */>> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);>>> Gratuliere.> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und> nicht mehr gültig.
Klär mich bitte auf
Gruß Knut
I. L. schrieb:>>> /* 8 data bits, 1 stop bit */>>> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);>>>>>> Gratuliere.>> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und>> nicht mehr gültig.>> Klär mich bitte auf
Das hier
> Im Datenblatt die Beschreibung des URSEL Bit im UCSRC nachlesen!> Der Mega8 hat ein UBRRH und ein URSEL Bit im UCSRC.> Und> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);> verändert NICHT das UCSRC.
verändert UBRRH(!) und nicht UCSRC
UBRRH und UBRRL bestimmen gemeinsam die Baudrate! Und damit hat die
Zuweisung, so wie sie geschrieben wurde, keinen Einfluss auf UCSRC aber
auf die Baudrate.
Zum Beschreiben des UCSRC muss beim Mega8 IMMER URSEL gesetzt sein.
ANsonsten verändert man eben nicht UCSRC sondern das Baudratenregister,
betsehend aus UBRRL und UBRRH.
Ja, hast Recht. Ich glaube wir reden aneinander vorbei.
Du schriebst:
> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);> Gratuliere.> Damit ist die vorhergehende Einstellung der Baudrate überschrieben> und nicht mehr gültig.
Nein, damit hat er nichts überschrieben, nur zusätzlich auch das UBRRH
beschrieben. Ich habe dich da etwas missverstanden, ok!
Nichts für ungut...
Gruß Knut
Jetzt streitet doch nicht über die Interpretation des Satzes -
eigentlich über die Bedeutung von "überschreiben".
Fakt ist Karl Heinz hat das Problem erkannt und auf seine Weise indirekt
angesporchen.
Einmal ins Datenblatt schauen um zu schauen worauf er hinaus will,
Fehler korrigieren und "Danke, das wars" wäre in diesem Forum besser
angebracht als ein Rhetorikkurs.
I. L. schrieb:> Nein, damit hat er nichts überschrieben, nur zusätzlich auch das UBRRH> beschrieben.
Welchen Teil des Satzes (aus dem Datenblatt)
The URSEL must be one when writing the UCSRC.
hast du nicht verstanden.
Das hier
1
/* Set the baud rate */
2
UBRRL=baudrate;
3
4
/* Enable UART receiver and transmitter */
5
UCSRB=(1<<RXEN)|(1<<TXEN);
6
7
/* 8 data bits, 1 stop bit */
8
UCSRC=(1<<UCSZ1)|(1<<UCSZ0);
ist 100% gleichwertig zu
1
/* Set the baud rate */
2
UBRRL=baudrate;
3
4
/* Enable UART receiver and transmitter */
5
UCSRB=(1<<RXEN)|(1<<TXEN);
6
7
/* 8 data bits, 1 stop bit */
8
UBRRH=(1<<UCSZ1)|(1<<UCSZ0);
Die letzte Zuweisung beschreibt NICHT UCSRC sondern das Register
UBRRH. Es tut mir leid, aber das ist Faktum. Da gibt es nichts daran zu
rütteln oder miszuverstehen.
> nur zusätzlich auch das UBRRH beschrieben
nicht zusätzlich. Das eigentliche UCSRC wurde nie beschrieben!
Karl Heinz Buchegger schrieb:> Die letzte Zuweisung beschreibt NICHT UCSRC sondern das Register> UBRRH. Es tut mir leid, aber das ist Faktum. Da gibt es nichts daran zu> rütteln oder miszuverstehen.
Ok, nochmal. Das er das UBRRH (unwissentlich) beschreibt ist mir
bekannt.
Karl Heinz Buchegger schrieb:> nicht zusätzlich.
natürlich, denn das hat er nie beschreiben wollen.
Er wollte das UBRRL beschreiben, hat nun aber (zusätzlich +
unwissentlich) das UBRRH Register auch beschrieben. Das UCSRC hat er nie
angerührt.
Nochmals...
I. L. schrieb:> Ich habe dich da etwas missverstanden, ok!
Gruß Knut
Das einzige was den TO jetzt noch gerettet haben könnte, ist die
Reihenfolge. Der Baudratenteiler wird erst mit dem beschrieben von UBRRL
tatsächlich upgedatet. Von daher könnte er tatsächlich die richtige
Baudrate haben. Was nicht heißt, dass die Zuweisung korrekt ist. Die ist
immer noch falsch, wirkt sich aber nicht direkt aus :-)
Insofern hatte ich also weiter oben unrecht.
> allerdings bekomme ich nichts raus...
ist eine schwammige Formulierung. Das könnte auch ein falsch gekreuztes
Kabel sein :-)
Warten wir mal ab, was das Abarbeiten der Checkliste ergibt. Am
wahrscheinlichsten ist halt immer noch eine falsche Taktfrequenz.