Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Einstieg in die PIC-Controllerfamile...
#1
Hallo zusammen,

bereits im Vorfeld des Microcontroller-Einstiegskurses und auch jetzt gab es wieder Anfragen, ob man die PIC-Familie
nicht auch behandeln kann. Ich habe als erstes gezögert, weil es für die PIC-Controller nicht solche Highlevel-Softwarebibliotheken
gibt, die den Einsteiger von den Registern des Prozessors abschirmt wie bei der Arduino-Plattform. Ja erste Ansätze sind
unter dem Begriff Pinguino schon zu sehen, aber bis man das erreicht was die aktuellen Controllerfamilien (AVR, ESP8266/32, STM32/Teensy) unter der Arduino-Plattform so können, ich glaube das dauert noch!

Auch hat Microchip, der Hersteller der PICs (mittlerweile auch der AVR-Famile, Atmel wurde ja aufgekauft), mit der MPLAB IDE und den C18, xc8, xc16 und x32 wirklich richtig gute Compiler und Entwicklungswerkzeuge im Programm, die die Baseline 8-Bit MCUs (PIC10/12/16), über die Fortgeschrittenen 8-Bit MCUs PIC18 und PIC24, ebenso die 16 Bit Klein-DSPs dsPIC, aber auch die dicken 32-Bitter PIC32 beherrschen. Nicht zuletzt kann man mit den neusten MPLAB - Werkzeugen auch Programme für AVRs vom kleinen Tiny bis zum XMega erstellen und mit dem Pickit4 auch programmieren bzw. in den Controller flashen!!!

Unter diesen Voraussetzungen wäre der noch kommende Fortgeschrittenenkurs also durchaus für AVRs und PICs gemeinsam möglich und rein unter der Verwendung der MPLAB IDE durchführbar. Ich möchte für die PIC-Leute im Forum aber dennoch eine Art Einstieg geben, wir sind drüben bei den Arduinos ja erst in der 3. Lektion und mit digitaler Ein- und Ausgabe beschäftigt. Ihr werdet sehen, das auch ohne Highlevel-Arduino-Bibliotheken  und rein über Register das Ganze gar nicht so schwierig ist. Vielleicht löst Ihr ja die Aufgaben (Ampel, 7-Segment und alle kommenden ) mal auf einem PIC?

Die PICs selbst sind jedenfalls nicht teurer als Arduinos! Man bekommt Sie für ein paar Euros - selbst die großen 8-Bit PIC18Fxxxx- bei Reichelt, Segor  und und und.
Kostenlos als Sample verschickt selbst Microchip pro Musterbestellung bis zu 6 Microcontroller (3x2 gleiche Typen) innerhalb von wenigen Tagen auch nach Deutschland.
Was man nicht kostenlos bekommt, ist das Programmiergerät, in der Regel ein Pickit. Dieses Pickit gibt es in verschiedenen Versionen, aktuell der Version 4 mit dem auch AVR programmiert werden können. Für uns Hobby-Programmierer reicht auch ein Pickit3 aus. Gibt es als Original in Deutschland so zwischen 35 bis 55 Euro, kostengünstige Nachbauten (die nicht schlechter sind!) auch für 15-20 Euro bei Amazon mit 1-Tag Lieferung. 

Das Programmiergerät Pickit3 sähe dann zum Beispiel so aus:

   

Die Anschlußbelegung ist folgende


.jpeg   PicKit3Pinout.jpeg (Größe: 20,26 KB / Downloads: 228)

Nun sind Arduino fertige kleine Boards mit Spannungsversorgung, Quarz als Taktgeber usw. drauf. Der normale PIC kommt aber "nackig" zum Nutzer und muss halt mit den Komponenten noch versorgt werden. Eine Minimalversion die man auch auf einem Steckbrett aufbauen kann, sähe dann so aus

   

Wer einen PIC ohne USB hat oder den PIC nicht über USB versorgen möchte, der lässt halt den USB-Teil weg.

Was brauchen wir noch? Nun die MPLAB X IDE und für PICs vom 10er bis zum 18er mindestens den xc8-Compiler. Beides (und andere Sachen auch) bekommt man ganz klar von der Microchip-Website für Windows, Linux und Mac!

