Forum: Mikrocontroller und Digitale Elektronik Probleme mit LCD an PIC 16f887


von Robert M. (pielo)


Angehängte Dateien:

Lesenswert?

Jetzt wo Tasterabfrage mit Blinklich, Lauflicht usw. funktionieren, hab 
ich mir gedacht ich versuche mich an einer LCD Ansteuerung.

Ich habe mir das "AVR-Tutorial: LCD" und die Dokumentation von Stefan 
Buchgeher (http://www.stefan-buchgeher.info/elektronik/lcd/lcd.html) 
durchgelesen und versucht es für den 16f887 umzusetzen.
Aber leider sehe ich nur eine schwarze Zeile.
Nach etlichen erfolglosen Versuchen das Problem zu beheben, wende ich 
mich nun an Pro's in diesem Forum.
Es wäre lieb wenn ihr mir ein paar Tipps bzw. Anregungen gebt, was das 
Problem sein könnte.

Verwendetes Display: Batron BTHQ 21605VSS-15

Im Anhang habe ich das Programm und die verwendete Schaltung eingefügt.

***lg Pielo***

von Chris B. (dekatz)


Lesenswert?

Im Programm sind deine Steuerleitungen auf PORTB festgelegt:
LCD_CTRL      equ PORTB
LCD_CTRL_TRIS    equ TRISB

und die einzelnen Pins sind so belegt:
  LCD_RS        equ  1
  LCD_RW        equ  2
  LCD_E        equ  3

Laut Schaltplan hängen die Steuerleitungen alle an PORTA und die 
einzelnen Pins haben folgende Funktionen:

3 = RS
1 = RW
0 = E

Pass irgendwie überhaupt nicht zum Programm....

von Robert M. (pielo)


Lesenswert?

Danke für die fixe Antwort.

Upps!!! Da hab ich wohl irgendwie durchs rumprobieren alles 
durcheinander gebracht. Habe es jetzt wieder berichtigt.
1
  LCD_DATA      equ PORTB
2
  LCD_DATA_TRIS    equ TRISB
3
  LCD_CTRL      equ PORTA
4
  LCD_CTRL_TRIS    equ TRISA
5
6
  LCD_RS        equ  3
7
  LCD_RW        equ  1
8
  LCD_E        equ  0

Leider muss da irgendwo noch ein Fehler drin.

von Chris B. (dekatz)


Lesenswert?

Beim F887 hat PORTB auch Analogfunktionen. Diese müssen abgeschaltet 
werden (wenn ich mich recht erinnere geht das mit ANSEL oder ANSELH).
Warum?
Weil BUSYLCD auf PORTB Lesend zugreift und bei Analogkonfiguration dort 
immer nur 0x00 eingelesen wird - für die Busyflagabfrage tödlich ;-)

von Robert M. (pielo)


Lesenswert?

Ich habe die Init jetzt nochmal ein wenig überarbeitet.
1
  INIT    
2
    BSF     STATUS,RP1      ;Bank 2
3
    BCF     CM1CON0,C1ON    ;Comparator 1 ist aus
4
    BCF     CM2CON0,C2ON    ;Comparator 2 ist aus
5
6
    BANKSEL PORTA           ;springe direkt zu Bank0 zum Register PortA
7
    CLRF    PORTA           ;Init PORTA
8
    BANKSEL ANSEL           ;springe direkt zu Bank3 zum Register Ansel
9
    CLRF    ANSEL           ;setze PortA auf digital I/O
10
    BSF     STATUS,RP0      ;springe zu Bank1 
11
    MOVLW   b'00001011'     ;schreibe Wert Inputs ins W-Reg
12
    MOVWF   TRISA           ;schreibe Wert aus W-Reg in TristateA
13
    MOVLW   b'00000000'     ;schreibe Wert Outputs ins W-Reg
14
    MOVWF   TRISB           ;schreibe Wert aus W-Reg in TristateB
