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.
Hi Du hast doch bestimmt ein Programm zu diesem Fehler. MfG Spess
Der Interrupt löst solange aus, bis Du die Daten aus UDR abgeholt hast.
wie meinst du abgeholt?? ich mach das halt so: interrupt: push r16 in r16, udr out porta, r16 pop r16 reti
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.
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 |
Genau die interessanten Stellen zeigst du nicht. Wie trägst du das Label interrupt: in die Tabelle mit den Interruptvektoren ein? Manipulierst du vorher schon porta? So dass du eigentlich nicht die Aktion in der IST sondern die Auswirkungen eines ständigen Resettens siehst...
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 |
Hi Und wo wird das Baudratenregister initialisiert? MfG Spess
.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)
mit dem baudratenregister dürfte eig. nix sein. weil senden klappt ja
Hi Und wo steht so etwas wie: ldi r16,High($XYZ) ; out UBRRH,r16 ldi r16,Low($XYZ) ; out UBRRL,r16 MfG spess
; 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
ldi temp, HIGH(RAMEND) out SPH, temp ldi temp, LOW(RAMEND) out SPL, temp
Hi Was sollen diese Fragmente? Stell dein komplettes Programm hier rein oder vergiss es. Mfg Spess
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 |
.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
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 |
> 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.
Hi Und wo ist die Include-Anweisung? .include "m16def.inc" MfG Spess
die .include ist ganz oben bloß beim kopieren nicht mit markiert
Hi An deinem Programm kann ich erstmal keinen Fehler erkennen Und woran erkennst du jetzt, das der Interrupt so oft auslöst? MfG Spess
die ausgabe an porta ändert sich um die 10 mal pro sekunde (wenn ich ein zeichen sende). Dercontroller empfängt irgendwelchen schrott
Hi Ich habe mal das Programm simuliert. Es macht eigentlich das ,was es es soll. Wie sieht den deine Hardware aus. MfG Spess
also schema: atmega16 => max232 => Kabel(ca. 80cm) => PC noch was. das senden der daten klappt einwandfrei.
Hi >atmega16 => max232 => Kabel(ca. 80cm) => PC >noch was. das senden der daten klappt einwandfrei. Ich frage trotzdem: Ist auch die Masseverbindung in Ordnung? MfG Spess
Hi Hast du eine Möglichkeit, DSO/LA, dir das Signal anzusehen? MfG Spess
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.