pacer_one
20.01.2008, 17:23
Hallo Leute,
habe mir ein kleines Programm gestrickt, dass Zeichen aus dem RAM an das Hyperterminal schicken soll. Leider bringe ich meinen Atmel nicht dazu einen Interrupt (UTXCaddr) auszulösen.
Eigentlich habe ich alles gemacht was zu tun ist:
sbi UCSRB,TXCIE ; Interrupt für "senden fertig" aktivieren
sei ; globale Interruptfreigabe
sbi UCSRA,TXC ; Initialisierung des Interrupts
Was habe ich vergessen?
.NOLIST ; List-Output unterdrücken
.INCLUDE <m8def.inc> ; das gibt es für jeden Controllertyp
.def temp = R16 ; für Interrupt
.def ZEICHEN = R17
.equ VARIABLE = 0 ; Beschreibung der Variable
;------------------------------------------------------
; Peripherie initialisieren
;------------------------------------------------------
.equ F_CPU = 7273800 ; 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
.LIST ; List-Output wieder aufdrehen
.CSEG ; was nun folgt, gehört in den FLASH-Speicher
;------------------------------------------------------
; Start Adresse 0000 /Interruptvektoren
;------------------------------------------------------
.org 0x000
rjmp Init ; Interruptvektoren überspringen
.org UTXCaddr ; UART Transmit Complete Interrupt
rjmp serout
;------------------------------------------------------
; INITIALIZE
;------------------------------------------------------
INIT:
;Stack Pointer setzen
ldi temp,high(RAMEND)
out SPH,temp
ldi temp,low(RAMEND)
out SPL,temp
; Baudrate einstellen
ldi temp, HIGH(UBRR_VAL)
out UBRRH, temp
ldi temp, LOW(UBRR_VAL)
out UBRRL, temp
; Frame-Format: 1 Stop-Bits, 8 Bit
ldi temp, (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
out UCSRC, temp
sbi UCSRB,TXEN ; Sender aktivieren
sbi UCSRB,TXCIE ; Interrupt für "senden fertig" aktivieren
sei ; globale Interruptfreigabe
sbi UCSRA,TXC ; Initialisierung des Interrupts
;------------------------------------------------------
; HAUPTSCHLEIFE
;------------------------------------------------------
Hauptschleife:
rjmp Hauptschleife
;------------------------------------------------------
; Subroutinen / ISRs
;------------------------------------------------------
;Auslesen der Zeichen und bereitstellen in ZEICHEN
;Erhöhen des Z-Pointers; bei leerem Zeichen --> Zurücksetzen des Z-Pointers
serout:
lpm ; Erstes Byte des Strings nach R0 lesen
mov ZEICHEN,R0
adiw ZL, 1 ; Adresse des Z-Pointers um 1 erhöhen
tst R0 ; Inhalt von R0 auf Bull testen
brbc 1,sprung_b
ldi ZL, LOW(Daten*2) ; Adresse des ersten Strings in den
ldi ZH, HIGH(Daten*2) ; Z-Pointer laden
sprung_b:
out UDR, ZEICHEN ; Zeichen auf UART ausgeben
reti
;------------------------------------------------------
; Datenbereich
;------------------------------------------------------
Daten:
.db 0x12, 0x12
.db 0x20, 0x20
.db 0x63, 0x63
.db 0x58, 0x00
;------------------------------------------------------
; ENDE
;------------------------------------------------------
Ende:
rjmp Ende
habe mir ein kleines Programm gestrickt, dass Zeichen aus dem RAM an das Hyperterminal schicken soll. Leider bringe ich meinen Atmel nicht dazu einen Interrupt (UTXCaddr) auszulösen.
Eigentlich habe ich alles gemacht was zu tun ist:
sbi UCSRB,TXCIE ; Interrupt für "senden fertig" aktivieren
sei ; globale Interruptfreigabe
sbi UCSRA,TXC ; Initialisierung des Interrupts
Was habe ich vergessen?
.NOLIST ; List-Output unterdrücken
.INCLUDE <m8def.inc> ; das gibt es für jeden Controllertyp
.def temp = R16 ; für Interrupt
.def ZEICHEN = R17
.equ VARIABLE = 0 ; Beschreibung der Variable
;------------------------------------------------------
; Peripherie initialisieren
;------------------------------------------------------
.equ F_CPU = 7273800 ; 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
.LIST ; List-Output wieder aufdrehen
.CSEG ; was nun folgt, gehört in den FLASH-Speicher
;------------------------------------------------------
; Start Adresse 0000 /Interruptvektoren
;------------------------------------------------------
.org 0x000
rjmp Init ; Interruptvektoren überspringen
.org UTXCaddr ; UART Transmit Complete Interrupt
rjmp serout
;------------------------------------------------------
; INITIALIZE
;------------------------------------------------------
INIT:
;Stack Pointer setzen
ldi temp,high(RAMEND)
out SPH,temp
ldi temp,low(RAMEND)
out SPL,temp
; Baudrate einstellen
ldi temp, HIGH(UBRR_VAL)
out UBRRH, temp
ldi temp, LOW(UBRR_VAL)
out UBRRL, temp
; Frame-Format: 1 Stop-Bits, 8 Bit
ldi temp, (1<<URSEL)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)
out UCSRC, temp
sbi UCSRB,TXEN ; Sender aktivieren
sbi UCSRB,TXCIE ; Interrupt für "senden fertig" aktivieren
sei ; globale Interruptfreigabe
sbi UCSRA,TXC ; Initialisierung des Interrupts
;------------------------------------------------------
; HAUPTSCHLEIFE
;------------------------------------------------------
Hauptschleife:
rjmp Hauptschleife
;------------------------------------------------------
; Subroutinen / ISRs
;------------------------------------------------------
;Auslesen der Zeichen und bereitstellen in ZEICHEN
;Erhöhen des Z-Pointers; bei leerem Zeichen --> Zurücksetzen des Z-Pointers
serout:
lpm ; Erstes Byte des Strings nach R0 lesen
mov ZEICHEN,R0
adiw ZL, 1 ; Adresse des Z-Pointers um 1 erhöhen
tst R0 ; Inhalt von R0 auf Bull testen
brbc 1,sprung_b
ldi ZL, LOW(Daten*2) ; Adresse des ersten Strings in den
ldi ZH, HIGH(Daten*2) ; Z-Pointer laden
sprung_b:
out UDR, ZEICHEN ; Zeichen auf UART ausgeben
reti
;------------------------------------------------------
; Datenbereich
;------------------------------------------------------
Daten:
.db 0x12, 0x12
.db 0x20, 0x20
.db 0x63, 0x63
.db 0x58, 0x00
;------------------------------------------------------
; ENDE
;------------------------------------------------------
Ende:
rjmp Ende