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
Hi mmerten, danke für den Tip! Mit "sts DDRA+0x20,temp1" usw. geht's wunderbar! :-) Sebastian
> 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?
@mathew You're sure you're talking about an Atmel device ? I just checked the Atmel site and the search for SX 460 didn't find anything.
>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 :-)
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.