PIC-Controller - Home of Manuel Magninch

Direkt zum Seiteninhalt

Hauptmenü:

PIC-Controller

Controller
SYSTEM-CLINCH
PIC Microcontroller HOWTO

Author: Manuel Magnin - MMagnin(a)Clinch.ch
Datum: 12. April 2017
Quelle: http://www.clinch.ch/clinch/PIC/PIC-Controller.htm
Version: V0.0
Geändert: ...

Dieses Dokument soll die grundlegenden Schritte zur Erstellung einer PIC programmier und Entwicklungsumgebung aufzeigen.
Dieses Zusammenstellung ist für Mess- und Steueraufgaben gedacht und ausgelegt.
Die PIC Familie hat folgende Eigenschaften:
- Sehr robuster Aufbau, grosse Toleranzen (betriebsstabil)
- Starke Ausgangstreiber 25mA (Nach Masse und nach Vdd), DIL-Gehäuse (und andere)
- Sehr simpler Assembler RISC Befehls-Satz  bestehend aus 35 Befehlen
- Enfache und vielseitige Beschaltung der Oszilatoren (Quarz, extern, R/C, R, intern)
- Minimaler Stromverbrauch bei geringen Taktraten und Spannungen  (2mA, 5V, 4MHz / 15uA, 3V, 32kHz, <1uA Sleep)
- Einfache Programmierung und Reprogrammierung (Flash)


Übersicht der wichtigen DIL18 Typen:
Die PIC Microcontroller eignen sich speziell für kleine Steueraufgaben, da diese günstig und einfach zu programmieren sind.
Die Controller können mit einfachsten mitteln in der Schaltung programmiert werden. Es sind nur wenige externe Bauteile für den Berieb notwendig. 
MCU Typ Gehäuse Flash / RAM I/O Lines Preis Bemerkungen
PIC 16F84A DIL18 1kWord / 68Byte 13 2.00 1Ti,Oldtimer
PIC 16F627 DIL18 1kWord / 224Byte 16 1.50 PWM,3xTi,Compar
PIC 16F628 DIL18 2kWord / 224Byte 16 1.70 RS232,PWM,3xTi,Compar
PIC 16F648 DIL18 4kWord / 256Byte 16 2.00 RS232,PWM,3xTi,Compar
PIC 16F818 DIL18 1kWord / 128Byte 16 1.80 5xADC10,PWM,SPI,I2C,2xTi, ab 87uA
PIC 16F819 DIL18 2kWord / 256Byte 16 2.20 5xADC10,PWM,SPI,I2C,2xTi, ab 87uA
PIC 18F1220 DIL18 2kWord / 256Byte 16 2.50 RS232,7xADC10,PWM,4xTi
PIC 18F1320 DIL18 4kWord / 256Byte 16 2.70 RS232,7xADC10,PWM,4xTi

PIC Incircuit Programmer mit ICSP Schnittstelle. Der Programmierer ist kompatibel zu WinXP bis Win10 und läuft sowohl mit RS232 (+-12V) Schnittstellen (PC Integriert), so wie mit USB zu RS232 Wandlern (mit +-5V).

Um alles zu vereinfachen wurde ein Entwiklungsboard erstellt (mit Platine) das den Programmer mit enthält. Zur Programmierung von PICs in der Schaltung kann bei diesem Board nur der Programmerteil mit dem ICSP Port verwendet werden. Wenn mit dem ICSP Port und einem Kabel ein PIC auf einer anderen Platine programmiert werden soll, so darf keim PIC auf der Platine des ICSP Programmers stecken.
Der 10k Widerstad und die Dioder am Pin 4 (Vpp) ist nur beim 16F84 notwendig.
Je nach PIC Typ werden die Pins OSC1, OSC2 & Vpp nicht benötigt, dann können diese auch als ein oder Ausgang für Steuerzwecke genutzt werden. D.h. im besten Fall stehen von den DIL 18Pin's ganze 16 Pin's für Ein- und Ausgänge zur Verfügung.

 
PIC-CPU16FX-InCircuit-V0.1


Übersicht der Taktgeneratoren:
MCP Standard R / C  Intern Bemerkungen
PIC 16F84A Quarz 30k - 4MHz - 22pF+10k=2MHz, 330p+56k=4MHz
PIC 16F62x Quarz, 15-30pF R ohne C: 10k - 8MHz ja nur-R: 1k=10MHz, 10k=1.6MHz, 47k=3MHz
PIC 16F64x Quarz, 15-30pF 30k-4MHz/3-100k, >20pF - 100pF+5k=1MHz, 22pF+10k=2MHz,
 22pF+5k=4M, 100p+10k=0.6MHz
