UART ATmega16 Interrupt geht nicht

Gast #1635958
Lesenswert?

Hi Leute.

Ich habe mit meinem atmega16 bis jetzt nur daten gesendet. Dann dachte 
ich mir, ich könnte auch mal welche empfangen (per Interrupt). Jetzt 
kommt das problem. ich sende ein einziges Zeichen und der interrupt wird 
über 10 in der sekunde ausgelöst und das bis ich die spannung abschalte 
oder reset mache.

Könnt ihr mir helfen???

Gruß M.H.
Gast #1635979
Lesenswert?

Der RXCI löst solange aus, bis UDR gelesen wurde. Nur die ISR aufsetzen 
aber UDR nicht auslesen würde das von Dir beschriebene Symptom ergeben.

Da Du UDR aber ausliest, hat Dein Fehler einen anderen Grund, dann poste 
doch mal mehr Code.
Gast #1635991
Lesenswert?

Hier ist ein ausschnitt/zusammenschnitt des Codes:
1
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
2
    out     UCSRC, temp
3
 
4
    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang
5
    sbi     UCSRB, RXEN
6
sbi ucsrb, txen
7

8
    
9
    sei                                     ; Interrupts global aktivieren
10
    
11
schleife:
12
    rjmp schleife
13

14

15

16
interrupt:
17
push r16
18

19
in r16, udr
20
out porta, r16
21
pop r16
22

23

24
reti
Gast #1636015
Lesenswert?

1
.org 0x00
2
        rjmp start
3
 
4
.org URXCaddr                                   ; Interruptvektor für UART-Empfang
5
        rjmp interrupt
6

7

8
start:
9
    ldi r16, 0xFF
10
  out ddra, r16
11
clr r16
12
out porta, r16
13

14
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
15
    out     UCSRC, temp
16
 
17
    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang
18
    sbi     UCSRB, RXEN
19
sbi ucsrb, txen
20

21
    sei                                     ; Interrupts global aktivieren
22
    
23
schleife:
24
    rjmp schleife
25

26

27

28
interrupt:
29
push r16
30

31
in r16, udr
32
out porta, r16
33
pop r16
34

35

36
reti
Gast #1636022
Lesenswert?

.equ F_CPU = 4000000                            ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille 
Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit 
zu hoch!"
.endif


(siehe avr tutorial)
Gast #1636036
Lesenswert?

; Stackpointer initialisieren

    ldi     temp, LOW(RAMEND)
    out     SPL, temp
    ldi     temp, HIGH(RAMEND)
    out     SPH, temp

    ; Baudrate einstellen

    ldi     temp, HIGH(UBRR_VAL)
    out     UBRRH, temp
    ldi     temp, LOW(UBRR_VAL)
    out     UBRRL, temp
Gast #1636048
Lesenswert?

1
.def temp = r20
2
.equ F_CPU = 4000000                            ; Systemtakt in Hz
3
.equ BAUD  = 9600                               ; Baudrate
4
 
5
; Berechnungen
6
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
7
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
8
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
9
 
10
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
11
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
12
.endif
13

14
.cseg
15
.org 0x00
16
        rjmp start
17
 
18
.org URXCaddr                                   ; Interruptvektor für UART-Empfang
19
        rjmp interrupt
20

21

22

23
start:ldi r16, low(RAMEND)
24
ldi r17, high(RAMEND)
25
out spl, r16
26
out sph, r16
27

28
 ldi     temp, HIGH(UBRR_VAL)
29
    out     UBRRH, temp
30
    ldi     temp, LOW(UBRR_VAL)
31
    out     UBRRL, temp
32

33

34

35

36
    ldi r16, 0xFF
37
  out ddra, r16
38
clr r16
39
out porta, r16
40

41
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
42
    out     UCSRC, temp
43
 
44
    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang
45
    sbi     UCSRB, RXEN
46
sbi ucsrb, txen
47

48
    sei                                     ; Interrupts global aktivieren
49
    
50
schleife:
51
    rjmp schleife
52

53

54

55
interrupt:
56
push r16
57

58
in r16, udr
59
out porta, r16
60
pop r16
61

62

63
reti
64
.exit
Gast #1636049
Lesenswert?

.def temp = r20
.equ F_CPU = 4000000                            ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille 
Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit 
zu hoch!"
.endif

.cseg
.org 0x00
        rjmp start

.org URXCaddr                                   ; Interruptvektor für 
UART-Empfang
        rjmp interrupt



start:ldi r16, low(RAMEND)
ldi r17, high(RAMEND)
out spl, r16
out sph, r17

 ldi     temp, HIGH(UBRR_VAL)
    out     UBRRH, temp
    ldi     temp, LOW(UBRR_VAL)
    out     UBRRL, temp




    ldi r16, 0xFF
  out ddra, r16
clr r16
out porta, r16

    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
    out     UCSRC, temp

    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang
    sbi     UCSRB, RXEN
sbi ucsrb, txen

    sei                                     ; Interrupts global 
aktivieren

schleife:
    rjmp schleife



interrupt:
push r16

in r16, udr
out porta, r16
pop r16


reti
.exit
Gast #1636053
Lesenswert?

tschuldigung. so ist es richtig
1
.def temp = r20
2
.equ F_CPU = 4000000                            ; Systemtakt in Hz
3
.equ BAUD  = 9600                               ; Baudrate
4
 
5
; Berechnungen
6
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
7
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate
8
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
9
 
10
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
11
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
12
.endif
13

14
.cseg
15
.org 0x00
16
        rjmp start
17
 
18
.org URXCaddr                                   ; Interruptvektor für UART-Empfang
19
        rjmp interrupt
20

21

22

23
start:ldi r16, low(RAMEND)
24
ldi r17, high(RAMEND)
25
out spl, r16
26
out sph, r17
27

28
 ldi     temp, HIGH(UBRR_VAL)
29
    out     UBRRH, temp
30
    ldi     temp, LOW(UBRR_VAL)
31
    out     UBRRL, temp
32

33

34

35

36
    ldi r16, 0xFF
37
  out ddra, r16
38
clr r16
39
out porta, r16
40

41
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
42
    out     UCSRC, temp
43
 
44
    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang
45
    sbi     UCSRB, RXEN
46
sbi ucsrb, txen
47

48
    sei                                     ; Interrupts global aktivieren
49
    
50
schleife:
51
    rjmp schleife
52

53

54

55
interrupt:
56
push r16
57

58
in r16, udr
59
out porta, r16
60
pop r16
61

62

63

64
reti
65
.exit
Gast #1636055
Lesenswert?

> Willst du uns eigentlich veralbern?

Ach geh, jetzt dauerts nimmer lang und der Code könnte fast vollständig 
sein. Wär ja auch zu einfach alles zusammen zu posten, und nur halb so 
spannend sowieso. Wer helfen will muss schon ein bisschen Initiative 
zeigen und sich den Baukausten selber zusammensetzen, und falls dann der 
Fehler des TO reproduzierbar sein sollte, dann möge selbiger den 
Quellcode bitte fertig korrigiert servieren!

</sarkasmus>

Nix für ungut.

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