PIC in Assembler programmieren


© Januar 2022, letzte Änderung am 01.04.25

--- still under construction ---

Übersicht

MCU PIC 12F1840

Bei der hier vorliegenden Anwendungen, Lichtsteuerung,
habe ich mich für einen 8 Bit-PIC Prozessor entschieden,
da ich den bereits seit längeren verwende.

Um die richtigen Komponenten zu finden,
habe ich zunächst eine passende CPU, genauer MCU, gesucht.
In meinen Fall fand ich den 8 Pin PIC 12F1840 geeignet.

Es ist eine 32 MHz 8-bit MCU - Micro controller unit mit folgender Peripherie.
Wobei die meisten Befehle innerhalb eines 'cycle' = 4 Oszillator Zyklen
hier 8 MHz (bei 32 MHz Oszillator) oder 125 ns abgearbeitet werden.

Name Pin     Pin Name
VDD 1 8 GND
RA5 2 7 RA0
RA4 3 6 RA1
RA3 4 5 RA2

Zum Anfang

Minimal - Entwicklungssystem

Um einen PIC-Prozessor von Microchip programmieren zu können,
benötigt man ein IDE - integrated development environment
oder Entwicklungs-Umgebung.
Kleinster gemeinsamer Nenner war früher MPLAB mit den Programmer PICkit 3.

Einen Programmer als Selbstbaulösungen, welche einen Parallelport benötigt,
betrachte ich nicht mehr.

Auf der  Microchip.com  Seite unter dem Abschnitt
"Tools and Resources / Develop" stehen dann folgende Tools.

Entsprechend der Anleitung unter  microchipdeveloper.com/MPLAB dependencies
vorzugehen, habe ich getrost ignoriert.
Es reicht mittlerweile die Entwicklungsumgebung unter  microchip.com 
runter zu laden, zu entpacken und zu installieren.   Z.B. wie folgt:

cd Downloads/
ls
MPLABX-v6.20-linux-installer.sh

sudo sh MPLABX-v6.20-linux-installer.sh 
64-bit Linux detected.
Check for 64-bit libraries
Verifying archive integrity... All good.
Uncompressing MPLAB X 'v6.20' installer...

Es öffnet sich ein grafischer Dialog, wo man die Lizenz annehmen muss.
Bei mir wird kein Proxy verwendet. Und ich habe nur 8-bit MCUs ausgewählt.
Als Folge, wird der XC8 C Compiler installiert (freie Version).
Ich habe Einstellungen für alle Benutzer und xc8 zu den Umgebungsvariablen hinzugefügt.
Für die Aktivierung der C Compiler Lizenz wird eine Host ID herausgespuckt.
Z.B. 525400112fbd

Zum Anfang

Erster Test mit MPLAB

Für einen ersten Test habe ich zunächst ein Projekt angelegt und ein Minimalprogramm geschrieben.
Also CTRL-SHIFT-N für ein neues Projekt.

new project

Als Projekttyp wähle ich   Microchip Embedded  und  Anwendung.

project type

Dann muß ich mich entscheiden für welchen Prozessor.
Der PIC 12F1840 ist zu finden unter Mid-Range 8-bit MCUs.

choose CPU

Um den an USB angeschlossenen Programmer PICkit 3 in einer virtuellen Maschine sehen zu können,
muß er weitergeleitet werden (hier MX-Linux in einer KVM, eingestellt vom virt-manager).

forward USB

Also der PICkit Programmer muß weitergeleitet werden.

select PICkit

Zunächst habe ich nicht den XC8 C-Compiler, sondern den Assmbler ausgewählt.

choose assembler

Den Projekt-Ordner habe ich gelassen, den Namen habe ich umbenannt in  test01.

select names

Nun muß noch eine Datei für den Assembler-Code angelegt werden.

new file

Zur richtigen Behandlung sollte die Datei auch als Assembler-Datei gekennzeichnet sein.

filetype assembler

Zu guterletzt ist ein Dateiname zu definieren.

nameing

Wenn ich nun ein Programm schreibe, stolpert der Assembler bereits am
#include "p12f1840.inc".

Eine Möglichkeit das zu beheben war, sich die Include-Datei aus dem Internet zu besorgen
und ins eigene Projekt zu kopieren.
Ich habe die Datei z.B. unter  github.com  gefunden und nach
 /home/m/MPLABXProjects/test01.X/p12f1840.inc  kopiert.
Die Include-Datei wird zwar erkannt, aber bereits in Zeile 33 ist der erste Fehler.