15
    BSF     STATUS,RP1      ;springe zu Bank3
16
    CLRF    ANSELH          ;setze PortB auf digital I/O
17
    BCF     STATUS,RP0      ;springe zu Bank2
18
    BCF     STATUS,RP1      ;springe zu Bank0
19
20
  RETURN

Ich hoffe das sieht jetzt besser aus. Leider versteckt sich aber 
immernoch irgendwo ein Fehler :-(

: Bearbeitet durch User
von Chris B. (dekatz)


Lesenswert?

Damit bist du in Bank3 - völlig richtig
BANKSEL ANSEL           ;springe direkt zu Bank3 zum Register Ansel
CLRF    ANSEL           ;setze PortA auf digital I/O

jetzt ist RP0 = 1, RP1 = 1

nur mit dem hier:
BSF     STATUS,RP0      ;springe zu Bank1
kommst du sicher nicht in Bank1 zu TRISA und TRISB

Verwende einfach BANKSEL KONSEQUENT !!! dann passieren solche Sachen 
nicht.

von Robert M. (pielo)


Lesenswert?

hmmm Stimmt...

das ist halt die Sch... wenn man es in der Schule viel umständlicher 
erklärt bekommt.

Habe es jetzt geändert, aber leider noch immer ohne Erfolg :-(
1
  INIT    
2
    BSF      STATUS,RP1      ;Bank 2
3
    BCF      CM1CON0,C1ON    ;Comparator 1 ist aus
4
    BCF      CM2CON0,C2ON    ;Comparator 2 ist aus
5
6
    BANKSEL  PORTA           ;springe direkt zum Register PortA
7
    CLRF     PORTA           ;Init PORTA
8
    BANKSEL  ANSEL           ;springe direkt zum Register Ansel
9
    CLRF     ANSEL           ;setze PortA auf digital I/O
10
    BANKSEL  TRISA           ;springe zu Bank1 
11
    MOVLW    b'00001011'     ;schreibe Wert Inputs ins W-Reg
12
    MOVWF    TRISA           ;schreibe Wert aus W-Reg in TristateA
13
    BANKSEL  TRISB           ;springe direkt zum Register Tristate
14
    MOVLW    b'00000000'     ;schreibe Wert Outputs ins W-Reg
15
    MOVWF    TRISB           ;schreibe Wert aus W-Reg in TristateB
16
    BANKSEL  ANSELH          ;springe direkt zum Register AnselH
17
    CLRF     ANSELH          ;setze PortB auf digital I/O
18
    BCF      STATUS,RP0      ;springe zu Bank2
19
    BCF      STATUS,RP1      ;springe zu Bank0
20
21
  RETURN

von Martin M. (ats3788)


Lesenswert?

Wenn Du es nicht gebacken bekommt ich habe dafür eine Library
um den 887 anzusteuern.
Frag mich einfach wenn Du diese haben möchtest

von Robert M. (pielo)


Lesenswert?

Leider habe ich noch nie mit Libaries gearbeitet, daher weis ich 
garnicht so genau was das ist, bzw was ich damit machen kann. Dazu kommt 
noch das ich es ja auch irgendwie lernen möchte. Oder meine gemachten 
Fehler kennen lernen möchte um ihnen nicht noch einmal zu begegnen ;-)

von Karl H. (kbuchegg)


Lesenswert?

Robert Manzke schrieb:
> Leider habe ich noch nie mit Libaries gearbeitet,

In diesem Zusammenhang ist mit 'LIbrary' einfach nur der Source-Code 
gemeint und seltener eine tatsächlich richtige Library.

> daher weis ich
> garnicht so genau was das ist, bzw was ich damit machen kann.

Auf Deutsch: er gibt dir seinen Source Code, der nachweislich bei ihm 
funktioniert.

> Dazu kommt
> noch das ich es ja auch irgendwie lernen möchte. Oder meine gemachten
> Fehler kennen lernen möchte um ihnen nicht noch einmal zu begegnen ;-)