PIC 16F818 Quarz, 15-30pF
30k-4MHz/3-100k, >20pF
32k-8MHz nur-R: 1k=10MHz, 10k=1.6MHz, 47k=3MHz
PIC 18F1220 Quarz 30k-4MHz/3-100k,>20pF 125k-8MHz

RC Taktberechnung:  F = 1 / (  (R * C) * Ln( Vdd / (Vdd - Vdd*0.9)) )
für 5V Vdd:  F = 1 / ( (R * C) * Ln( 5 / (5 - 5*0.9)) )  =>   F = 1 / (R * C * 2.3)
für 5V vereinfacht: F [in MHz] = 1 / ( R [in kR] * C [in nF]  * 2.3 )
R C F (Clock)
+-10%
Cyklen/Sek +-10%
100kR 100nF 44Hz 11
10kR 100nF 0.44kHz 109
10kR 10nF 4.3kHz 1'087
100kR 1nF 4.3kHz 1'087
10kR 1nF 43kHz 10'870
100kR 100pF 43kHz 10'870
100kR 22pF 0.2MHz 49'407
10kR 100pF 0.43MHz 108'696
10kR 47pF 0.93MHz 231'267
4.7kR 100pF 0.93MHz 231'267
4.7kR 47pF 1.97MHz 492'058
10kR 22pF 1.98MHz 494'071
4.7kR 33pF 2.8MHz 7000'810
10k paral. 10k 22pF 4.0MHz 988'142
4.7kR 22pF 4.2MHz 1'051'215
3.0kR 22pF 6.6MHz 1'646'904
Für den Betrieb mit einer Batterie empfehlen sich 10kR & 1nF mit 43kHz
Für einfache Anwendungen eigenen sich: 10kR & 100pF für 0.4MHz und 10kR & 22pF für 2MHz
Für passende Timer (+-10%) eignen sich: 5kR & 22pF oder 4.7kR & 22pF für ca. 4MHz

CPU16FX-Entw-Circ-V0.1.png

CPU16FX-Entw-PCB-V0.1.png

Programmier-Kabel (nur für PC integrierte RS232 Schnittstellen ausgelegt!)
Sonst die obige Programmer-Schaltung verwenden, die ist auch für USB zu RS232 & Notebooks ausgelegt:

Um die PIC Kontroller zu programmieren reicht ein einfacher Programmieradapter. Um den Aufwand für die Programmierung und Entwicklung zu reduzieren kann der PIC mit einem Programmierkabel und ein paar Komponenten gleich in der Schaltung programmiert und umprogrammiert werden. Das RC-Glied am Clk-In lässt den PIC nach der Programmierung mit ca. 2MHz schwingen.  Vpp wird nach der Programmierung auf ca. Betriebsspannung gebracht und somit in den Betriebsmodus des PICs.

Wichtig für den Programmer ist, dass die Schnittstelle mit +-12V arbeitet (PC Schnittstellen auf dem Prozessorboard). USB zu Serial Schnittstellen Adaper Kabel arbeiten meistens mit +-5 oder +-10V. Dies kann mit einem Voltmeter an der Seriellen Schnittstelle gemessen werden: Pin 5(GND) zu Pin 3(TxD).
PIC InCircuit Programmer



Blinker mit PIC

init:


main:









delay100:

delayf:




delay1:
delaya:

org     0 

clrf     PORTB

bsf     PORTB,0
call    delay100
call    delay100
call    delay100
bcf     PORTB,0   
call    delay100
call    delay100
call    delay100
goto   main

movlw   D'100
movwf  
0x1f
call      delay1
decfsz  0x1f,f
goto     delayf
return

movlw   d'249'
addlw    d'255'
btfss     Status, Z
goto      delaya
return

; start at address 0
; Set all bits of Port-B to Lo

; Set PortB Bit-0 to 1 (LED-ON)
; Wait 100ms
; Wait 100ms
; Wait 100ms
; Clear PortB Bit 0 (LED-OFF)
; Wait 100ms
; Wait 100ms
; Wait 100ms


; (1) load Working reg. with 100
; (1) Save to temp Mem Count
; (0 (4)) Wait for 1mS, 
; (1) it01 := it01 - 1, skip if zero
; (2 (1)) if not Zero go again
; (4) back to calling prog

; (1) load w with 249 (248 loops)
; (1) dec w / w := w - 1
; (1+(1)) Check if z flag is set
; (2 (1)) no, than again
; (4) back to call. prog incl call

PIC-Blinker.png

Lauflicht mit PIC und 8xLED

init:


main:

nextl:






nextr:





delay100:

delayf:





delay1:
delaya:

org     0 

clrf     PORTB

