Archiv verlassen und diese Seite im Standarddesign anzeigen : Look up table
Hallo,
wie funktioniert eine LUT? Also sowohl praktisch (in Assembler) als auch theoretisch.
ps: Habe den 89S8252, ist alt, aber wird mir von meiner Schule vorgeschrieben.
Hallo cipoint,
es ist schon eine Weile her, daß ich mit den 8051ern rumgespielt habe.
Der 89S8252 ist eigentlich ein relativ neuer 8051 Typ... es gibt noch ältere Varianten. Aber zum Table:
Du musst einfach irgendwo im Programmspeicher dein LUT ablegen und kannst dann mit dem Befehl "movc A,@(A+DPTR)" das Datenwort in den Akku laden. Vorher musst du natürlich die Startadresse des LUT ins DPTR laden und den Offset in den Akku.
LUT:
.db irgendwas....
MOV A,LOW(LUT)
MOV DPL,A
MOV A,HIGH(LUT)
MOV DPH,A
MOV A,LUT_Offset
MOVC A,@(A+DPTR)
Ist nicht getestet... sollte aber so ähnlich funktionieren.
Gruß,
SIGINT
;Zweiter Versuch mit dem Drehimpulsencoder
include REG8252.INC
;Zuweisungen
SIG_A EQU P3.3 ;0
SIG_B EQU P3.2 ;1
LAST_STATE EQU R6
TEMP EQU R2
;Resets
MOV P2, #0
MOV LAST_STATE, #0
;************************************************* **************************************************
;Die Hauptschleife
LOOP: ACALL CHECK_DIG_STATE
SJMP LOOP
;************************************************* **************************************************
CHECK_DIG_STATE: ACALL READOUT_DIG ;Zustand auslesen und
MOV A, LAST_STATE ;im Accu an der Stelle
MOV B, #04h ;X X X X - - X X platzieren
MUL AB
ACALL READOUT_DIG ;Zustand auslesen, an der
ORL A, LAST_STATE ;Stelle X X X X X X - - platzieren
ANL A, #0Fh
MOV P2, A
MOV DPTR, #TABLE
JMP @A+DPTR
;************************************************* **************************************************
;Liest den Drehimpulsgeber aus und speichert den Zustand im Register LAST_STATE
READOUT_DIG: JB SIG_A, A_TRUE
SJMP A_FALSE
A_TRUE: JB SIG_B, STATE_2
SJMP STATE_1
A_FALSE: JB SIG_B, STATE_3
SJMP STATE_0
STATE_0: MOV LAST_STATE, #0 ;SIG_A=0 and SIG_B=0
RET
STATE_1: MOV LAST_STATE, #1 ;SIG_A=1 and SIG_B=0
RET
STATE_2: MOV LAST_STATE, #2 ;SIG_A=1 and SIG_B=1
RET
STATE_3: MOV LAST_STATE, #3 ;SIG_A=0 and SIG_B=1
RET
;************************************************* **************************************************
TABLE: SJMP NOA
SJMP CW
SJMP ERR
SJMP CCW
SJMP CCW
SJMP NOA
SJMP CW
SJMP ERR
SJMP ERR
SJMP CCW
SJMP NOA
SJMP CW
SJMP CW
SJMP ERR
SJMP CCW
SJMP NOA
;************************************************* **************************************************
NOA: NOP
RET
ERR: NOP
RET
CW: SETB P2.7
RET
CCW: CLR P2.7
RET
END
Der uC hängt sich auf, wenn SIG_A=0 und SIG_B=1 ist. Sobald der Debugger an die Zeile JMP @A+DPTR kommt, gibt er "Out of Code" aus. Ich kann mir das aber nicht erklären. Der ACCU enthält zu diesem Zeitpunkt 00001010 und springt sogar zu der Adresse in der Tabelle unten. Dann führt der NOP aus und gibt eben den Fehler aus.
Vielleicht überschreibe ich versehentliche wichtige Register?
Ich hab wie gesagt lange nichts mehr mit dem 8051 gemacht... wie war das mit dem Stackpointer? Musst du eventuell noch den Stackpointer initialisieren?
SprinterSB
16.03.2007, 16:04
Der SJMP ist 2 Bytes lang. Musst du nicht vor dem relativen Sprung noch den Akku mir der Länge des SJMP-Befehls multiplizieren?
Allserdings erklärt das nicht den Debugger-Fehler bei dir, weil 1010 (DEC=10, also state no. 5) ein gültiger Offset ist :-k
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.