Fremden Code zu analysieren ist dabei gar nicht mal die schlechteste 
Methode. Man kann sehr viel lernen, wenn man sich ansieht, wie andere 
ein bestimmtes Problem lösen. Kein Mensch sagt, dass du den Code ohne 
genauer anzusehen übernehmen sollst, bzw. ob du ihn überhaupt 1:1 ohne 
Änderungen übernehmen kannst, ist damit noch lange nicht gesagt.

von Martin M. (ats3788)


Angehängte Dateien:

Lesenswert?

Hallo Robert ich hänge erst mal ein normales asm und die dazugehörige 
include file. Bitte teile mit ob das funktioniert hat.
Gehe einfach auf http://www.sprut.de/
da habe ich vieeeellll gelernt.

: Bearbeitet durch User
von Robert M. (pielo)


Lesenswert?

Danke ats3788,

leider fehlt noch die LCDMacros.inc um das Prog zu builden.

von Ottmar K. (wil1)


Lesenswert?

Hallo Robert,
falls Du mit der bisherigen Software nicht weiterkommen solltest, 
insbesondere falls "relocatable Code" Dir noch nicht geläufig sein 
sollte, könnte ich Dir ein für den PIC16F877 geschriebenes ASM-File 
(absoluter Code) und HD44780.INC (LCD-Initialisierung) hier einstellen. 
Wie ich das sehe, müsste lediglich der Header (Prozessor, INC-File, 
Config-Word)
und PORTA ADCON1 ->> ANSEL angepasst werden.

mfG Ottmar

von Robert M. (pielo)


Lesenswert?

@ wil1

Ich benutze ein "Batron BTHQ 21605VSS-15" Display, wenn ich mich nicht 
irre ist darin ein Samsung KS0070, ist dieser mit dem HD44780 identisch? 
Leider finden ich in den Weiten kein Datenblatt für dieses Display um 
sicher zu gehen das auch wirklich dieser Chip verbaut ist. Aber ich wäre 
auf alle Fälle an diese Code interessiert.

***lg Pielo***

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Robert Manzke schrieb:
> Es wäre lieb wenn ihr mir ein paar Tipps bzw. Anregungen gebt, was das
> Problem sein könnte.

Laß lieber den PortA frei für andere Zwecke und betreibe das LCD im 4 
Bit Modus. Dann kannst du es komplett mit nur dem PortB betreiben.

Ich häng dir mal ein Beispiel dran. Die LCD-Routinen daraus kannst du 
übernehmen, allenfalls mußt du ne "Stil"-Anpassung auf deinen Assembler 
vornehmen.

W.S.

von Ottmar K. (wil1)


Angehängte Dateien:

Lesenswert?

Hallo Robert,
beiliegend das ASM-File und die LCD-Initialisierung. Meiner Erinnerung 
nach hatte bei mir ein BATRON-LCD mit der HD44780-initialisierung 
funktioniert.

Du brauchst im ASM-File lediglich den PIC16F887-spezifischen Teil und 
#define-Anweisungen hinsichtlich der PORT- und PIN-Zuweisungen 
anzupassen.

