Ich habe ein kleines Programm für einen PIC in Maschinen-Code geschrieben, das funktioniert, aber ich weiß nicht – warum! Der PIC ist ein 18F14K22, die MPLAB X-Version ist 3.55, genutzt wird das PICkit3 und eine Basiplatine dafür. Es geht letztlich um einen bestimmten Opcode, bzw. um die Begriffe „BSR („Bank Select Register“), bzw. schlicht um den aktuellen Platz/ die Bank im Daten-Memory. Als Beispiele nehme ich zwei Befehle aus dem Instruction-Set. movf file,0,1 oder auch movf EEDATA,0,0 Beide Befehle bewegen den Inhalt eines Files, beim zweiten geht es um das Auslesen des EEPROMs. Der jeweils erste Opcode (intern mit „d“ bezeichnet) , bestimmt, dass bei „0“ das WREG das Ziel ist, bei „1“ würde in das Register zurück gespeichert. Der zweite Opcode ist der Stolperstein, das ist der intern mit „a“ bezeichnete. Bei „0“ ist die „Access Bank“ ausgewählt, bei „1“ die „GPR“-Bank, und letzteres per default. Lesen kann ich, aber nix verstehen. Vermutlich geht es um die bei PICs berühmte Speicher-Akrobatik. Aber woher erkenne ich nun, welche Bank da anzuwählen ist? Im Simulator gibt’s ja ganz oben in der Mitte ein kleines Fensterchen mit diversen Anzeigen, u.a. auch dem Bank-Register. Bei movf EEDATA,0,1 wird der Eeprom-Inhalt mit FFh ausgegeben, bei movf EEDATA,0,0 gibt’s den „richtigen“ Inhalt. Muss und kann ich da beim „Simulieren“ reinschauen, in welcher Bank gerade rumprozessiert wird? Muss man das ausrechnen, oder was ist zu tun? Mit try-and-error hab ich die Funktion des Progs ja rausgefunden, aber verstehen würde ich es auch gerne. Grüße, wilhelmT
:
Bearbeitet durch User
Hallo! Verwende doch ganz einfach "Banksel" und der Assembler/Compiler verwendet automatisch die richtige Bank. Beispiel: Banksel LATB ;Latchregister movlw 0x00 ;clear PORTB Output Latches movwf LATB Banksel TRISB ;Datenrichtungsregister movlw 0x00 ;set RB7:RB0 as autputs BANKSEL 0 ,zurück zu Bank 0 Das kannst Du bei allen SFR's so anwenden. Banksel EECON1 bsf EECON1,EEPGD Banksel 0 mfG Ottmar
Danke für deine Anregung! Erst hattest du mich in Verlegenheit gebracht, weil der "normale" Befehlssatz des PIC18F14K22 solche Befehle nicht vorhält. Nur einer der Befehle hantiert direkt mit dem BSR: movlb k , da wird eine 8-bit-Zahl in das untere Nibbel des BSR geschrieben. Der Assembler scheint "deinen" Befehl aber zu kennen, die Auswirkung hatte ich allerdings noch nicht getestet. Im Prinzip weiche ich damit meinem Ziel auch wieder aus, ich wollte ja gerne verstehen, in welcher Bank das Programm so gerade Bits schaufelt, und vor allem: wo gibt es einen Anzeige für die momentane Bank? Ist das die schon angesprochene Info in dem Mini-Fensterchen rechts oben im Simulator? Grüße, wilhelmT
Be T. schrieb: > Lesen kann ich, aber nix verstehen. Vermutlich geht es um die bei PICs > berühmte Speicher-Akrobatik. Hallo Wilhelm, der Hintergrund ist, daß im Opcode des Befehls nur Platz für eine 8-Bit breite Adresse ist, also maximal 0 bis 255. Da der PIC aber mehr Register (GPR und SFR) hat, als 256, werden die Register in Bänke eingeteilt. Die Adresse, auf die man dann mit dem Befehl zugreift, ergibt sich aus der Banknummer im BSR-Register und der Adresse (0..255) im Opcode, so kann man dann auf bis zu 16 Bänke * 256 Adressen = 4096 Register zugreifen, wenn das "A"-Bit im Opcode 1 ist. Damit man nicht für jeden Zugriff auf eine häufig benutzte Variable oder ein SFR immer erst das Bankselect-Register mit der richtigen Banknummer laden muss, kann man durch A=0 im Opcode das BSR-Register ignorieren, allerdings kann man so eben auch nur 256 Register adressieren. Diese sind dann fest vorgegeben: Für Adressen 0 bis 0x5F werden die entsprechenden GPRs in Bank 0 angesprochen (es ist also klug, viel benutze Variablen in diesen Bereich zu legen, um sich die Bankumschaltung zu sparen), für Adressen 0x60..0xFF wird mit A=0 auf die SFRs (in Bank 15) zugegriffen. Die SFRs sind also immer ohne Bankumschaltung erreichbar. Gruß, Thomas
:
Bearbeitet durch User
Be T. schrieb: > Der zweite Opcode ist der > Stolperstein, das ist der intern mit „a“ bezeichnete. Bei „0“ ist die > „Access Bank“ ausgewählt, bei „1“ die „GPR“-Bank, und letzteres per > default. Das mit den Defaults stimmt so nicht, obwohl es im Datenblatt steht. Der Assembler "weiß", wenn eine Variable im ACCESS Ram steht und verwendet dann nicht banked. (außer du erzwingst es mit der Angabe des Parameters a)
:
Bearbeitet durch User
Danke sehr für eure Erklärungen! Wenn die Hilfen hier weiter gehen, werde ich das irgendwann verstehen, aber noch ist es nicht soweit. Ein Prob ist inzwischen geklärt, die von mir vermisste Anzeige der Speicher ist gefunden. Im Simulator- is klar – liegen ja in dem linken, unteren Fenster, dem „Dashboard“, u.a. zwei hübsch gefärbte Balken. Oft gesehen, aber nicht wirklich hingeschaut. Da gibt’s also als Balkenanzeige und in Zahlen zunächst den vom Prog benutzten Datenspeicher-Platz. Der macht bei meinem Prog genau 15 Bytes aus, und dass in dem Prog 15 Variable definiert sind, ist eher kein Zufall. Da drunter der Balken für den Programm-Speicher, der benötigte Platz peilt z.Z. bei 365 Bytes. Trotzdem ist mir nicht klar, wo und in welchem Speicher und welcher Bank denn nun diese vermaledeite EEprom-Variable EEDATA liegt. Laut Datenblatt verstehe ich das so, dass dieses EEDATA im Datenspeicher liegt und dort fest verankert „ganz oben“ im Bereich der SFRs, im „Acces RAM High“, im Bereich 60h bis Ffh (und dieser SFR-Bereich taucht dann auch noch im Bereich F60h bis FFFh auf ???? !!!) Wenn dieses EEDATA im SFR-Bereich liegt und dort fest verankert ist, müsste doch diese Bank-Zuweisung quasi immer gelten. Oder kann ich etwa dieses EEDATA zusätzlich in meine Variablen-Liste aufnehmen, um so zu erreichen, dass diese Variable „ganz vorne“ und in der Bank 0 liegt? Oder ist es doch ganz anders, und wichtig für die Bankzuordnung ist die Stelle, an welcher im Programmspeicher diese vermaledeite Variable EEDATA gerade plaziert ist? Grundlagenwissen, schön, wenn man es hätte. Grüße, wilhelmT
:
Bearbeitet durch User
Be T. schrieb: > Trotzdem ist mir nicht klar, wo und in welchem Speicher und welcher Bank > denn nun diese vermaledeite EEprom-Variable EEDATA liegt. Also EEDATA liegt laut Datenblatt an der Adresse 0xFA8. Das ist absolut fix und in keiner Weise änderbar. 0xFA8 liegt automatisch im ACCESS Bereich und auch das ist in keiner Weise änderbar. Wenn du mit Gewalt banked auf EEDATA zugreifen willst, kannst du die Adresse FA8 aufteilen in die Adresse der Bank (F) und in die Adresse in der Bank (A8). Beim einem Befehl zur Verarbeitung von EEDATA wird das F (außer bei movff) sowieso ignoriert. Anstatt dessen wird der Inhalt von BSR verwendet und nur das A8 ausgewertet. Also falls du aus welchen Gründen auch immer "banked" auf EEDATA zugreifen willst, dann muss vorher VON DIR BSR auf 0x0F gesetzt worden sein. Beim access Zugriff wird das F auch ignoriert, aber weil die verbleibende Adresse xA8 >= x60 ist, wird quasi im Hintergrund ein F wieder ergänzt und die Adresse wird zu 0xFA8. (Was im BSR steht wird beim access Zugriff ignoriert.) Bei Adressen kleiner 0x_wasauchimmer_60 wird beim access Zugriff das wasauchimmer ignoriert und eine Null ergänzt. Die Adresse wird zu 0x000..0x05F. Deine Variablen sollten die Adressen 0x000..0x00E belegen, falls du die in einer UDATA_ACS Section untergebracht hast. Das kann man z.B. im Debugger sehen...
:
Bearbeitet durch User
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.