https://www.microchip.com/mplab/mplab-x-ide
https://www.microchip.com/mplab/compilers

Im Prinzip sind dort sogar Lehrgänge für ASM und C mit zum Download aufgeführt. Ob die ein totaler Einsteiger versteht? Ich glaube nicht, denn selbst bei unserem uC-Kurs wird ja vieles nicht gleicht auf Anhieb verstanden! Man richtet sich halt schon an den Entwickler und Umsteiger auf PICs.

Nun die Installation der MPLAB IDE und des passenden Compiler will ich hier nicht zeigen, Ihr seid alt genug und könnt sicher eine Dialog-geführte Installation allein bewältigen. Ein Grundkurs "PC-Bedienung" wollen wir ja nicht abhalten!

Wenn wir auf dem PC also beides, die IDE und den passenden Compiler installiert haben, starten wir die IDE!

Das sieht dann ungefähr so aus

   

danach wählen wir Datei und Neues Projekt



.jpg   New-Project-Step-1.jpg (Größe: 42,92 KB / Downloads: 228)

Microchip Embedded und Standalone ist das was wir wollen


.jpg   New-Project-Step-2.jpg (Größe: 47,22 KB / Downloads: 227)

Danach wählen wir unseren PIC aus, bei mir ist es ein 18F2550


.jpg   New-Project-Step-3.jpg (Größe: 45,47 KB / Downloads: 226)

Nun suchen wir unser Programmiergerät aus oder halt den Simulator.


.jpg   New-Project-Step-4.jpg (Größe: 49,26 KB / Downloads: 226)

Danach noch den passenden Compiler für das Zielsystem wählen, hier ist ja nur der xc8 Compiler installiert


   

dann gibt man dem Projekt noch einen passenden Namen und wählt den Speicherort aus.
Danach wird in der IDE ein leeres Projekt angelegt.

Was machen wir nun? Nun ein Programm besteht mindestens aus einer Main/main.c Datei,
die legen wir jetzt an.



.jpg   Adding-a-Source-File.jpg (Größe: 44,61 KB / Downloads: 221)


Danach ist die leere Hauptdatei des Programms im Source-Ordner vorhanden, eine Grundstuktur einen C-Programms ist vorgegeben.


.jpg   New-Source-File-Created.jpg (Größe: 17,66 KB / Downloads: 219)

Wollen wir zum Beispiel unseren Wechselblinker aus der Lektion 2 nachbauen, dann ersetzen wir den Dateiinhalt durch folgendes:


Zitat:/*
 * File:   main.c
 * Author: Bernhard
 *
 * Created on 15. Januar 2020, 12:29
 */
#include <xc.h>

#define _XTAL_FREQ 8000000 // meine Quarzfrequenz 8 MHz

// PIC18F2550 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1L
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator (HS))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = ON        // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOR = ON         // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = ON         // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF       // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)



int main()
{
  // Initialisierung, entspricht setup() bei Arduino
  TRISB = 0; // Ganzer PortB als Ausgang
 
  // Hauptprogramm, Dauerschleife, entspricht loop() bei Arduino)
  while(1)
  {
    RB0 = 1;  // LED an RB0 an
    __delay_ms(1000); // 1 Second Delay
    RB0 = 0;  // LED an RB0 aus
    RB2 = 1;  // LED an RB2 an
    __delay_ms(1000); // 1 Second Delay
    RB2 = 0;  // LED an RB2 aus
  }
 
  return 0;
}


Unter _XTAL_FREQ lege ich die Quarzfrequenz meines Steckquarzes fest, mit den ich den PIC antreibe. Ich habe ein 8 MHz Quarz gewählt, andere gehen auch!

Danach kommen die ganzen Configurationsbits des Prozessors, das entspricht ungefähr den FUSES eines AVRs.

Diese erzeuge ich in einem leeren Programm normalerweise so:


.jpg   PIC-Memory-Views-Configuration-Bits.jpg (Größe: 46,38 KB / Downloads: 217)

Am unteren rechten Ende der IDE öffnet sich ein Fester in dem man die Bits mit der Maus setzen oder löschen bzw. Einträge ändern kann.

   