Die LCD-initialisierung verwendet den 4Bit-Datenbus D4 - D7 am LCD. Wie 
viele andere auch, habe ich zum LCD (und anderem) bei 
[http://www.sprut.de] kräftig abgeschaut. Die Initialisierung wurde mti 
dem Timing für fosc 4MHz erstellt, funktioniert aber bei mir bis fosc 
10MHz.

Zur Sicherheit, dass das Timing auch klappt, empfehle ich im Abschnitt 
"Labels & Constants" diese Anpassung einzufügen:
  FOSC       equ .20    ;aktuelle fosc eintragen (z.B. 20MHz)
  FOSC_MULT  equ FOSC/4 ;Multiplikator für Delays

Delay aufrufen:
  movlw  .10*FOSC_MULT  ;Delaytime an aktuelle fosc anpassen.
  CALL Delay1ms

Ich hoffe, dass ich Dir ein wenig weiterhelfen konnte.

mfG Ottmar

von Robert M. (pielo)


Angehängte Dateien:

Lesenswert?

Danke für eure zahlreichen Tipps und Infos.

Ich habe es jetzt entlich geschafft. Ich habe das Voltmeter 
(http://pic-projekte.de/phpBB3/viewtopic.php?f=14&t=25), welches ich vor 
paar Monaten schon mal auf den 887 umgebastelt habe, auf das geringste 
gekürtzt und für mich angepasst.

Kann man da noch was Verbessern, was würdet ihr besser machen?

Jetzt habe ich aber mal noch die ein oder andere Frage dazu, damit ich 
auch vollkommen nachvollziehen kann was ich da genau getan habe. Ich 
weiß zwar nicht ob ich das jetzt hier reinschreiben kann oder ob ich ein 
neues Thread eröffnen soll.

Und zwar:

In diesem Programm verwendet Nico ein Linker Script, für was wird dieses 
verwendet, bzw. wann verwendet man sowas?

Was bedeutet "MYUDATA UDATA 0x20"?

Variablen werden mit z.b. "warten RES 1" deklariert, ich kenne aber nur 
den Befehl "warten EQU 0x20" wo ist da der Unterschied bzw. woher weiß 
der µC welche Speicherzelle für welchen Befehl zugewiesen wird?

Besteht die Möglichkeit die Buchstaben auch irgendwie mit einmal zu 
übertragen, gerade wenn man längere Texte übertragen möchte ist es ja 
ziemlich umfangreich. Oder besteht diese Möglcihkeit nur bei der 
C-Programmierung?

Ich denke mal das waren erstmal meine Fragen, wenn noch mehr dazu kommen 
melde ich mich noch mal.

***lg Pielo***

: Bearbeitet durch User
von Ottmar K. (wil1)


Lesenswert?

Robert Manzke schrieb:
> Was bedeutet "MYUDATA UDATA 0x20"?

Nachstehende Infos sind bei Weitem nicht vollständig! Das Thema 
"relocatable code" kann hier nur angerissen werden!

Bei der Assemblerprogrammierung mit MPLAB unterscheidet man 2 
Möglichkeiten:
a)Absolute Code
b)Relocatable Code

Absolute Code
Es gibt ein Sourcefile z.B. "Voltmeter.ASM" In diesem befinden sich alle 
Initialisierungen und Unterprogramme.
Zusätzlich können noch KOMPLETTE Include-Files "*.INC" an beliebiger 
Stelle im ASM-File mit der Direktive " include "LCD_Init.INC" eingefügt 
werden, was vom Compiler beim Assemblieren erledigt wird. Es werden 
jedoch alle Subroutinen des *.INC-Files eingefügt auch wenn diese im 
speziellen Fall nicht benötigt werden.

Relocatable Code
Man schreibt weiterhin die Software "Voltmeter.ASM". Zusätzlich verfügt 
man z.B. über ein ASM-File "MATH.ASM" mit allen möglichen 
Unterprogrammen z.b. 32-Bit Division, Additionen usw. Hieraus wird z.B. 
nur die 16-Bit-Multiplikations-Sub "Mult16" benötigt.

MATH.ASM wird daher als Sourcefile mit in das Projekt, zusätzlich zu 
"Voltmeter.ASM" eingefügt.
Mittels der Direktive "GLOBAL Mult16" ist diese Sub in MATH.ASM (neben 
anderen) explizit zur globalen Verwendung freigegeben. Ebenso die 
zugehörigen Variablen "global VarXY".

Ebenso explizit wird im "Voltmeter.ASM" mittels der Direktive
 "EXTERN Mult16" die Sub bekannt gemacht, Natürlich auch die zugehörigen 
Variable "extern VarXY".

