Hallo,
ich verzweifel gerade etwas an einem kleinen ATmega8 evtl. hat hier
jemand einen Rat oder Tipp was ich falsch mache oder übersehe.
Schaltung wie hier im Tutorial mit folgendem Programm:
-----------------------------------------------------------
.include "m8def.inc"
.def temp = R16
.equ CLOCK = 3686411
.equ BAUD = 9600
.equ UBRRVAL = CLOCK/(BAUD*16)-1
.org 0x00
rjmp main
.org URXCaddr ;Interruptvektor für UART-Empfang
rjmp int_rxc
;Hauptprogramm
main:
ldi temp, LOW(RAMEND)
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
; Baudrate einstellen
ldi temp, LOW(UBRRVAL)
out UBRRL, temp
ldi temp, HIGH(UBRRVAL)
out UBRRH, temp
; Frame-Format: 8 Bit
ldi temp, (1<<URSEL)|(3<<UCSZ0)
out UCSRC, temp
sbi UCSRB, RXCIE ;Interrupt bei Empfang
sbi UCSRB, RXEN ;RX (Empfang) aktivieren
sbi UCSRB, TXEN ;TX (Senden) aktivieren
ldi temp, 0x01 ;0x01 ins Arbeitsregister r16 laden
out DDRC, temp ;Inhalt von r16 ins IO-Register DDRC
ausgeben
ldi temp, 0x01
out PORTC, temp ;PORTC auf 0x01 setzen -> Port PC0
sei ;Interrupts global aktivieren
loop:
cbi PINC, 0 ;An
rcall wait ;warten
sbi PINC, 0 ;aus
rcall wait ;warten
rjmp loop ;Endlosschleife
;Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
push temp
ldi temp, 'H'
rcall serout
ldi temp, 'a'
rcall serout
ldi temp, 'l'
rcall serout
ldi temp, 'l'
rcall serout
ldi temp, 'o'
rcall serout
ldi temp, 10
rcall serout
ldi temp, 13
rcall serout
pop temp ; temp wiederherstellen
reti ; Interrupt beenden
serout:
sbis UCSRA,UDRE ;Warten bis UDR für das nächste
;Byte bereit ist
rjmp serout
out UDR, temp
ret
wait:
; =============================
; delay loop generator
; 18432000 cycles:
; -----------------------------
; delaying 18431985 cycles:
ldi R17, $A9
WGLOOP0: ldi R18, $92
WGLOOP1: ldi R19, $F8
WGLOOP2: dec R19
brne WGLOOP2
dec R18
brne WGLOOP1
dec R17
brne WGLOOP0
; -----------------------------
; delaying 15 cycles:
ldi R17, $05
WGLOOP3: dec R17
brne WGLOOP3
; =============================
ret
------ENDE-------
Das Problem ist ich bekomme weder eine serielle Verbindung zum
Controller noch blinkt Port PC0. Der Controller lässt sich mit YAAP
einwandfrei beschreiben und auslesen.
Guten Rutsch
Reinhard
Blinken wird's so sicher nicht. PINC und PORTC verwechselt. Die Interrupt-Routine ist bemerkenswert - statt den Status zu retten, ein konsequenter Verzicht auf alle Befehle die was dran ändern ;-). Sieht man nicht oft.
Hallo,
folgendermaßen würde ich die Interruptroutine noch abändern und wie
oben schon gesagt noch statt PINC PortC schreiben.
;Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
push temp
in temp,SREG ; Statusregister sichern
push temp ; dito
ldi temp, 'H'
rcall serout
ldi temp, 'a'
rcall serout
ldi temp, 'l'
rcall serout
ldi temp, 'l'
rcall serout
ldi temp, 'o'
rcall serout
ldi temp, 10
rcall serout
ldi temp, 13
rcall serout
pop temp1 ; Statusregister vom Stack holen
out SREG, temp1 ; dito
pop temp ; temp wiederherstellen
reti
Gruß
Man sollte sich solche Art der schlechten Interruptprogrammierung garnicht erst angewöhnen. Das verstößt nämlich gegen die ersten 3 Lehrsätze der Interruptprogramierung: 1. Halte Interrupts so kurz wie möglich 2. Halte Interrupts so kurz wie möglich 3. Halte Interrupts so kurz wie möglich Und serielle Ausgabezeiten nutzlos zu verwarten, gulpt hier schon stolze 19200 Zyklen kostbarer CPU-Zeit: 3686411 / 9600 10 5 Peter
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.