PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Indirekte Adressierung PIC16F84A



wolf***
31.12.2006, 16:59
Hallo, ich möchte mich erstmal bei allen bedanken, die mir beim DB Assembler Befehl weitergeholfen haben. Es ist ein gutes Gefühl wenn man nicht so allein rumwuselt. Auf der Sprut Seite ist der Befehl DE nicht enthalten. Ich sitze an meinem ersten Programm. Es soll 8 LEDs am Port B steuern. Ich möchte gerne ein binäres Bitmuster im Speicher Ablegen, welches durch indirekte Adressierung die LED Muster zur Anzeige bringt. Mit mehr Erfahrung auch mal eine LED Matrix mit verschiedenen Mustern ansteuern. In meinem jetzigen Programm wird zwar das FSR Register hochgezählt, aber die indirekten Adressierten Speicherwerte werden nicht gefunden. Die erste Frage was mache ich falsch? Wo müssen die binären LED Musterwerte hin, in ein Fileregister oder in den Programmspeicher und wie geht das? Bei meinem Programm landen die Werte im Programmspeicher, kann die indirekte Adressierung hier angewand werden?
Ist der Befehl movfw INDF richtig? Hier das Programm:

list p=16f84a ;PIC type auswählen
;-------------------------------
;Pinbelegung
;Port b0(pin6) LED1
;Port b1(pin7) LED2
;Port b2(pin8) LED3
;Port b3(pin9) LED4
;Port b4(pin10)LED5
;Port b5(pin11)LED6
;-------------------------------
;Droste Ver.1 18.11.2006
;Lauflicht an Port B
;Takt: 4MHz, Quarz
;-------------------------------
;Includedatei für den 16f84 einbinden
#include <P16f84a.INC>
;Configuration festlegen
;4Mhz, Power On Timer, kein Watchdog, Xt-Oszillator
__config _PWRTE_ON & _WDT_OFF & _XT_OSC
;-------------------------------
init

;Variablennamen vergeben

loop equ 0x22
loop2 equ 0x23
;programm
bsf STATUS, RP0 ;zu bank 1
movlw 0x00 ;Port B alles Null
movwf TRISB ;Port B alles Ausgänge
bcf STATUS, RP0 ;zu bank 0
clrf PORTB ;alle LEDs aus


beginn movlw 0x40 ;Zeiger setzen
movwf FSR ;indirekte Adr.
loop3 movfw INDF ;Wert aus Sp.
movwf PORTB ;Wert Out
call Wait
incf FSR,f
movfw FSR
sublw 0x4d
btfsc STATUS,Z
goto beginn
goto loop3
Wait movlw d'250'
movwf loop
wai movlw .110
movwf loop2
wai2 nop
nop
nop
nop
nop
nop
decfsz loop2,f
goto wai2
retlw 0
goto beginn
org 0x40
de b'10001000'
de b'11001100'
de b'11101110'
de b'11111111'
de b'11111110'
de b'11111100'
de b'11111000'
de b'11110000'
de b'11100000'
de b'11000000'
de b'10000000'
de b'00000000'
de b'11111111'
de b'00011000'
end

Ich wünsche allen ein guten Rutsch und ein frohes neues Jahr und möchte mich schon im vorraus für die Hilfe bedanken.
MfG Wolf***[/code]

kalledom
31.12.2006, 18:51
Hallo Wolf,
Indirekte Adressierung (INDF / FSR) kannst Du nur im Zusammenhang mit RAM-Speicher anwenden.
Zum Auslesen des Flash-Speichers mußt Du die High- und Low-Adresse in besonderen Registern setzen, und eine bestimmte Flash-Lese-Routine benutzen.
Schau Dir dazu meine PIC-Seiten an, dort ist die RdFlash-Routine drin.
Die Adressen kannst Du vorher berechnen, dann ablegen und das Byte auslesen. Ein 'incf' reicht anschließend für die nächste Adresse aus; dabei evtl. Übertrag auf High-Byte der Adresse nicht vergessen !
ORG 0x40 ist evtl. irgendwo im Programm-Code; hat der Assembler da noch nicht gemeckert wegen Overlapp oder so ? Setz die Daten ziemlich an das Ende des Code-Speichers, falls Du das Programm erweitern möchtest.

Dir und allen Anderen einen guten Rutsch ins neue Jahr !

PICture
01.01.2007, 08:06
Hallo wolf***!

Ich habe es versucht Dir das, was oben der kalledom geschrieben habe, einfacher zu erklären.

So wie ich es aus Deinem programm sehe, sollen die LED Muster im RAM abgelegt werden und danach daraus am PORTB ausgegeben werden.

Die Muster lassen sich mittels einer Schleife mit indirekter Adressierung nich ablegen, da der nächste Wert nicht aus dem vorherigen mit "incf" oder "decf" erzeugt werden kann.

Ich würde Dir empfehlen, die LED Muster folgendemassen im RAM abzulegen:

movlw Wert1
movwf RAM1
movlw Wert2
movwf RAM2, u.s.w., wo RAM ist eine Speicherstelle die mit absoluter Adresse (z.B. 0x40) oder einem Label (z.B. LED1) direkt adressiert wird.

Die so im RAM abgelegte Werte können danach nacheinander mit indirekter Adressierung in W Register eingelesen und danach ins PORTB eingeschrieben werden, z.B. so:

movlw 0x40 oder movlw LED1
movwf FSR
movf INDF,0 (das ist die Speicherstelle, dessen Adresse sich im FSR Register befindet)
movfw PORTB

incf FSR,1 (die Adresse der zu lesender Speicherstelle um 1 erhöhen)

movf INDF,0
movwf PORTB u.s.w.

Das ganze kann man natürlich in einer Schleife mit Zähler machen, so wie Du es in Deinem Programm hast.

Du musst unterscheiden zwischen Programm- und Dataspeicher und entsprechend programmieren. Dein Fehler war auch, das Du den Wert aus dem SFR lesen wolltest, der befindet sich aber immer im INDF Register.

MfG