In "MATH.ASM" befinden sich diese Direktiven
My_Udata:  UDATA_SHR    ;Mx_Udata ist ein x-beliebiger Label
           VarXY res 1  ;reserviert 1 Byte für diese Variable
die "shared"(=SHR) VarXY kann jetzt aus anderen ASM-Files heraus 
aufgerufen werden.

labelXY:  UDATA 0x20
          VarAZ res 1
weist den Compiler an, 1 Byte im Speicher für die Variable VarAZ 
explizit an Adresse 0x20 bereitzustellen.

Beim Assemblieren sorgt der Compiler dann selbstständig dafür, dass nur 
die bezeichneten Unterprogramme und Variablen, die angegebenen 
Speicherbereiche usw. verwendet werden.

Der Clou ist, dass Du in Voltmeter.ASM, aber auch in MATH.ASM 
gleichnamige Variablen verwenden kannst. Man kann Speicherbereiche 
reservieren usw. Wenn man es einmal geblickt hat ist das gar nicht so 
schwierig.

Auf jeden Fall entbindet es einen immer wieder gleichlautende 
Unterprogramme zu schreiben, man kann sich so eine "Bibliothek" z.B. für 
Mathematik, LCD-Ausgabe usw zulegen und immer wieder darauf - wenn 
einmal erstellt - einfach und wenig zeitaufwendig zugreifen.

In der Hilfe zu MPLAB, bzw. im Handbuch dazu ist dieses Vorgehen, 
allerdings in englischer Sprache recht gut und verständlich beschrieben. 
Wenn Du Interesse hast, kann ich Dir eine von mir erstellte Ausarbeitung 
zum relocatable code als persönliche Mail zusenden.

mfG Ottmar

von Robert M. (pielo)


Lesenswert?

Danke für die ausführliche Erklärung. Ich werde mich aber erstmal mit 
den "einfachen" Weg beschäftigen, quasi nur ein asm-File. Ich werde dir 
trotz alle dem mal meine E-Mail schicken, damit ich mich mal ein wenig 
in diese Geschichte einlesen kann.
Jetzt werde ich mich mal daran machen Tasterabfrage mit LCD Anzeige zu 
vereinen.

***lg Pielo***

: Bearbeitet durch User
von Robert M. (pielo)


Lesenswert?

Ich habe an das Display jetzt 2 Taster, mit den ich den Curser nach 
links und nach rechts schieben kann. Jetzt würde ich aber gern mit 2 
weiteren Tastern das Alphabet vorwarts bzw. rückwärts schalten können. 
Dazu habe ich mich entschieden die Position des Cursers mit zu zählen 
und dann dem Wert der in dem Register steht an dem der Curser sich 
befindet einfach 1 zu addieren bzw. subtrahieren. Dazu habe ich hier im 
Forum ein Code-Schnipsel gefunden, der aber leider in avr-asm 
geschrieben ist. Wäre es möglich das mir jemand ein paar Komentare 
dahinter schreibt, damit ich es in pic-asm um dichten kann. Befehle wie 
"SETB", "ANL" oder "ORL" finde ich irgendwie in keiner Dokumentation.

Klaus schrieb im Beitrag "Re: LCD Zeichen auslesen":
> ; -------------------------------------------------------------
> ; LCD_GetChar
> ; -------------------------------------------------------------
> ; Beschreibung: Liest ein Zeichen von der aktuellen Cursor Position
> ;               LCD_buffer enthält empfangens Zeichen
> ; -------------------------------------------------------------
1
 $Region "Ein Zeichen aus dem LCD auslesen"
2
 LCD_GetChar:
3
 
4
    MOV   LCD_Port,#00111111b
5
    CALL  LCD_Pause_4ms
6
    SETB  LCD_EN
7
    MOV   A,LCD_Port
8
    SWAP  A
9
    ANL   A,#0F0h
10
    CLR   LCD_EN
11
    MOV   LCD_buffer,A
12
    NOP
13
    SETB  LCD_EN