Unter  Tools > Templates  finde ich nur leere Assembler Templates.
Aber unter  Tools > Plugins > Available Plugins > GPUTILS Toolchain 
gibt es etwas interessantes, was nach der Installation einen Neustart von MPLAB erfordert.

Um  GPUTILS  statt den  pic-as  zu verwenden, ist es nötig das Projekt zu ändern
und GPUTILS zu installieren.

Zum Anfang

GPUTILS Installation

Installiert man gputils via Synaptic auf DEB 9 oder Mint 20.3 oder MX-23.5-Linux (DEB 12)
erhält man in allen Fällen eine veraltete gputils Version 1.4.0 von 2012.

Es macht also Sinn sich die Version 1.5.2 vom 25.11.2023 runter zu laden.
Siehe   sourceforge.net gputils
Auf Sourceforge.net möchte zusätzlich fsdn.com Zugriff haben.

gputils macht noch aus einen anderen Grunde Sinn.
Den XC8 gibt es in einer kostenpflichtigen und in einer freien Version.
Leider ist der Code der über die freie Version erzeugt wird, nicht mehr optimiert.
Dadurch passen z.B. die USB Beispiele nicht mehr in den Speicher.

cd Downloads/
ls
gputils-1.5.2.tar.bz2

tar -xaf gputils-1.5.2.tar.bz2    entpacken
cd gputils-1.5.2

./configure
…
/usr/bin/ld: cannot find Scrtl.o: No such file or directory

sudo apt install gcc-multilib

./configure                       2. Versuch
make
sudo make install

gpasm --version                   Erwartungsgemäß die richtige Version.
gpasm-1.5.2 #1325 (Mar 31 2025)
nano config.log                   falls etwas nicht funktioniert.

Nun kann über das Werkzeug-Symbol das Projekt geändert werden.

project properties

Hier kann nun gpasm ausgewählt werden.

select gpasm

Mit dieser Lösung, mit  gpasm , kann zwar noch eine PIC MCU via PICkit 3 programmiert werden.
Aber leider funktioniert auf diese Weise nicht mehr der Debugger von MPLAB.

simulation does not work

Die Alternative zu MPLAB-Simulator heisst gpsim und läßt sich unter  sourceforge.net  runterladen.

Etwas ähnliches hatte ich vor Jahren schon einmal gehabt mit Mint 20.3. Damals schrieb ich…
Auf einem via KVM virtualisierten Linux Mint 20.3 läuft zumindest MPLAB X IDE 6.00
und gputils 1.5.2 und es läßt sich ein lauffähiges PIC-Programm erzeugen
welches via PicKit 3 auf einen 12F1840 brennbar ist.

Sobald ich jedoch versuche etwas zu debuggen, bekomme ich eine Fehlermeldung.
nico01.X.debug.cof does not exist.
Daher ist noch  sourceforge.net gpsim  runter zu laden und zu installieren.
Zum Vergleich, Synaptic enthält Version 0.31.0 statt 0.32.1.

Zum Anfang

gpsim Installation

gpsim läßt sich auch über Synaptic installieren.
Zum Vergleich, die Synaptic Version bei MX-23.5-Linux ist 0.31.0 und die Version über github ist 0.32.1 .
Optimalerweise versuche ich die neueste Version zu installieren.
Dafür ist das runter geladene Paket zunächst zu entpacken.

cd Downloads/
ls
gpsim-0.32.1.tar.gz

tar -xaf gpsim-0.32.1.tar.gz      entpacken
cd gpsim-0.32.1
./configure
configure: error: popt not installed: cannot find popt.h

sudo apt install libpopt-dev      Bib. um zu parsen
checking for pkg-config... no
checking for P_GTK... no
…
To get pkg-config, see <http://pkg-config.freedesktop.org/>.

Bei der  gpsim-Seite  wird darauf hingewiesen, dass gtk+extra nötig ist.
Was ich dann von  sourceforge.net  runtergeladen habe, entpackt…
und leider gibt es bei configure ein Problem.

cd ~/Downloads
tar -xaf gtkextra-3.3.4.tar.gz
cd gtkextra-3.3.4                 die 2.1.2 ist von 2010-03-23
./configure
checking for pkg-config... no
checking for GTK... no
…
To get pkg-config, see .

Also habe ich von einer Unterseite  pgkconfig-0.29.tar.gz  vom 27.09.2017
runtergeladen, entpackt und ein vergleichbares Problem gefunden.

cd ~/Downloads
tar -xaf pkg-config-0.29.2.tar.gz
cd pkg-config-0.29.2
./configure 
configure: error: Either a previously installed pkg-config or "glib-2.0 >= 2.16" could not be found.

