Atmega 48 UART Daten empfangen

Gast #3003468
Lesenswert?

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?
#3003569
Lesenswert?

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?
#3003621
Lesenswert?

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.
#3003633
Lesenswert?

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.
(Firma: matzetronics) #3003673
Lesenswert?

Aargh, wenn du im Interrupt R16 benutzt, muss das vorher gerettet 
werden.
Normalerweise beginnt eine ISR mit:
1
; sichererplatz ist ein beliebiges, sonst unbenutztes register
2
       mov sichererplatz, SREG
3
       push   r16
4
; nun mache ich mit r16 rum
5
; und am ende:
6
      pop     r16
7
      mov     SREG,sichererplatz
8
      reti
Da deine Hauptschleife noch nix tut, ist das im Moment noch nicht 
wichtig. Aber später wunderst du dich.
Gast #3003744
Lesenswert?

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!
#3003794
Lesenswert?

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
5
page 18.
#3003811
Lesenswert?

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.

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