Hallo, ich habe folgendes Programm geschrieben um per Hyperterminal
gesendete Daten mit einem Atmega 48 zu empfangen:
1
.include "m48def.inc"
2
.org 0x000
3
rjmp RESET
4
.org 0x012
5
rjmp USART_RXC
6
7
USART_RXC:
8
ldi r16, 0b01000000
9
out TCCR0A, r16
10
reti
11
reset:
12
rcall INIT
13
14
15
16
sei
17
main:
18
rjmp main
19
20
21
22
INIT:
23
;Ports setzen
24
;Summer
25
ldi r16, 0b11000000
26
out DDRD, r16
27
28
29
30
31
;Timer für Summer (aus)
32
ldi r16, 0b00000000
33
out TCCR0A, r16
34
ldi r16, 0b00000010
35
out TCCR0B, r16
36
37
;UART RX 2400 baud, RX INT
38
ldi r16, 0b10010000
39
sts UCSR0B, r16
40
ldi r16, 0b00000110
41
sts UCSR0C, r16
42
ldi r16, 95
43
sts UBRR0L, r16
44
ret
Es soll einfach nur ein Summer angehen wenn irgendein Zeichen empfangen
worden ist. Der Summer funktioniert, daten an den Pc senden funktioniert
auch (hatte ich mal kurz getestet)
Sieht jemand einen Fehler?
Jochen schrieb:> ;UART RX 2400 baud, RX INT> ldi r16, 0b10010000> sts UCSR0B, r16> ldi r16, 0b00000110> sts UCSR0C, r16> ldi r16, 95> sts UBRR0L, r16> ret
Kann man die elend langen Bitschreibweise mal durch was klar
ersichtliches ersetzen(oder gleich verbieten)? (1 << UMSEL)|(1 <<
wasweißich) kann ich viel leichter optisch dekodieren, als das
Bitgewusel. In ein paar Monaten schon kann die Schreibfaulheit nach
hinten los gehen, wenn man sich slebst nicht mehr auskennt. Code, der
selbstdokumentierend ist, braucht nicht viel weitere Erklärungen.
mfg mf
PS: Genau darum muss ich jetzt fragen: Ist RXEN gesetzt?
Ich schreib mal kurz auf was die Bytes machen:
ldi r16, 0b10010000
sts UCSR0B, r16
RXCIE0 setzen
RXEN0 setzen
ldi r16, 0b00000110
sts UCSR0C, r16
UCSZ01 setzen
UCSZ00 setzen
Jochen schrieb:> Ich schreib mal kurz auf was die Bytes machen:> ldi r16, 0b10010000> sts UCSR0B, r16> RXCIE0 setzen> RXEN0 setzen
UCSR0B wird laut Datenblatt mittels out angesprochen und nicht mit sts
Und warum schreibst du dann nicht gleich
ldi r16, (1<<RXCIE0) | (1<<RXEN0)
dann brauchst du das keinem erklären und auch keinen Kommentar
> ldi r16, 0b00000110> sts UCSR0C, r16> UCSZ01 setzen> UCSZ00 setzen
AUch UCSR0C wird laut Datenblatt mit out angesprochen.
Das ist NICHT egal, weil die Adresslage eine andere ist, je nachdem ob
du einen out oder einen sts benutzt. Im Beschreibungsteil des
Datenblattes sind immer wieder Codeschnipsel enthalten, aus denen
hervorgeht, welchen Befehl du benutzen musst.
Hallo Karl Heinz. Also wenn ich das mit out schreibe kriege ich immer
einen Fehler "Operand out of Range"
Vielleicht gibts da Unterschiede zwischen den 3 Atmega (48/88/168) ?
Jochen schrieb:> Hallo Karl Heinz. Also wenn ich das mit out schreibe kriege ich immer> einen Fehler "Operand out of Range"> Vielleicht gibts da Unterschiede zwischen den 3 Atmega (48/88/168) ?
Du hast recht.
Hab grade den Abschnitt 'Register Summary' studiert. Das scheint sich
tatsächlich um einen Fehler im UART Abschnitt im Datenblatt zu handeln.
Die Register sind allesamt nicht per out zu erreichen. Da war ich zu
voreilig und habe dem Code im Abschnitt vertraut.
Ich konnte im Datenblatt nichts darüber finden, dass der Stackpointer
automatisch korrekt initialisiert wird. D.h. du solltest das selbst in
die Hand nahmen.
Karl Heinz Buchegger schrieb:> Ich konnte im Datenblatt nichts darüber finden, dass der Stackpointer> automatisch korrekt initialisiert wird.
"Initial Value" unter 6.5.1.
Fehler gefunden. Ich habe nur 2 USB Ports und habe daher mein AVR ISP
MKII herausgezogen und den USB seriell Wandler eingesteckt. Aber
anscheinend hält der stromlose Programmer den Controller im Reset.
ARGH
Vielen Dank für eure Hilfe!
Karl Heinz Buchegger schrieb:> Hä? Hab ich das falsche Datenblatt oder ihr?> Ich verwende das da
Und dort unter 7.6.1 "Initial Value".
Der Text suggeriert in der Tat was anderes. Ist meiner Meinung nach aber
nur als Hinweis gedacht, wo der Stack-Pointer starten muss, ohne dabei
zu erwähnen, dass er bereits einen passenden Default-Wert hat.
In "meinem" Datenblatt sieht der Text übrigens so aus:
1
The Stack in the data SRAM must be defined by the program before any
2
subroutine calls are executed or interrupts are enabled. Initial Stack
3
Pointer value equals the last address of the internal SRAM and the Stack
4
Pointer must be set to point above start of the SRAM, see Table 7-3 on
Stefan Ernst schrieb:> Karl Heinz Buchegger schrieb:>> Hä? Hab ich das falsche Datenblatt oder ihr?>> Ich verwende das da>> Und dort unter 7.6.1 "Initial Value".
Hmm.
Anscheinend gibt es da mehrere Versionen. Goggle hat mir diesen Hit als
ersten Treffer bei Atmel rausgeworfen
7.6.1 ist bei mir
7.6.1 SPH and SPL – Stack pointer high and stack pointer low register
Und Initial Values werden da keine erwähnt.
Thomas Eckmann schrieb:> Karl Heinz Buchegger schrieb:>> Und Initial Values werden da keine erwähnt.> Steht doch darunter:> Initial Value: RAMEND>
Autsch. Du hast recht.
Wenn man mir freundlich mit dem Brett den Hinterkopf tätschelt, dann seh
ich das sogar :-)
Danke.