Leider führt das so nicht zum gewünschten Erfolg.
Da ich noch irgendwo den Hinweis fand "Other dependencies include gtk-2.0, readline, popt",
versuchte ich dem auch nachzu gehen.
Doch  sudo apt install libreadline-dev  hilft auch nicht weiter.
Geht man auf die  gtk.org -Seite, fällt auf dass 4.18.3 aktuell ist und 3.24 noch unterstützt wird,
aber 2.16 definitv nicht mehr.
Also habe ich der Empfehlung der Seite  virajstechblog.blogspot.com  noch eine Chance gegeben.

sudo apt install libgtkextra-dev        libgtkextra-3.0
cd ~/Downloads/gpsim-0.32.1
cp ./configure configure.orginal
nano configure
Nützt nichts, da gtkextra-2.0 im auskommentierten Bereich steht

Also zurzeit habe kapituliert und kurzerhand gpsim via Synaptic installiert.
Also

gpsim --version
gpsim-0.31.0 # (Aug 17 2021)

Zum Anfang

Das erste Test Programm

Um einen kleinen Test zu machen, ob die Simulation funktioniert, habe ich folgenden Code geschrieben.
Es werden alle 5 Ausgänge aktiviert und hoch gezählt.

; test01.asm 31.03.2025
;         5V 1   8 Gnd
; Out    RA5 2   7 RA0 Out 
; Out    RA4 3   6 RA1 Out
; in     RA3 2   5 RA2 Out

PROCESSOR   12F1840              ; list p=12f1840
#include    "p12f1840.inc"
__CONFIG _CONFIG1, 0xC9A4	
__CONFIG _CONFIG2, 0xDFFF

            errorlevel -302

#define     cPause  0x80
#define     cWeakR  b'00001000'  ; weak pullup on RA3
#define     cInOut  b'00001000'  ; RA3 IN, Rest Out

cblock      0x20
            vCnt                 ; variable für einen Zähler
endc
;***********************************
          org     0x00           ; reset oder CODE 0x00
          goto    sReset
;***********************************
          org     0x04
          retfie
;***********************************
sReset:   banksel PORTA
          clrf    PORTA        ; b0 page 100
          banksel LATA
          clrf    LATA         ; b2 0 = latch output page 98
          banksel ANSELA       ; b3
          clrf    ANSELA       ;    0 = only digital
          banksel WPUA         ; b4
          movlw   cWeakR       ;    1 = pull-up enabled
          movwf   WPUA
          banksel OPTION_REG   ; b1
          bcf     OPTION_REG, NOT_WPUEN ; 0 =  enable weak pullups
          banksel TRISA
          movlw   cInOut
          movwf   TRISA        ; b1 alles was möglich ist, ausgang
          banksel OSCCON       ; b1 1 = SPLLEN, 1110 = IRCF, 00 = SCS -> FOSC
          movlw   0xF0         ;    500 kHz -> 32 MHz
          movwf   OSCCON       ; b1
          call    sOscTune     ;    retlw 0x00
          banksel OSCTUNE
          movwf   OSCTUNE      ; b1

bL1:      movlw   0xff
          movwf   vCnt
bL2:      decfsz  vCnt, 1
          goto    bL2
          banksel LATA
          incf    LATA,1       ; b2
          bra     bLoop1

          org     0x07ff
sOscTune: retlw   0x00         ; factor cal. freq.
          END

Wenn ich nun in der IDE auf  Debug > Debug Main Project  klicke,
bekomme ich zwar eine Fehlermeldung, aber es wird auch eine  .cod-Datei erstellt.
Diese befindet sich hier in  /home/m/MPLABXProjects/test01.X/dist/default/debug/ .
Leider ist Thunar nicht in der Lage eine Uhrzeit anzuzeigen.

thunar folder

Also im Terminal folgendes eingeben.

cd cd ~/MPLABXProjects/test01.X/dist/default/debug/
gpsim test01.X.debug.cod

Es erscheint dann ein Menü, wo ich mir zwei Fenster geöffnet habe.
Windows > Source  und  Windows > RAM
Das Ergebnis sieht dann wie folgt aus.
Es wurde bereits schon einige Male step gedrückt.

simulation does not work

Funktioniert alles wie geplant,

Zum Anfang

4 Kanal PWM für Lichtsteuerung

