Hallo,
nach Lektüre vieler Beiträge und Tutorial-Artikel dachte ich, daß ein
funktiomierender Code entstanden ist, um Daten vom ATMEGA 16 zum
PC-Terminal transferieren zu können - aber es geht einfach nicht!
Ob sich mal jemand mit unvoreingenommenem Blick meinen Code ansehen
könnte?
1 | #define BAUD 9600UL
| 2 | #define UBRR_BAUD ((F_CPU) / (16UL*BAUD) - 1)
| 3 |
| 4 | void USARTinit(void)
| 5 | {
| 6 | UBRRH = (uint8_t) (UBRR_BAUD>>8);
| 7 | UBRRL = (uint8_t) (UBRR_BAUD & 0x0FF );
| 8 | UCSRB |= (1<<TXEN); // USART TX einschalten zum Senden
| 9 | UCSRC |= (1<<URSEL) | (1<<UCSZ1) |(1<<UCSZ0) ; // Asynchr 8N1
| 10 | }
| 11 |
| 12 | und dann aus endloser Schleife in main der Aufruf:
| 13 |
| 14 | USARTinit();
| 15 | while (!(UCSRA & (1<<UDRE))) // warten bis Senden möglich
| 16 | { // while-Schleife ist hier unnötig!)
| 17 | }
| 18 | UDR = 'x';
|
Laufen soll das auf einem ATMEGA16, am anderen Ende der seriellen
Leitung ist ein PC mit AVRTerm. Die Schnittstelle ist ok, lt. AVRTerm
scheint es eine Verbindung zu geben, aber es kommt nichts an, kein "x"
und auch keine Sonderzeichen.
Falls die Baudrate falsch eingestellt wäre, müßten ja wenigstens
irgendwelcher Kram ankommen - aber es kommt nichts.
Den Code habe ich mir nicht selbst ausgedacht, es ist aus dem Manual,
div. Forenbeiträgen usw. übernommen. Meine Hoffnung ist, daß irgend
jemand vielleicht einen Schreibfehler findet (obwohl der Compiler von
WinAVR nichts beanstandet).
Ansonsten bin ich ratlos.
Vielen Dank im Voraus
Alexander
PS: Der Atmega hat einen externen Quarz, aber die Aufschrift fehlt,
(wahrscheinlich 8MHz), deshalb würde ich mich z.Zt. mit schrägen
Sonderzeichen begnügen, wenn nur etwas ankäme.
1. Feststellen mit welcher Speed der Atmega16 tatsächlich läuft.
Mit Datenblatt:
AVR Fuses auslesen und Setting nachschlagen
Mit Oszi oder Frequenzzähler:
Takt per Hardware auf den Pin CLKOUT geben und messen.
Mit LED/Vorwiderstand:
F_CPU auf irgendeinen Wert z.B. 1 MHz definieren und eine LED mit Hilfe
der _delay_ms() (#) blinken lassen. Wenn die im Programm vorgegebene
Blinkzeit 8s beträgt und die LED tatsächlich im 1s Abstand blinkt, ist
die tatsächliche F_CPU 8 MHz. Wenn die Messung mit diesen Zahlen zu
schwierig ist, Zahlen im nächsten Durchgang anpassen.
(#) 1 | #include <util/delay.h>
| 2 | void warte()
| 3 | {
| 4 | uint8_t i;
| 5 | for (i=0; i<8*10; i++)
| 6 | _delay_ms(100); // 100ms * 10 * 8 = 8s (bei F_CPU 1 MHz)
| 7 | }
|
2. Tatsächliche F_CPU nach 1. definieren und damit UBRR berechnen und
UART Programm laufen lassen.
Senderoutine:
1 | int main()
| 2 | {
| 3 | USARTinit();
| 4 | while(1)
| 5 | {
| 6 | while (!(UCSRA & (1<<UDRE))) // warten bis Senden möglich
| 7 | {
| 8 | }
| 9 | UDR = 'x';
| 10 | }
| 11 | }
|
> Die Schnittstelle ist ok, lt. AVRTerm
> scheint es eine Verbindung zu geben,
Es gibt bei einer einfachen Dreidrahtverbindung keine Möglichkeit für
ein Terminalprogramm, Folgendes festzustellen: "lt. AVRTerm scheint es
eine Verbindung zu geben".
Um die Schnittstelle zu testen: µC ziehen und den RxD- mit dem TxD-Pin
verbinden. Kommen jetzt alle eingegebenen Zeichen wieder zurück, ist
die serielle Verdrahtung in Ordnung.
Hallo
ist denn der Code an sich in Ordnung?
Bei der CPU-Taktfrequenz hatte ich über Delayschleifen schon
festgestellt, daß der externe Quarz seinen Dienst tut. Nur habe ich noch
nicht getestet, ob es ein 8 MHz oder ein 7,3...MHz (für UART) drin ist.
Auf jeden Fall will ich mir einen mit 7,3...MHz beschaffen und
einsetzen.
Aber nebenbei: wenn die Baudrate ein wenig oder auch massiv falsch ist,
müßte nicht irgendetwas gesendet werden?
@ Hc Zimmerer
Ausbau des µC ist schwierig, aber ich komme an die Kontakte. Könnte man
hilfsweise auch die TX- und RX-Pins miteinenander verbinden - über einen
1k-Widerstand, damit nichts zerstört wird?
Was ich zu erwähnen vergessen hatte: ich benutze ein Board AVR-P4ß 0535
aus dem hiesigen Shop, mit MAX232 (und nachgerüsteter Drahtverbindung
zwischen µC und MAX).
Viele Grüße
Alexander
Alexander Schmeil schrieb:
> ist denn der Code an sich in Ordnung?
Dein Originalcode - Ausschnitt? 1 | und dann aus endloser Schleife in main der Aufruf:
| 2 |
| 3 | USARTinit();
| 4 | while (!(UCSRA & (1<<UDRE))) // warten bis Senden möglich
| 5 | { // while-Schleife ist hier unnötig!)
| 6 | }
| 7 | UDR = 'x';
|
Nein.
Lass die UART arbeiten und Initialisiere sie nicht innerhalb der
Endlosschleife immer wieder neu.
Initialisieren heist deshalb Initialisieren, weil man diese Aktion am
Anfang des Programms nur einmal macht.
> Bei der CPU-Taktfrequenz hatte ich über Delayschleifen schon
> festgestellt, daß der externe Quarz seinen Dienst tut. Nur habe ich noch
> nicht getestet, ob es ein 8 MHz oder ein 7,3...MHz (für UART) drin ist.
Das solltest du aber wissen.
Allerdings: wenn der Wert nicht mit dem übereinstimmt, mit dem du
rechnest sollte sich zumindest beim Empfänger etwas tun. Du kriegst zwar
die falschen Zeichen, aber du kriegst zumindest irgendwelche Zeichen
> @ Hc Zimmerer
> Ausbau des µC ist schwierig, aber ich komme an die Kontakte. Könnte man
> hilfsweise auch die TX- und RX-Pins miteinenander verbinden - über einen
> 1k-Widerstand, damit nichts zerstört wird?
Meinst du die Tx/Rx Pins direkt am Prozessor?
Ich denke nicht das das funktionieren wird. Letztendes hängt es davon
ab, wer mehr "Kraft" hat: der µC, der seinen Ausgangspin auf zb 0 halten
will, oder der RS232-Treiber, der dieselbe Leitung partout auf 1 ziehen
will.
> Was ich zu erwähnen vergessen hatte: ich benutze ein Board AVR-P4ß 0535
Wo liegt dann das Problem?
Den Prozessor aus dem Sockel ziehen. Mit einem Stückchen Draht im Sockel
eine Verbindung der RX/Tx Pins herstellen und auf dem PC auf der
Tastatur klimpern. Wenn die Übertragungsstrecke steht, dann erscheint
das Getippte wieder auf dem PC. Gegentest: Drahtbrücke rausnehmen und
das mitschreiben auf dem PC muss aufhören.
> Ausbau des µC ist schwierig, aber ich komme an die Kontakte. Könnte man
> hilfsweise auch die TX- und RX-Pins miteinenander verbinden?
Nein, das wird nicht funktionieren. Der AVR wird sich gegenüber dem
MAX232 durchsetzen.
Abgesehen davon solltest Du erst mal die Baudrate ermitteln. Wenn die
nicht auf wenige einstellige Prozent stimmt, klappt die Übertragung
nicht. Allerdings sollte bei Abweichungen wie 8 MHz vs. 7,3 MHz schon
wenigstens Müll auf der Gegenseite ankommen.
>
> USARTinit();
> while (!(UCSRA & (1<<UDRE))) // warten bis Senden möglich
> { // while-Schleife ist hier
> unnötig!)
> }
> UDR = 'x';
> [/C]
>
> Nein.
> Lass die UART arbeiten und Initialisiere sie nicht innerhalb der
> Endlosschleife immer wieder neu.
sorry, habe ich falsch kopiert, die Initialisierung ist in Wirklichkeit
v o r dem Eintritt in die Endlosschleife. Aber sonst sind die Register
usw. richtig?
> die falschen Zeichen, aber du kriegst zumindest irgendwelche Zeichen
damit wäre ich als erste Erfolgkontrolle höchst zufrieden, bis der
UART-Quarz geliefert wird.
>
> Meinst du die Tx/Rx Pins direkt am Prozessor?
> Ich denke nicht das das funktionieren wird. Letztendes hängt es davon
> ab, wer mehr "Kraft" hat: der µC, der seinen Ausgangspin auf zb 0 halten
> will, oder der RS232-Treiber, der dieselbe Leitung partout auf 1 ziehen
> will.
Ja, ich hatte an die PINs direkt am µC gedacht, weil der Ausbau durch
darüberliegende Teile (LCD usw) sehr schwierig ist. Aber ich könnte auf
dem µC ein "Programm" laufen lassen, das die beiden PINs auf high oder
low hält???
Gruß
Alexander
Alexander Schmeil schrieb:
> Ja, ich hatte an die PINs direkt am µC gedacht, weil der Ausbau durch
> darüberliegende Teile (LCD usw) sehr schwierig ist. Aber ich könnte auf
> dem µC ein "Programm" laufen lassen, das die beiden PINs auf high oder
> low hält???
Und, was hilft dir das?
Es ist trotzdem (im Prinzip nach) nur 1 'Kabel' an dem alle Teilnehmer
hängen. Und wenn der eine auf 1 will und der andere auf 0, dann gibt es
ein Problem.
Bau die Hardware auseinander. Bei der Gelegenheit kannst du auch gleich
nachsehen, was auf deinem Quarz draufsteht :-)
Karl heinz Buchegger schrieb:
>
> Bau die Hardware auseinander. Bei der Gelegenheit kannst du auch gleich
> nachsehen, was auf deinem Quarz draufsteht :-)
Ich habe am MAX232 (der bei mir anders beschriftet ist) die TX- und
RX-Pins verbunden - und auf dem PC-Monitor waren die eingegebenen
Zeichen zu sehen - wie Du beschrieben hast - also ist die Schnittstelle
ok.
Als nächstes habe ich die bisher unbenutzten Verbindungen zu PB5 und PB6
zu RX und TX getauscht - danach kamen auf dem PC verquere Zeichen an,
die Übertragung mit "meinem" Code funktionierte also jetzt.
Zuletzt habe ich die Inschrift auf dem Quarz idenfizieren können, es war
einer für UART (7372800 Hz), den Wert ins Makefile geschrieben - nun
kommen ordentliche Zahlen an - und ich bin happy!
Ohne Eure Hilfe hätte ich mich noch lange mit der Software beschäftigt
und nie an die vertauschten Leitungen gedacht.
Vielen Dank!
Gruß
Alexander
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|