Die Bedeutung der Bits erschließt sich natürlich nur im Zusammenhang mit dem Datenblatt des PIC, hier sind zum Beispiel Einstellung vorzunehmen welche Taktquelle verwendet wird und und und. Eine kurze Beschreibung steht natürlich auch im Fenster, aber ohne Datenblatt hat man da als Neuling keinen Durchblick! Deshalb lesen!

Hat man schlußendlich alle Einstellung gemacht, dann lässt man sich den Source Code dafür generieren und packt Ihn so in die Hauptdatei wie ich es oben im Codebeispiel gezeigt habe.

Danach kommen wir dann schon in die Hauptfunktion eines richtigen C-Programms. Jedes C-Programm egal ob auf PC, oder auf AVR oder Raspberry hat so eine int main() - Hauptfunktion. Nur unsere Arduino-Softwarebibliothek im Einsteigerkurs macht aus der main() eine setup() und eine loop().  Ihr könnt ja im Programmcode lesen wie die Ersetzung dafür wäre.

Denkbar ist auch:


Zitat:void setup() {
   // Hier kommen wieder alles Einstellungen rein
}

void loop() {
  // Hier unser Hauptprogramm was unendlich oft wiederholt wird
}

int main()
{
  setup();

  while(1)
   {
      loop();
    }
 
  return 0;
}

Ist verständlich wie die Arduino-Softwarebibliothek drüben im anderen Thread und Kurs arbeitet und alles "Komplexere" vom Einsteiger fernhält, oder!?

Okay, schauen wir uns jetzt mal das Pinout eines 18F2550 an!


.png   pic18f2550-microcontroller-pinout-diagram.png (Größe: 34,63 KB / Downloads: 215)

Analog zum Arduino Nano sind die Pins gruppiert und haben mehrere Funktionen. Entweder sind es I/Os, manchmal sogar mit Analog-Eingang, machmal liegt auch eine Hardwareschnittstelle funktioniell an. Das Datenblatt des Controllers hilft!  Unser Wechselblinker aus Lektions 2 soll über PortB (das ist RB0 bis RB7) angeschlossen werden. Genauer eine LED an RB0, die andere zur Abwechselung an RB2. Das beide LEDs wieder einen Vorwiderstand haben, sollte klar sein (siehe Lektion 2, Einsteigerkurs).

Analog zum Arduino sind auch beim PIC die Pins in Ihrer Funktion festzulegen. Es gibt dafür ein Datenrichtungsregister mit dem Namen TRIS, für PortB genauer TRISB !  (Steht alles im Datenblatt)

   

Dieses Register ist genau ein Byte, also 8 Bit breit und entspricht somit RB0 bis RB7. Der Pin der ein Eingang sein soll, bekommt den Wert 1, der der ein Ausgang sein soll 0.   Acht dieser Ziffern, also 8 Bit hintereinander 01000101 würden dann eine Binärzahl ergeben. Diese Binärzahl kann man auch als Dezimalzahl , Okatalzahl oder Hexadezimalzahl in C/C++ angeben und in das Register schreiben. Wir wollen erstmal 8 Ausgänge haben also RB0 - 7 sind Ausgänge das macht 00000000 = 0 ! Diese Null schreiben wir mit TRISB = 0; in das Register und damit sind die Pins als Ausgänge festgelegt. Einfach oder? Kein achtmal pinMode(....) wie High-Level Arduino? Nein, beim Arduino kann man natürlich auch die Register des AVRs direkt beschreiben, aber das habe ich mit Absicht nicht in den Einstiegskurs aufgenommen.

Das restliche Programm:


Zitat:  // Hauptprogramm, Dauerschleife, entspricht loop() bei Arduino)
  while(1)
  {
    RB0 = 1;  // LED an RB0 an
    __delay_ms(1000); // 1 Second Delay
    RB0 = 0;  // LED an RB0 aus
    RB2 = 1;  // LED an RB2 an
    __delay_ms(1000); // 1 Second Delay
    RB2 = 0;  // LED an RB2 aus
  }

Ich glaube das muss ich nicht erklären oder? Hier habe ich extra jeden Pin per Namen (RB0 und RB2) angesprochen. Man könnte das Portregister natürlich ähnlich wie das TRISB-Register mit einem Rutsch in einem Byte wegschreiben (oder einlesen).