14
    MOV   A,LCD_Port
15
    ANL   A,#0Fh
16
    CLR   LCD_EN
17
    ORL   LCD_buffer,A
18
    CLR   LCD_RW
19
    CLR   LCD_RS
20
 RET

***lg Pielo***

von Robert M. (pielo)


Lesenswert?

was anders...

ist es irgendwie möglich einen Zählerwert festen Zeichen zuzuweisen?

D.h.:

Speicherzelle "0x25" hat den Wert "3" -> festgelegt ist für 3 der 
Buchstabe "C" -> jetzt das "C" ins Arbeitsregister übergeben -> dann 
ausgeben?

***lg Pielo***

von Ottmar K. (wil1)


Angehängte Dateien:

Lesenswert?

Hallo Robert,

beiliegend eine Richtungsangabe wie Du zur Ausgabe eines Buchstabens per 
Tastendruck verfahren könntest. Ich hab den Code nicht getestet, einfach 
mal hingeschrieben, wie es gemacht werden könnte.
Evtl. kannst Du das dann auch in einen eigenen Code umsetzen.

mfG Ottmar

von Ottmar K. (wil1)


Lesenswert?

Robert Manzke schrieb:
> Speicherzelle "0x25" hat den Wert "3" -> festgelegt ist für 3 der
> Buchstabe "C" -> jetzt das "C" ins Arbeitsregister übergeben -> dann
> ausgeben?

Klar geht das mit indirekter Adressierung. Lies doch dazu im Datenblatt 
des 16F628 diesen Abschnitt: "3.4 Indirect Addressing, INDF and FSR 
Registers"

In Register schreiben:
movlw 0x22     ;Adressezeiger z.B. 0x22 über das WREG
movwf FSR      ;ins Register "FSR" (FileSelectRegister) kopieren
movlw "A"      ;Wert ins WREG
movwf INDF     ;und ins virtuelle Register übertragen, damit enthält 
dann
               ;zugleich das Register 0x22 nun den Ascii-Wert von "A"
               ;nächstes Register belegen
incf  FSR,f    ;Adresszeiger+1
movlw "B"      ;nächsten Wert übertragen
movwf INDF     :Ascii-Wert von B steht nun in Adresse 0x23

Aus Register lesen, der umgekehrte Vorgang, im Prinzip wie vorstehend:
movlw 0x22
movwf FSR
movf  INDF,w    ;kopiert Inhalt Adresse 22h ins WREG
movwf Variable  ;Variable enthält nun die K0pie des Wertes
                ; in Adresse 0x22 -> "A"
incf  FSR,f
movf  INDF,w
movwf Variable  ;Variable enthält nun die Kpie des Wertes
                in Adresse 0x23 -> "B"

Das lässt sich natürlich in eine Schleife gefasst mit weniger Code und 
dazu übersichtlicher erledigen.

mfG Ottmar

von Robert M. (pielo)


Lesenswert?

Ottmar K. schrieb:
> Hallo Robert,
>
> beiliegend eine Richtungsangabe wie Du zur Ausgabe eines Buchstabens per
> Tastendruck verfahren könntest. Ich hab den Code nicht getestet, einfach
> mal hingeschrieben, wie es gemacht werden könnte.
> Evtl. kannst Du das dann auch in einen eigenen Code umsetzen.
>
> mfG Ottmar

Danke für die gute Erklärung.

Leider hapert es noch ein wenig bei mir an der Umsetzung, ich komme 
einfach nicht dahinter für was "pointer_H" und "pointer_L" da sind.
Und mit dem "PLCATH" hab ich mich vorher auch noch nie beschäftigt, da 
probiere ich gerade diesen Abschnitt zu verstehen.
-> http://www.sprut.de/electronic/pic/grund/adress.htm#progmem

von Robert M. (pielo)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt ein wenig Durchblick, dadurch habe ich jetzt mit der 
Simulation auch einen Fehler im Ablauf gefunden.
Er springt nach "ABC_Char:" (vor dem "return") an einen willkürlichen 
Punkt, meistens zu Taster_links.