Wie man aus den Datenblatt sieht, kann die PIC Hardware des 12F1840 nur einen
pulse weiten modulierten - PWM Kanal bedienen.
Benötigt man meherere Kanäle ist ein anderer Prozessor zu wählen oder
man erzeugt die PWM per Software selbst.
Dabei ist zu berücksichtigen, das 8 Bit Auflösung zu gering ist.
Das bedeutet das in kleinster Dimm-Stufe, also ca. 0,4% Einschaltzeit
= 1/256   es bereits zu hell ist.

Um möglichst wenig CPU-Last zu erzeugen, lade ich im Interrupt einen
Timer mit unterschiedlichen Zeiten entsprechend der jeweiligen PWMs.
Dies habe ich z.B. mit den 16-Bit Timer TMR2 realisiert.
Im schlechtesten Fall ist von allen Kanälen die PWM anders,
wie im folgenden Besipiel gezeigt.

4 channel timing diagramm

Bei diesen konkreten Fall sind folgende Schritte im Timer-Interrupt INT zu erledigen

Nun kann man sich noch vorstellen, das alles Aus ist oder alles zu 100% Ein ist.
Dann ist nur noch ein  INT  je Periode nötig, nicht jedoch für die PWM,
sondern für die Tastenabfragen in anderen Routinen.

Wenn 1 bis 5 INTs je Periode tmax vorkommen, ist auch daran zu denken
daß eine gewisse Zeit, vom INT bis der Timer neu geladen wird, verstreicht.
Auch wenn es nur ein paar µs je INT sind, ist es wegen der Veränderlichkeit zu berücksichtigen.
Das alles fehlerfrei zu berücksichtigen, habe ich für 2 Kanälen hin bekommen,
aber dann wurde es mir zu komplex.

Weitere Aspekte sind, dass die zeitliche Auflösung der PWM
nicht unter der Verweildauer im INT sein kann.
Das heist der schmalst mögliche Puls ist die Zeit vom Ausgang ändern im INT
bis zum nächsten Ausgang ändern im darauffolgenden INT.
Die INT-Routine sollte also möglichst schnell & schlank sein.

Um die INT-Routine schneller zu bekommen, bin ich auf den 8-Bit Timer 0 ausgewichen.
Um die veränderliche Anzahl an INTs zu vermeiden, gehe ich je Periode (0..255)
stehts zwei Mal in den INT, auch wenn ich das nicht benötige.
Um die Auflösung zu erhöhen benutze ich eine art "dizzern".
Das bedeutet Ich variiere die 8 Bit PWM innerhalb 4 Zyklen so,
dass der Mittelwert den 10 Bit Wert entspricht.

Dann möchte ich noch Tasten und ein Infrarot-Signal (RC5) auswerten.
Da beide Signale nicht so zeitkritisch sind (889 µs oder die doppelte Zeit bis eine Pegeländerung erfolgt)
werden sie nicht im INT abgearbeitet.

Im INT stehen also nur folgende Zeilen, welche ca. 2 µs benötigen.

      org     0x04        ; INT 3..4 cycl to react
                          ; WREG STATUS BSR FSR PCLATH -> shadow reg.
      bcf     INTCON,TMR0IF ; bx 5
      movfw   v_fsr1l     ; bx 6
      movwf   FSR1L       ; bx 7
      moviw   0[FSR1]     ; bx 8
      banksel TMR0        ; b0 9
      movwf   TMR0        ; b0 10  TRM0 war schon bis 06
      moviw   1[FSR1]     ; bx 11
      banksel LATA        ; b2 12
      movwf   LATA        ; to 13 LATA
      btfsc   WREG, 7     ; bx 14
      incf    v_cnt       ; bx 15 jeder 8. INT 
      moviw   2[FSR1]     ; bx 16
      movwf   v_fsr1l     ; bx 17 FSR1L
      retfie              ; 2 cycles schreibt WREG STATUS BSR FSR PCLATH

Überschrift 1

choose system drive

Zum Anfang

Quellen

gputils   GPUTILS is a collection of tools for the Microchip PIC microcontrollers.
  It includes gpasm, gplink, and gplib.
gpsim   gpsim is a full-featured software simulator for Microchip PIC microcontrollers
sourceforge.net   gpsim - The gnupic Simulator Files
xizard   This software is a GUI which allows you to easy assemble PIC programs
  It uses gpasm software
pikdev.free.fr   PiKdev is a simple graphic IDE for the development of PIC-based applications.
misterelectronicoes.wordpress.com   Picsimlab interesting simulator.
https://github.com/LGTMCU/gputils/blob/master/gputils-extra/examples/example2/mastri2c.asm
https://microcontrollerelectronics.com/pic-assembler-coding/
https://github.com/74hc595/PIC16F1-USB-Bootloader/blob/master/bootloader.asm

Zum Anfang