Hi,
ich habe mir ein kleines Testprogramm für den Mega128 geschrieben.
Alles ist bestens, mein AVR-Studio 4.07 bringt aber bei "out
DDRF,temp1" und "out DDRG,temp1" und den entsprechenden
Port-Ausgaben den Fehler:
Illegal argument type or count
Bei DDRA und PortA klappt alles bestens. Was habe ich übersehen?!?
Hier der ganze Code:
.include "m128def.inc"
.def temp1 = r16
.def tx = r17
.cseg
rjmp start ;RESET
reti ;INT0 External Interrupt Request 0
reti ;INT1 External Interrupt Request 1
reti ;INT2 External Interrupt Request 2
reti ;INT3 External Interrupt Request 3
reti ;INT4 External Interrupt Request 4
reti ;INT5 External Interrupt Request 5
reti ;INT6 External Interrupt Request 6
reti ;INT7 External Interrupt Request 7
reti ;TIMER2 COMP Timer/Counter2 Compare Match
reti ;TIMER2 OVF Timer/Counter2 Overflow
reti ;TIMER1 CAPT Timer/Counter1 Capture Event
reti ;TIMER1 COMPA Timer/Counter1 Compare Match A
reti ;TIMER1 COMPB Timer/Counter1 Compare Match B
reti ;TIMER1 OVF Timer/Counter1 Overflow
reti ;TIMER0 COMP Timer/Counter0 Compare Match
reti ;TIMER0 OVF Timer/Counter0 Overflow
reti ;SPI, STC SPI Serial Transfer Complete
reti ;USART0, RX USART0, Rx Complete
reti ;USART0, UDRE USART0 Data Register Empty
reti ;USART0, TX USART0, Tx Complete
reti ;ADC ADC Conversion Complete
reti ;EE READY EEPROM Ready
reti ;ANALOG COMP Analog Comparator
reti ;TIMER1 COMPC Timer/Countre1 Compare Match C
reti ;TIMER3 CAPT Timer/Counter3 Capture Event
reti ;TIMER3 COMPA Timer/Counter3 Compare Match A
reti ;TIMER3 COMPB Timer/Counter3 Compare Match B
reti ;TIMER3 COMPC Timer/Counter3 Compare Match C
reti ;TIMER3 OVF Timer/Counter3 Overflow
reti ;USART1, RX USART1, Rx Complete
reti ;USART1, UDRE USART1 Data Register Empty
reti ;USART1, TX USART1, Tx Complete
reti ;TWI Two-wire Serial Interface
reti ;SPM READY Store Program Memory Ready
start:
ldi temp1,LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse
out SPL,temp1
ldi temp1,HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse
out SPH,temp1
;USART einstellen
;ldi temp1,0b00000000 ;Baudrate ...
;out UBRRH, temp1
;ldi temp1,8000000/(9600*16)-1 ;Baudrate einstellen
;out UBRRL, temp1 ;...einstellen (9600 @ 8MHz)
;sbi UCSRB,TXEN ;TX aktivieren
;alles auf Ausgang
ldi temp1,0xFF
out DDRA,temp1
out DDRB,temp1
out DDRC,temp1
out DDRD,temp1
out DDRE,temp1
out DDRF,temp1
out DDRG,temp1
ldi tx,65 ;als Test später immer ein "A" senden
rjmp MainLoop
reti
serout:
;sbis UCSRA,UDRE ;Warten, bis UDR für das nächste Byte bereit ist
;rjmp serout
;out UDR, tx
ret ;zurück zum Hauptprogramm
Wait_500ms:
; =============================
; Warteschleifen-Generator
; 4000000 Zyklen:
; -----------------------------
; warte 3999996 Zyklen:
ldi R29, $24
WGLOOP0: ldi R30, $BC
WGLOOP1: ldi R31, $C4
WGLOOP2: dec R31
brne WGLOOP2
dec R30
brne WGLOOP1
dec R29
brne WGLOOP0
; -----------------------------
; warte 3 Zyklen:
ldi R29, $01
WGLOOP3: dec R29
brne WGLOOP3
; -----------------------------
; warte 1 Zyklus:
nop
; =============================
ret
MainLoop:
ldi temp1,0x00
out PortA,temp1
out PortB,temp1
out PortC,temp1
out PortD,temp1
out PortE,temp1
out PortF,temp1
out PortG,temp1
;rcall serout
rcall Wait_500ms
ldi temp1,0xFF
out PortA,temp1
out PortB,temp1
out PortC,temp1
out PortD,temp1
out PortE,temp1
out PortF,temp1
out PortG,temp1
;rcall serout
rcall Wait_500ms
rjmp MainLoop
In der m128def.inc stehen alles Werte für DDRF usw.
Danke für Tips!
Sebastian
Hi,
also langsam verzweifle ich echt. Warum verdammt geht das nicht. Warum
hab' ich kein Zugriff auf PortF und PortG.
Das AVR Studio 3.56 zeigt das gleiche Phänomen.
Oder anders gefragt: Wer hat schonmal einen Mega128 in Assembler
progammiert und dabei die oben genannten Ports verwendet?
Danke schonmal für jede Hilfe!
Sebastian
P.S.: Danke für das Löschen des überflüssigen Threads!
Hi,
so, nun habe ich die Lösung gefunden. DDRF, DDRG, PortF, PortG und auch
UBBR0H haben alle Adressen über $63. Da funktioniert "out" schlicht
und einfach nicht mehr. Da muß man immer "sts" verwenden.
Ich frage mich nur, warum es "out" dann gibt, wenn "sts" das auch
kann und (!) für höhere Adressen...
Sebastian
lds und sts benötigen 2 Taktzyklen, in und out dagegen nur 1.
Bei der Konzeption des AVR hat man wohl den I/O-Bereich mit 64 Adressen
als ausreichend dimensioniert erachtet.
Hi,
Du hast Recht, verschiedene Taktzyklen...
Aber etwas ist noch seltsam: "sts DDRA,temp1" wird zwar compiliert,
aber das Programm läuft dann nicht korrekt. Dies tut es nur bei "out
DDRA,temp1". An was kann das liegen?
Danke!
Sebastian
bei I/O < 63 müssen 20 Hex addiert werden, der I/O-Bereich 0x0-0x3F wird
an den adressen 0x20 - 0x5F eingeblendet, da ja an 0x00-0x1F die
internen Register R0-R31 liegen. Hier funktioniert übrigens ebenfalls
LDS und STS
> Bei der Konzeption des AVR hat man wohl den I/O-Bereich mit> 64 Adressen als ausreichend dimensioniert erachtet.
Völlig unverständlich, wie Atmel in der heutigen Zeit noch so
engstirnig sein kann. Oder machen die das extra, um so ein guten
Vorwand für eine völlig neue Architektur zu haben?
>Völlig unverständlich, wie Atmel in der heutigen Zeit noch so>engstirnig sein kann. Oder machen die das extra, um so ein guten>Vorwand für eine völlig neue Architektur zu haben?
Wieso engstirnig? Was für ein Vorwand?
Wenn man einen Controller entwickelt muss man halt irgendwo Kompromisse
machen. Klar, daß nach ein paar Jahren irgendwo eine Grenze erreicht ist
(die AVRs gibt es seit 1997!).
meine auch, dass das nicht mit Engstirnigkeit/mangelnder Weitsicht zu
tun hat. Ist dasselbe Problem wie beim ldi, ori etc.
Opcode,Ziel/Quellregister, Portadresse - wenn man das in 16bit
unterbringen will, muss man eben Kompromisse machen. Und der Kompromiss
war von Anfang an gut (I/O-Zugriffe gingen schon immer auch als
Speicherzugriff), für die oft benötigten Ports gab es eben eine kürzere
und schnellere Alternative. Aber statt froh zu sein, wird gemeckert...,
so ist das nun mal :-)