Ich geh mal davon aus das ich den Codeteil falsch eingebaut habe, oder 
liegt das Problem wo anders?

Die Pausen habe ich nur für die Simulation ausgeblendet bzw. verkleinert

***lg Pielo***

von Ottmar K. (wil1)


Lesenswert?

Autor: Ottmar K. (wil1)
Datum: 18.10.2013 18:06

Robert Manzke schrieb:
> ich komme
> einfach nicht dahinter für was "pointer_H" und "pointer_L" da sind.

Also Pointer_H könnte auch
"Zeiger_auf_HByte_der_Adresse_von_Register_XYZ"
oder sonst wie benannt werden. Es handelt sich hier um einen beliebigen
Variablennamen. Es ist halt üblich einen Zeiger mit dem englischen Wort
"pointer" zu benennen.

Also angenommen die Variable heißt "Finde_Mich" und liegt infolge der
Anweisung
     CBLOCK 0x0020
        Finde_Mich
     ENDC
an Adresse 0x0020, also 20h. Dann ist in diesem Fall das H-Byte der
Adresse 0x00 und das Low-Byte 0x20.

Mit dem Code
movlw  high  Finde_Mich"
movwf  Zeiger_H

wird der Compiler beim Assemblieren angewiesen über das WREG der
Variablen "Zeiger_H" den Wert des Adress-HIGH-Bytes des Registers mit
dem "Decknamen" "Finde_Mich" also 00h, zuzuweisen.

Mit dem Code
movlw  low  Finde_Mich"
movwf  Zeiger_L

wird der Compiler beim Assemblieren angewiesen über das WREG der
Variablen "Zeiger_L" den Wert des Adress-LOW-Bytes des Registers mit dem
"Decknamen" "Finde_Mich" also 20h, zuzuweisen.

Siehe dazu auch 2.3 PCL and PCLATH im Datenblatt des PIC16F887!

Der Programmzähler beim PIC besteht ebenfalls aus H-Byte, das sind die
unteren Bit 4:0 des Register PCLATH und dem Low-Byte das ist das
Register PCL.
Folglich kann mann mit 13 Bit einen Speicherbereich von 0 - 8191 = 8192
Bytes adressieren.

Die Zuweisung
movlw    Zeiger_H
movwf    PCLATH
movlw    Zeiger_L
movwf    PCL
bewirkt bei Ausführung von "movwf PCL" dass der Programmzähler an die
Adresse der Variablen "Finde_Mich" springt. Natürlich würde das in
diesem Falle zu Unsinn führen, denn mit der Variablen kann je das
Programm weiter nichts anfangen.

Nich jedoch wenn die indirekte Adressierung per FSR und INDF (habe schon
was dazu geschrieben) ins Spiel kommt.

Eine Tabelle kann dann so ausgelesen werden (zu "dt - Define Table"
bitte die Hilfe zu MPLAB - Assembler lesen):

Sprungziel_1:
     dt "Volt"
Sprungziel_2
     dt "Ampere@"

Zeiger_H und Zeiger_L werden auf "Sprungziel_1" gerichtet, was ja nichts
anderes als die vollständige Adresse des 1.Buchstabens im String "Volt"
ergibt.
Wird PCL nach dem Lesen von "V" incrementiert (+1) kann Buchstaben für
Buchstaben ausgelesen und z.B. im LCD ausgegeben werden. Im Programm
muss durch mitzählen festgestellt werden wann der letzte Buchstabe "t"
gelesen wurde. Man kann aber z.B. wie beim "Sprungziel_2" ein Zeichen
(@) als Schlussmarke verwenden. Wird dieses gelesen, ist die Ausgabe
beendet.

Soviel mal zu diesem Thema, kannst ja wieder fragen.

mfG Ottmar

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
Noch kein Account? Hier anmelden.