clrf      PORTB
bsf      Status, C
rlf        PORTB, F
call     delay100
bcf      Status, C  
movf    PORTB, F
btfss   Status, Z
goto    nextl

bsf      Status, C
rrf       PORTB, F
call     delay100
bcf      Status, C
movf    PORTB, F
btfss    Status, Z
goto    nextr

goto    main

movlw   D'100
movwf  
0x1f
call      delay1
decfsz  0x1f,f
goto     delayf
return

movlw   d'249'
addlw    d'255'
btfss     Status, Z
goto      delaya
return
; start at address 0
; Set all bits of Port-B to Lo

; Port B clear
; Bit Set Carry for rotate
; rotate port B bits to left
; Wait 100ms
; Bit Clear Carry for rotate
; Check PORTB and Setz Z 
; Check if zero flag is set
; no, than again

; Bit Set Carry for rotate
; rotate port B bits to right
; Wait 100ms
; Bit Clear Carry for rotate
; Check PORTB and Setz Z 
; Check if zero flag is set
; no, than again

; and all agian

; (1) load W reg. with 100
; (1) Save to temp Mem Count
; (0 (4)) Wait for 1mS, 
; (1) it01 := it01 - 1, skip if zero
; (2 (1)) if not Zero go again
; (4) back to calling prog

; (1) load w with 249 (248 loop)
; (1) dec w / w := w - 1
; (1+(1)) Check if z flag is set
; (2 (1)) no, than again
; (4) back to call prog incl call
PIC-8xLED.png
Der Tackt wird mit 22pF + 10kR erzeugt (2MHz)

