Hallo,
ich versuche mich gerade an PIC Assembler, einfach weil ich es
interessant finde. Dazu habe ich einen PIC12F508 zur Verfügung, also ein
Winzling unter den PICs, aber übersichtlich vom Befehlssatz her :-)
Nun brauche ich eine Variable im RAM für einen Zähler (Loop) und da
stehe ich etwas auf dem Schlauch. Laut Datenblatt hat der PIC12F508 25
Bytes RAM (uh, yeah!) und wenn ich es richtig verstanden habe werden
diese 25 Bytes sowohl für die Register der MCU als auch für das Programm
benutzt.
Würde das heißen das die erste verfügbare RAM-Adresse dann 07h wäre?
Also z.B. so um diese zu nutzen:
Habe früher eher die größeren PICs mit Assembler genutzt und die üppigen
25 Byte RAM gemieden ;-)
Rein vom Datenblatt her sollte das passen. Einfach mal einen Pin + LED
mit einer Warteschleife blinken lassen, dann merkst du schon, ob es
stimmt.
Hier zum Einstieg eine Warteschleife:
Olli Z. schrieb:> wenn ich es richtig verstanden habe werden> diese 25 Bytes sowohl für die Register der MCU als auch für das Programm> benutzt.
Nein, die 25 Bytes sind nur RAM. der Programmspeicher ist viel grösser
als das RAM und wird getrennt behandelt.
>> Würde das heißen das die erste verfügbare RAM-Adresse dann 07h wäre?> Also z.B. so um diese zu nutzen:> var EQU 0x07h;> movlw 0xAA;> movwf var;
Richtig
Gruss J.P.S
Danke das mit der Variablen und der Schleife habe ich bereits
hinbekommen, ich wollte nochmal sicher gehen das ich das alles so
richtig verstanden habe :-)
Jetzt hänge ich am CALL/RETLW, der will noch nicht. Ich habe eine
Schleife programmiert die eine bestimmte Anzahl von 1/0-Übergängen am
GP2 auslöst.
1
count EQU 0x07;
2
3
...
4
movlw 16;
5
movwf count;
6
call send;
7
...
8
stop:
9
goto stop;
10
11
send:
12
bcf GPIO, 2; // LED ON (low)
13
bsf GPIO, 2; // LED OFF (high)
14
nop;
15
nop;
16
nop;
17
decfsz count, 1;
18
goto send;
19
retlw 0;
Da passiert leider nix, so als würde die Subroutine nicht angesprungen
werden. Ich habe es versucht mit dem Simulator nachzustellen, aber die
Subroutine wird nicht angesprungen.
Im Simulator sehe ich das meine Variable an RAM Position 07h ordentlich
befüllt wird. Danach kommt der CALL und dem wird mit F7 (Step Into)
nicht mehr gefolgt.
In der "SFRs" Anzeige im Simulator sehe ich das nach Ausführung des CALL
die richtige Nachfolge-Adresse auf den HW-Stack gelegt wird. Jedoch wird
der der PCL (Program Counter) auf die Adresse 0xBC eingestellt. Mein
Programm fängt aber erst ab 0xE9 an. Die richtige Adresse wäre 0xF5.
Warum biegt der CALL denn hier falsch ab?
In der "output" Ansicht wird das sogar angezeigt:
"No source code lines were found at current PC 0x1bc. Use Program memory
view to see instruction code disassembly"
Olli Z. schrieb:>> In der "SFRs" Anzeige im Simulator sehe ich das nach Ausführung des CALL> die richtige Nachfolge-Adresse auf den HW-Stack gelegt wird. Jedoch wird> der der PCL (Program Counter) auf die Adresse 0xBC eingestellt. Mein> Programm fängt aber erst ab 0xE9 an. Die richtige Adresse wäre 0xF5.> Warum biegt der CALL denn hier falsch ab?
Hast Du "4.7 Program Counter" im Datenblatt gelesen, speziell was beim
CALL passiert? Vielleicht erklärt es das ja.
bcf GPIO, 2; // LED ON (low)
bsf GPIO, 2; // LED OFF (high)
Diese zwei Befehle passieren im Mikrosekunden Bereich, so schnell, dass
man gar nichts sieht.
Du musst zwischen diesen zwei noch eine Verzögerungsschleife einbauen.
Etwa so:
movlw 0x00
banksel TRISGPIO
movwf TRISGPIO (Tristate-Ausgänge müssen geschaltet werden)
banksel GPIO
endlos:
call Wait_250ms
bcf GPIO, 2; // LED ON (low)
call Wait_250ms
bsf GPIO, 2; // LED On
goto endlos
Weiss nicht, ob beim pic12f508 TRISGPIO auf anderer Bank ist? Wenn
Fehlermeldung "banksel" weglassen
Fast vergessen: siehe www.sprut.de
dort ist alles bestens beschrieben
Dieter S. schrieb:> Hast Du "4.7 Program Counter" im Datenblatt gelesen, speziell was beim> CALL passiert? Vielleicht erklärt es das ja.
Ja, habe ich, aber es hat mich nicht weiter gebracht. Ich manipuliere
den PC nicht, PA0 ist 0 und der 12F508 hat ja nur eine Page. Das OSCCAL
wird ordentlich beladen und auch sonst kann ich jeden Schritt im
Simulator nachvollziehen, nur eben den CALL nicht.
Der PC ist ja praktisch nur 8-Bit breit. Er könnte also eine Adresse wie
0x1F5 garnicht aufnehmen. Im Assembly-Code steht auch der Mnemonic "09
F5", also ist es innerhalb der Bank, die ja nur 256 12-Bit Instruktionen
enthalten kann, eine art relativer Call.
Jochen-paul S. schrieb:> Stop->goto->stop darf es in diesem Programm nicht geben, du willst ja> dass die LED immer wieder blinkt....
Das dient nur zur Simulation. Um eine LED geht es mir dabei erstmal
garnicht. Der goto STOP war eine Endlosschleife, damit das Programm da
endet.
Olli Z. schrieb:
Tippfehler:
> die ja nur 512 12-Bit Instruktionen
Der Compiler scheint die Programme immer ans Ende vom Flash zu legen...
Ich muss mich hier nochmal einlesen wo mein Denkfehler liegt mit dem PC:
"Because PC<8> is cleared in the CALL instruction or any modify PCL
instruction, all subroutine calls or computed jumps are limited to the
first 256 locations of any program memory page (512 words long)."
Ohne das ich mir das Gemurkse jetzt angesehen haette, 2 Tipps:
- Benutze mindestens einen PIC, den dein Programmieradapter auch
debuggen kann. Z.B. einen 16F819 o.ae. Meinen ersten PIC habe
ich z.B. von einem HP-Batterypack fuer den RAID-Controller recycled.
Das war/ist besagter 16(L)F819...
Und wirf blos das Winzzwergel 508 in eine d0nkle Ecke.
Um die "Familie" kennenzulernen, ist der schlicht ungeeignet.
- Lass den Einfachst-Assembler links liegen, und installiere dir
XC-8 und benutze den dort mitgelieferten Assembler.
Fuer das alte MP-Lab ist die letzte verwendbare XC-8 Version: 1.45.
Spaetestens, wenn einem die kleinen Kerlchen naeher gekommen sind,
wird man auch C benutzen wollen, und das auch gerne mit ein wenig
Assembler aufpeppen wollen. Da ist man dann, wenn man den XC-8
Assembler bereits kennt, klar im Vorteil.
Eingestellt mit Linker-Option "-PmyMain=0020h"
Ich habe mal den map-output in den Linker-Options aktiviert und da
erkennt man das er nichtmal den Reset-Vector richtig platziert:
1
Non line specific message::: warning: (2092) relocatable list file is not available; fixup overflow list file messages cannot be generated
Viele empfehlen anstelle dem MPLAB-X lieber die alte Version (v5.x) zu
installieren, da damit alles wie erwartet klappt :-(
Achja, ich benutze "MPLAB X IDE" v6.15, "pic-as" v2.45 aus "XC8" v2.45
Olli Z. schrieb:> Dazu habe ich einen PIC12F508 zur Verfügung, also ein> Winzling unter den PICs, aber übersichtlich vom Befehlssatz her :-)
Für "übersichtlich" kannst Du Dir nichts kaufen. Mehr Befehle sind immer
besser, Du mußt ja nicht gleich alle benutzen.
"übersichtlich" übersetze mit "stark eingeschränkt", das kommt eher hin.
Mit nur 2 Level Stack und ohne Interrupts möchte ich nie arbeiten
müssen. Da muß man zu sehr um die Ecke denken, um selbst einfachste
Projekte zu realisieren.
Ich hab mich früher immer gewundert, warum PIC-Programme immer soviel
gleichen Code hintereinander enthalten. Bei dem winzigen Stack sind
Calls das pure Gift, daher wurde das Unterteilen in Unterfunktionen
weitgehend vermieden. Was aber stark zu Lasten der Lesbarkeit und
Erweiterbarkeit geht.
Ich hab mit 8051 angefangen, da war Stack nie eine Problem und daher
habe ich auch fleißig gecallt und Unterfunktionen benutzt.
Ich würde Anfängern nicht unter ATtiny85 empfehlen, da paßt selbst float
in C drauf, wenn man möchte. Und der hat auch nur 8 Pins.
Wird im MPLAB mit der Voreinstellung "relocatable" oder "absolute"
gearbeitet?
Mit "absolute" sollte der Code dort geladen werden wo man es selbst
bestimmt.
Nachtrag:
Habe selbst etliches mit den sehr ähnlichen PICs aus der 10F200 -Serie
gemacht. (12-Bit Befehlswort; gleicher Befehlssatz, noch weniger Pins
und weniger Speicher)
Mit "absolute"-Voreinstellung f. die Codegenerierung hatte ich nie
solche Probleme.
> Mit "absolute"-Voreinstellung f. die Codegenerierung hatte ich nie> solche Probleme.
Ich wuerde eher vermuten, dass die Einstellung mit einem XC-8
als Compiler, heute wenig (= gar keinen) Einfluss hat.
Olli Z. schrieb:> wird ordentlich beladen und auch sonst kann ich jeden Schritt im> Simulator nachvollziehen, nur eben den CALL nicht.>
Meine Erfahrung ist auch, dass man sich nicht zu 100% auf den Simulator
verlassen kann. Übrigens kann man sich auch nicht zu 100% auf den
Codeconfigurator von MPLAX verlassen.
Motopick schrieb:> .......mit einem XC-8> als Compiler, heute wenig (= gar keinen) Einfluss hat.
Gut möglich.
Ich hab den "mpasm" verwendet. Das hat bei mir immer ohne Beanstandung
funktioniert.
Hans schrieb:> Wird im MPLAB mit der Voreinstellung "relocatable" oder "absolute"> gearbeitet?
Genau. Im "MPLAB-XC8-PIC-Assembler-User-Guide-50002974.pdf" Sektion 4.8
steht: "Unless defined as abs (absolute), psects are relocatable".
Also habe ich der PSECT ein "abs" angefügt:
1
PSECT resetVec, class=CODE, delta=2, abs
2
ORG 0000h
3
resetVec:
4
goto main
5
6
PSECT myMain, class=CODE, delta=2, abs
7
ORG 0020h
8
...
und schon klappt es mit dem "ORG" unterhalb eine absolute Adresse
vorzugeben:
Und siehe da, plötzlich funktionieren auch die CALLs wie erwartet. Es
scheint also wirklich so zu sein das der kleine Baseline PIC nur
Zieladressen in den ersten 100h Adressen der Bank anspringen kann.
Ja, so nach und nach komme ich dahinter das die 12F Serie eher nur für
einfachste Steueraufgaben zu gebrauchen ist...
P.S.: MPASM gibt es mit der neuen X-IDE nicht mehr, der wurde durch XC8
ersetzt.
Motopick schrieb:> Ich wuerde eher vermuten, dass die Einstellung mit einem XC-8> als Compiler, heute wenig (= gar keinen) Einfluss hat.
Und wieder mal liegt Du total falsch.
> Und wieder mal liegt Du total falsch
Gelegentlich programmiere ich auch PICs.
Meine machen aber was sie sollen. Und ich muss da auch
keinen anderen fragen.
Die Einstellung "absolut" und "relocatable" gibt es schon
im uralten MPLAB und bezog sich auf den MPASM.
Da du ja aber immer nur "Neuling" bist, sehe ich dir diese
Unkenntnis gerne nach.
Du hast zwar jetzt "einen" Weg gefunden, der ist dir aber
verbaut, wenn du noch andere Dinge dazulinken willst.
Deswegen koennte man jetzt den von dir berschrittenen Weg
auch als "falsch" bezeichnen.
Olli Z. schrieb:> Es> scheint also wirklich so zu sein das der kleine Baseline PIC nur> Zieladressen in den ersten 100h Adressen der Bank anspringen kann.
Steht exakt so im Datenblatt, Bit A8 = 0:
"For a CALL instruction, or any instruction where the PCL is the
destination, bits 7:0 of the PC again are provided by the instruction
word. However, PC<8> does not come from the instruction word, but is
always cleared (Figure 4-6)."
Für einen Call in die 2. Pages muß man also ein Label in den 1. Pages
callen, wo dann ein Goto zum Ziel steht.
Olli Z. schrieb:> Ja, so nach und nach komme ich dahinter das die 12F Serie eher nur für> einfachste Steueraufgaben zu gebrauchen ist...
So ist es, du hast dir den schlimmsten Krüppel unter den Pics
ausgelesen. Die neueren 12F sind extrem besser, haben auch Interrupt und
interessante Peripherie.
... alles schonmal besprochen.
Beitrag "Vom MPASMWIN zum PIC-ASS : Übersetzungshilfe."
... wie man mit rumraten anstatt zuvor nachlesen schlau werden kann
verstehe ich niemals.
pic-as und pic12/16xx User guide zuvor lesen ist Pflicht, aber
wahrscheinlich total old school.
... wie Unsinn immer noch weiteren Unsinn anzieht, zum staunen - wau!
Olli Z. schrieb:> ....so zu sein das der kleine Baseline PIC nur> Zieladressen in den ersten 100h Adressen der Bank anspringen kann.
Wenn ich mich richtig erinnere:
CALL kann nur zu den (unteren) 8-bit-adressen springen.
GOTO kann 9-bit adressen anspringen.
Vermutlich ist das 12-bit Programmwort zu kurz um beim call-befehl auch
noch eine 9-bit Adresse aufzunehmen.
Die Pics mit 14-bit Programmwort haben diese Beschränkung nicht.
Motopick schrieb:> Deswegen koennte man jetzt den von dir berschrittenen Weg> auch als "falsch" bezeichnen.
+1
Anstelle von Rumgemurkse mit "absolut" und ORG und EQU und ...
sollte man versuchen zu lernen, wie man das im aktuellen
Jahrtausend dem Linker überlässt.
MPLAB_XC8_PIC_Assembler_User_Guide_for_Embedded_Engineers.pdf
könnte dabei hilfreich sein. -> 9. Baseline Code Example
Ist leider ohne ganz ausfühliche Erläuterungen, aber man kann evtl.
auch mal da schauen -> 4. A Basic Example For Mid-range Devices
https://github.com/dsoze1138/MPLABXv5xx_pic-as_examples
... Nahrung zum schlauer werden.
Selber Linker spielen macht nur für spezielle use cases Sinn, also <org>
wird besser immer durch psect Anweisung ersetzt. Wenn es sein muss,
werden die psect dann mit Linker Option auf absolute Addr plaziert
innerhalb der Project Config.
Ich habe hierzu nur einen use case, dass ich am flash ende eine
Prüfsumme plaziere. Sonst brauche ich sowas nie.
> am flash ende eine Prüfsumme plaziere
Steht da nicht der Kalibrierwert fuer den internen Oszillator?
Den braucht man natuerlich nicht, wenn der PIC seinen Takt von
einem Quarz(-ozillator) bezieht. Aber sonst?
Man kann auch Datentabellen in die erste Page legen.
Dann braucht man fuer den Zugriff das High-Register nicht
und kann es einfach loeschen statt einen Wert setzen zu muessen. :)
Motopick schrieb:>> Mit "absolute"-Voreinstellung f. die Codegenerierung hatte ich nie>> solche Probleme.>> Ich wuerde eher vermuten, dass die Einstellung mit einem XC-8> als Compiler, heute wenig (= gar keinen) Einfluss hat.
Gibt es diese Einstellung überhaupt noch?
Olli Z. schrieb:> Also habe ich der PSECT ein "abs" angefügt:PSECT resetVec, class=CODE,> delta=2, abs> ...> und schon klappt es mit dem "ORG" unterhalb eine absolute Adresse> vorzugeben:
Es könnte sein, dass da nicht immer das dabei raus kommt, was man denkt
User Guide
>4.9.41 Org Directive>The ORG directive changes the value of the location counter within the>current psect. This means that the addresses set with ORG are relative to>the base address of the psect, which is not determined until link time.>>Note: The much-abused ORG directive does not move the location counter to>the absolute address you specify.
Jochen-paul S. schrieb:> So ist es, du hast dir den schlimmsten Krüppel unter den Pics> ausgelesen. Die neueren 12F sind extrem besser, haben auch Interrupt und> interessante Peripherie.
Die neuen 12F können deutliche mehr, werden aber für Anfänger schnell
unübersichtlich, so hat der PIC12F1840 schon 2 Pages und die Register
sind auf 8 Banks verteilt.
Stephan S. schrieb:> werden aber für Anfänger schnell> unübersichtlich, so hat der PIC12F1840 schon 2 Pages und die Register> sind auf 8 Banks verteilt.
Insbesondere für Programmierer, die aus der 8051- oder AVR-Ecke kommen,
ist das ganze Banking- und Paging-Geraffel eine Qual. Das sollte man
besser dem C-Compiler überlassen.
PIC in Assembler ist wirklich nur was für eingefleischte Fans, die
vorher nicht von anderen Architekturen ohne diesen Hassle verwöhnt
worden sind.
Insbesondere, wenn durch Änderungen sich Code über Pagegrenzen
verschiebt, sind Anfänger regelmäßig geschockt, wenn der PIC plötzlich
Amok läuft (z.B. RETLW-Fallgrube).
Sehr schön einfach finde ich den 8051-Assembler. Mit den Bitbefehlen
kann man direkt Logik-Gatter implementieren, mit MOVC bequem
Tabellenzugriffe, mit DPTR computed Jumps und Calls und 8Bit-MUL/DIV
sind auch ganz nett.
Ja, ich habe es verstanden, vielen Dank. Dennoch interessant das alles
mal zu hören und zu erfahren, auch wenn es nur dazu dient zu wissen was
man besser nicht macht ;-)