So nachdem das C-Programm für den PIC18F2550 klar ist, bauchen wir nur nochmal das Projekt speichern und dann oben auf Bauen (Make) und Device programmieren gehen. Das Pickit und der PIC in der Minimalschaltung + 2xLEDs und Vorwiderstände sind natürlich am Rechner angeschlossen!

Die IDE meldet in der Consolenausgabe:

Memory Summary:

    Program space        used    4Ah (    74) of  8000h bytes   (  0.2%)
    Data space           used     2h (     2) of   800h bytes   (  0.1%)
    Configuration bits   used     7h (     7) of     7h words   (100.0%)
    EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
    ID Location space    used     8h (     8) of     8h bytes   (100.0%)
    Data stack space     used     0h (     0) of   7A0h bytes   (  0.0%)

BUILD SUCCESSFUL (total time: 1s)


Loading completed

Connecting to programmer...
Programming target...
Programming completed
Running target...

Target voltage detected

Target device PIC18F2550 found.
Device Revision ID = 2

Device Erased...

Programming...

The following memory area(s) will be programmed:
program memory: start address = 0x0, end address = 0x7fff
configuration memory
Programming/Verify complete


Und unser Wechselblinker aus Lektion 2 auf dem Steckbrett fängt an zu arbeiten!
Mit wenig Modifikation kann nun auch die Ampel, Ampel samt Taster und auch die Zusatzaufgabe mit den 7-Segmentanzeigen aus Lektion 3 auf einem PIC umgesetzt werden. Auch alle anderen Lektionen aus dem Einstiegskurs können so auf einen PIC übertragen werden. Hier allerdings gleich von Anfang an mit direkten Registerzugriffen und nicht wie bei uns drüben im anderen Thread mit richtig lesbaren Befehlen wo man praktisch das Datenblatt gar nicht braucht!

War doch gut so das wir mit dem Arduino-System im Einsteigerkurs arbeiten?!  Aber glaubt mir, spätesten im Fortgeschrittenkurs geht das mit den Registern auch beim AVR in Fleisch und Blut über und PIC oder AVR, Arduino oder direkt Registerzugriff in C, das macht keinen Unterschied mehr aus.

Also PIC-Leute die Ihr mich angeschrieben habt, hängt Euch mit den PICs jetzt gleich noch in Lektion 2 und 3 an den Einsteigerkurs mit ran.
Ich beantworte Fragen und Probleme aus beiden Welten im FAQ.

Gruß Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
#2
Hallo,

eben kam die Frage warum ein Pickit3, nach dem Compilieren und beim Versuch das Programm zu brennen, kein Zielsystem (Target device) findet.

Nun das liegt wohl daran das der Prozessor aktuell keine Versorgungsspannung vom PicKit oder aus der Schaltung erhält!

Entweder ist das Pickit3 schon defekt, weil damit ein Prozessor in einer Schaltung programmiert wurde, die mehr als 50-60 mA zieht oder Vdd des Pickit3 kam mal gegen Masse! Ist das der Fall, dann dürfte das Programmiergerät ein Reparaturfall sein!
Leider sind die Versorgungsleitungen der Programmiergeräte nicht abgesichert!

Es kann aber auch sein (hoffentlich), das die Betriebsspannung absichtlich vom Pickit abgeschaltet ist, zum Beispiel weil ein PIC in einer Schaltung unter Spannung programmiert wurde und der Programmierer hoffentlich daran gedacht hat den Pickit umzustellen.
Versucht man mit so einem Pickit dann ohne externe Versorgungsspannung zu programmieren, erhält man zwangsläufig folgende Meldung:

   

Wie schaltet man die Versorgungsspannungspin des Pickit an?

Das geht über den Eintrag "Datei" und "Projekteigenschaften".

   

Danach wählt man den Pickit als Programmiergerät aus. In den Option categories wählt man "Power". Jetzt kann man die Versorgungsspannung in mehreren Stufen angeben. Achtung: 3.3V Pics sollten auch keine 5V abbekommen! Nicht den Haken bei
"Power target circuit from Pickite3" vergessen.

Anschließend das Programm nochmal compilieren und übertragen. Es sollte jetzt klappen.

Gruß Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren


Gehe zu: