blamaster,
so wie's PicNick in Basic geschrieben hat, hatte ich's auch gemeint. In Assembler sieht's ganz ähnlich aus. Nach ein bisschen Herumprobieren kam mir eine echte Sprungtabelle als die einfachste Methode (in Assembler) vor. Dann braucht man aber doppelt soviel Platz für die Tabelle, als wenn man Port- und Pin-Nummer in einem Byte kodiert ablegt. Es ist aber einfacher, über die Sprungtabelle direkt eine Auswertungsprozedur anzuspringen, als das gelesene Tabellenbyte zu dekodieren. Das kommt daher, dass man beim Atmel die Ports nur direkt (immediate) adressieren kann.
Zur Information hänge ich das Beispiel unten an.
mare_crisium
Code:;*----------------------------------- ; BEISPIEL Tabelle_V01.asm ; Entwicklungsversion ;*----------------------------------- ;* Einbinden ;* .device ATmega8 .include "m8def.inc" ;*----------------------------------- ;* Definitionen ;* .equ PORTA = 0x1B ;*------------------------------------ ;* PROCEDURE TBL_CALL ;* ;* Die Prozedure TBL_JMP liest aus einer Sprung- ;* tabelle, die im Programmspeicher abgelegt ;* ist, ein 2-Byte-Adresse aus. Sie wird als ;* Programmadresse angesprungen. ; ; Eingangsvariablen ; zh:zl: enhält den Zeiger auf die RAM-Adresse, ; an der die Sprungtabelle beginnt ; r16: enthält den Index der Adresse, die ; angesprungen werden soll ; ; Ausgangsvariablen ; keine ; ; geänderte Register ; zh,zl ; ; geänderte Ports ; keine ; TBL_CALL: push r17 in r17,SREG push r17 clr r17 add zl,r16 adc zh,r17 add zl,zl adc zh,zh lpm r17,z+ lpm zh,z mov zl,r17 pop r17 out SREG,r17 pop r17 ijmp /*------------------------------------ SPRUNGTABELLE */ // 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 SPRUNG_TBL: .dw SET_PORTA0, RES_PORTA0 ; ... usw. //... .dw SET_PORTC7, RES_PORTC7 /*------------------------------------ PROCEDURE EVAL_RS485 Die Prozedure EVAL_RS485 wertet ein Datenbyte aus, das über die RS485 empfangen wurde. Das Datenbyte dient als Zeiger in die Sprungtabelle SPRUNG_TBL. Die Einträge enthalten die Adresse je einer Prozedur, die an einem bestimmten Port einen bestimmten Pin setzt oder zurücksetzt. Eingangsvariablen r16: enthält den das Datenbyte, das ausgewertet werden soll Ausgangsvariablen r16: enthält das ungeänderte Datenbyte geänderte Register keine geänderte Ports PORTA,PORTB,PORTC, je nach Datenbyte */ EVAL_RS485: push r16 push zl in zl,SREG push zl push zh ldi zl,low(SPRUNG_TBL); zh:zl := Adresse der Tabelle ldi zh,high(SPRUNG_TBL) rcall TBL_CALL ; ausgewählte Prozedure anspringen pop zh pop zl out SREG,zl pop r16 ret ; /*------------------------------------ PROZEDUREN SET_PORTA0/RES_PORTA0 bis SET_PORTC7/RES_PORTC7 Hier kommen die Prozeduren, die die ausgewählten Ports und Pins ansprechen. Eingangsvariablen keine Ausgangsvariablen keine geänderte Register keine geänderte Ports PORTA,PORTB,PORTC, je nach Datenbyte */ SET_PORTA0: sbi PORTA,0 ret RES_PORTA0: cbi PORTA,0 ret // und so weiter SET_PORTC7: sbi PORTC,7 ret RES_PORTC7: cbi PORTC,7 ret //------------------------







Zitieren
Lesezeichen