PIC Assembler Befehlssatz
ADDLW  wert Addiere W und wert, speichere das Resultat in W W := W + wert D,DC,Z
ADDLW  0x00 Teste W und setze Flags D,DC,Z  W := W + 0 D,DC,Z
ADDLW  0xff verkleinere das Arbeitsregister um eins (Decrement) W := W - 1 D,DC,Z
ADDWF  speicher,F Adiere W und den Inhalt der Speicheradresse, 
speichere das Resultat in Speicheradresse
[speicher] := W + [speicher] D,DC,Z
ADDWF  speicher,W Addiere W und den Inhalt der Speicheradresse, speichere das Resultat in W W := W + [speicher] Z
ANDLW  wert Logische Bit-Und Operation von wert mit W, speichere das Resultat in W W := W && wert Z
ANDWF  speicher,F Logische Bit-Und Operation vom Inhalt der Speicheradr. mit W, 
speichere das Resultat in Speicheradr.
[speicher] := W && [speicher] Z
ANDWF  speicher,W Logische Bit-Und Operation vom Inhalt der Speicheradresse mit W,
speichere das Resultat in W
W := W && [speicher] Z
BCF  speicher,bit-nr Bit löschen speicher, Bit Nummer [0..7], lösche ausgewähltes Bit (auf "0") -
BSF  speicher,bit-nr Bit setzen speicher, Bit Nummer [0..7], setze ausgewähltes Bit auf "1" -
BTFSC speich,bit-nr Teste  Bit im Speicher und überspringe nächsten Befehl wenn das Bit "0" ist. -
BTFSS speich,bit-nr Teste  Bit im Speicher und überspringe nächsten Befehl wenn das Bit "1" ist. -
CALL  label Springe zum Unterprogramm Label, Rückkehr mit Return, Returnlw -
CLRF  speicher Lösche den Inhalt des Speichers (=0x00) [speicher] := 0x00 Z
CLRW Lösche das W Register des Prozessors W := 0x00 Z
CLRWDT den watchdog timer zurücksetzen (Reset / clear watchdog) TO,PD
COMF  speicher,W nimm den Inhalt der Speicheradresse und invertiere alle Bits, 
speichere das Resultat in W
W:= [speicher] XOR 0xFF Z
COMF  speicher,F nimm den Inhalt der Speicheradr. & invertiere alle Bits, 
speichere Resultat in Speicheradr.
[speicher] := [speicher] XOr 255 Z
DECF  speicher,W Subtrahiere 1 vom Inhalt der Speicheradresse, speichere das Resultat in W W := [speicher] - 1 Z
DECF  speicher,F Subtrahiere 1 vom Inhalt der Speicheradr., speichere das Resultat in Speicheradr. [speicher] := [speicher] - 1 Z
DECFSZ speicher,W Subtrahiere 1 vom Inhalt der Speicheradresse, speichere das Resultat in W
und überspringe nächsten Befehl wenn das Resultat "0" ist.
W := [speicher] - 1  -
DECFSZ speicher,F Subtrahiere 1 vom Inhalt der Speicheradr., speichere das Resultat in Speicheradr. und überspringe nächsten Befehl wenn das Resultat "0" ist. [speicher] := [speicher] - 1 -
GOTO label Springe zur Marke Label -
INCF speicher,W Addiere 1 zum Inhalt der Speicheradresse, speichere das Resultat in W W := [speicher] + 1 Z
INCF speicher,F Addiere 1 zum Inhalt der Speicheradr., speichere das Resultat in Speicheradr. [speicher] := [speicher] + 1 Z
INCFSZ speicher,W Addiere 1 zum Inhalt der Speicheradresse, speichere das Resultat in W
und überspringe nächsten Befehl wenn das Resultat "0" ist.
W := [speicher] + 1 -
INCFSZ speicher,F Addiere 1 zum Inhalt der Speicheradr., speichere das Resultat in Speicheradr.
und überspringe nächsten Befehl wenn das Resultat "0" ist.
[speicher] := [speicher] + 1 -
IORLW wert Logische Bit-Or von value mit W, speichere das Resultat in W W := W !! wert Z
IORWF speicher,F Logische Bit-Or des Inhalts der Speicheradr. mit W,
speichere das Resultat in Speicheradr.
[speicher] := W !! [speicher] Z
IORWF speicher,W Logische Bit-Or des Inhalts der Speicheradr. mit W, speichere das Resultat in W W := W !! [speicher] Z
MOVLW wert Laden den Wert in das Arbeitsregister W W := wert -
MOVF speicher,W Laden den Inhalt der Speicheradresse in das Arbeitsregister W W := [speicher] Z
MOVF speicher,F Laden den Inhalt der Speicheradresse in die Speicheradresse
(setzt Z Flag entsprechend)
[speicher] := [speicher] Z
MOVWF speicher Speichert das Arbeitsregister W in die Speicheradresse [speicher] := W -
NOP No Operation, nache nichts (braucht einen Cyklus) - -
RETFIE Return from Interrupt, Rückkehr aus einem Interrupt -
RETLW wert Rückkehr aus einem Unterprogramm das mit Call aufgerufen wurde, übergebe Wert -
RETURN Rückkehr aus einem Unterprogramm das mit Call aufgerufen wurde -
RLF speicher,F Rotiere Bits links durch das Carry Bit "C", speichere das Resultat in Speicheradr. C
RLF speicher,W Rotiere Bits nach links durch das Carry Bit "C", speichere das Resultat in W C
RRF speicher,F Rotiere Bits rechts durch das Carry Bit "C", 
speichere das Resultat in Speicheradr.
C
RRF speicher,W Rotiere Bits nach rechts durch das Carry Bit "C", speichere das Resultat in W W := [speicher]>> W C
SLEEP Versetze den Prozessor in den Schlafmodus (StandBy Mode) TO,PD
SUBLW wert Subtrahiere W von wert & speichere das Resultat in W W := wert - W C,DC,Z
SUBLW speicher,F Subtrahiere W vom Inhalt der Speicheradr. &  speichere das Resultat in Speicheradr. [speicher] := [speicher] - W C,DC,Z
SUBLW speicher,W Subtrahiere W vom Inhalt der Speicheradresse & speichere das Resultat in W W := [speicher] - W C,DC,Z
SWAPF speicher,W Austausch obere und untere Bytehälfte, speichere das Resultat in W -
SWAPF speicher,F Austausch obere und untere Bytehälfte, speichere das Resultat in Speicheradr. -
XORLW wert Logische Bit-XOr Operation von wert mit W, speichere das Resultat in W W := wert XOr W Z
XORWF speicher,F Logische Bit-XOr Operation  vom Inhalt der Speicheradr. mit W,
speichere das Resultat in Speicheradr.
[speicher] := [speicher]
XOr W
Z
XORWF speicher,W Logische Bit-XOr vom Inhalt der Speicheradr. mit W, speichere das Resultat in W W :== [speicher] XOr W Z
W = Workingregister des Prozessors, die Angabe ,W ist der Speicher Ort für Resultat im Workingregister (,W=",0")
F = Speicher Ort für Resultat ist eine Speicher-Adresse, , die Angabe ,F = Speicher (,F=",1") (Register File Adresse 0x00 bis 0x7F)
bit-nr = Werte 0..7 (Bit1 bis Bit8)
speicher = ist die Adresse deren Inhalt verwendet werden soll (Register File Adresse 0x00 bis 0x7F)
wert = Konstanter Wert der verwendet werden soll
label = Sprung Ziel (Frei wählbarer Begriff, ohne Sonderzeichen und ohne Leerzeichen)


PIC16F84_Architektur.png

 
Zurück zum Seiteninhalt | Zurück zum Hauptmenü