Peter Hofbauer’s private Homepage
Selbstbauprojekte eigene Entwicklungen
H o m e Seite 1 Seite 2 Seite 3 Seite 4 Impressum Letzte Änderung: 08.Juli 2013 Copyright: frei! Impressum Letzte Änderung: 28. September 2018 Copyright: frei! Hier ist meine kleine Homepage, mit kleinen Projekten und kleinen diversen Berichten zum Thema  Elektronik-Hobby. .

Die 16bit-Prozessoren von Microchip PIC24/dsPIC..

Bisher habe ich meine Projekte mit den ATMEGA-Prozessoren gemacht. Die sind mir aber für einige geplante Projekte zu langsam. Darum suche ich jetzt:

Ersatz für die ATMEGA’s

Vorweg: Prozessoren programmiere ich nur in Assembler! Also brauche ich eine Prozessorfamilie mit Entwicklungswerkzeuge die noch Assembler-freundlich sind. Die Programmiersprache C kann ich zwar, ist mir aber bei meinen Hardware-Entwicklungen zu weit weg. Eigentlich wollte ich vom ATMEGA zum STM32 wechseln. Weil der ATMEGA mir zu langsam und auch langweilig wurde. Habe ein STM32-Board besorgt und getestet ob es mit Assembler noch machbar ist. Also eine LED zum Blinken habe ich zwar in Assembler hin bekommen. Beim genauen studieren der Dokus musste ich einsehen: ohne C ist es sinnlos! Die Dokus für den STM32 sind nur für C ausgelegt. Dann habe ich die ganze Software für den STM32 vom PC geschmissen und das Board verschenkt. Nach intensiver Suche bin ich bei den 16-bitter PIC24/dsPIC gelandet. Der Befehlssatz ist sehr Assembler-freundlich und auch deutlich besser als beim ATMEGA. Und sehr gut dokumentiert. Mit den internen Oszillator benötigen fast alle Befehle nur einen 34ns-Takt. Vor allem der Befehlssatz macht den Prozessor schnell. Mal 2 Beispiele: Für die Bedienung einer Sprungtabelle benötigt der ATMEGA 14 Befehle, beim dsPIC nur einen. Für die Addition von BCD-Zahlen hatte der 8051 den Befehl daa. Beim ATMEGA war dazu ein Unterprogramn mit 100 Befehle nötig. Beim dsPIC ist der Befehl wieder vorhanden. Aus der Sicht eines Anfängers beschrieben ist für diese 16-Bitter nötig: Als IDE verwende ich die alte MPLAB IDE 8.91 Version. Die neuere MPLABX ist mir zu C-lastig und für Assembler schlecht  geeignet. Zum Debuggen / Programmieren verwende ich den PICkit3 oder PICkit3.5. Kosten im www etwa 10 Euro. Funktionieren beide! Ein dsPIC mit DIL-Gehäuse und ein Steckbrett damit man etwas experimentieren kann. Buch in deutsch: “Handbuch PIC24/dsPIC-Mikrocontroller” und für MatheFans “Softwareentwicklund für dsPIC33F-Mikrocontroller” Die komplette Befehlsliste aus z.B. DS70139F (S.136-142) ausdrucken und in Klarsichthüllen stecken, sollte man immer bereit haben.

Einfache Inbetriebnahme der IDE mit einen dsPIC30F2011

Dieser Prozessor ist noch mit 5V zu betreiben und hat ein DIL18-Gehäuse. Man kann ihn also auf ein Steckbrett in Betrieb nehmen. Für diesen Test reicht die neben stehende Schaltung. Nachdem der Aufbau fertig ist, kann man mit der IDE starten. Wie schon erwähnt verwende ich die alte MPLAB V8.91. Zuerst muss ein Projekt eingerichtet werden. Dazu Projekt > Projekt Wizzard... aufrufen. Mit 4 Schritte wird ein Projekt erstellt: 1. Prozessor auswählen: dsPIC30F2011 2. Programmier-Sprache auswählen, unverändert übernehmen 3. Projektverzeichnis \ Projektdatei: für diesen Test “dsPICTest\dsPICTest1” 4. Dateien auswählen: unverändert übernehmen Dieses Projektfenster erscheint, noch ohne Dateien Dann wie hier gezeigt die Dateien eintragen. Dazu mit Rechtsklick auf Source Files, die Datei “dsPICTest1.s” eintragen. Die muss man entweder vom Download holen oder ins leere Dateifenster eintippen. Die Dateien “p30F2011.inc” und “p30F2011.gld” sind auf dem PC unter z.B. “..\Programme(X86)\Microchip\MPLAP ASM30 Suite\Support\PIC30F\inc” und “..\gld” zu finden. Diese Dateien liefert Mikrochip für jeden Prozessor. Wird bei der Installation der IDE in die oben angegeben Verzeichnisse geladen.  “p30F2011.gld” ist eine Linkerdatei. Man braucht sich um den Linker nicht weiter kümmern, mit dieser Datei geht es von selber. Dann mal in “Configure>Select Device” nach schauen ob der richtige Device dsPIC30F2011 eingetragen ist. Dieser Sourcecode enthält nur die mindestens nötigen Zeilen. In Zeile 5, 8 und 11 wird der Prozessor configuriert. Im Prinzip das selbe was man beim ATMEGA mit den Fuses macht. config ist ein Assembler-Macro, das z.B. den Wert FRC_PLL16 ins Register __FOSC setzt. Hier wird der Interne Takt mit einer PLL mit 16 multipliziert und dann durch 4 geteilt. Das ergibt eine Zykluszeit von etwa 34ns. config ist in *.inc definiert und erklärt. Die Registeradressen stehen in der Linkerdatei *.gld. Die Werte stehen in *.inc. benötigt der Linker leitet den Codebereich ein den Stack benötigen wir eigentlich nicht, aber der Debugger hier wird der Port B als Ausgang gesetzt. Eine sehr kurze Programmschleife, damit wird der Pin alle 100ns gekippt ( 3 Befehlszyklen). Zur Inbetriebnahme den Debugger PICkit an PC/USB und den Prozessor/X3 anschließen. Im Output-Fenster ist wenn alles OK ist z.B. diese Meldung sichtbar. Der PICkit wird automatisch erkannt. Den Modus auf Debug einstellen damit der Prozessor zusätzlich mit Debuggerinfos geladen wird. Dann übersetzen und in den Prozessor laden. Dann sollte obiges Bild erscheinen und es kann durchs Programm geklickt werden. Wenn man das Programm startet (mit den blauen Pfeil) ist am Pin 2 des dsPIC mit einen Oszilloskop ein Rechtecksignal zu sehen. Alle 100ns wird die Spannung gekippt, also mit einer Frequenz von 5MHz. Die Verbindung Sourcecode > IDE MPLAB > Debugger PICkit > Prozessor dsPIC30F2011 ist damit erfolgreich hergestellt. Der Rest um ein Programm zu erstellen sollte jetzt ohne größere Probleme machbar sein. In der Regel besteht ein Programm aus mehreren Sourcedateien. Die kann man einfach zusätzlich im Projektfenster (Rechtsklick auf Source Files) eintragen, der Linker macht den Rest. Die 16bit-PICs haben einen sehr praktischen Befehlssatz. Es macht Spaß damit in Assembler zu programmieren. Die Zykluszeit von 34ns ist heute kein Spitzenwert mehr, aber vor allem der Befehlssatz macht den dsPIC erst so richtig schnell. Im Vergleich zum ATMEGA.   Die IDE MPLAB (ohne X) hat eigentlich alles was man braucht. Die neuere Version hat einen besseren Editor, aber alles andere braucht man nicht. Leider ist die neue IDE MPLAB-X für C-Programmierer ausgelegt. Wer Lust hat kann ja mal versuchen, damit Assembler Programme zu machen. Ich habs aufgegeben und MPLAB-X vom PC geschmisssen. Ich verwende zum editieren für alle Programmiersprachen den selben Editor: PSPad. Den kann man sich für jeden Prozessor und jeder Programmiersprache einrichten. Nur beim Debuggen verwende ich den Editor in der IDE. Man kann auch parallel beide verwenden, die vertragen sich. Die Highlighter-Datei für die sdPIC + PSPad habe ich im Download angehängt. MPLAB V8.91 befindet sich bei Microchip im Archiv. Unterschiede zum ATMEGA: Wenn man die Schaltung ohne Debugger in Betrieb nehmen will, muss man von Debug auf Release umschalten und nochmal übersetzen und in den Prozessor laden. Mit den PICkit, den man danach entfernen darf. Die Datenrichtung in der Befehlszeile geht beim ATMEGA von rechts nach links, beim dsPIC umgekehrt. Man benötigt einige Zeit um sich daran zu gewöhnen. Beim Subbtraktionsbefehl wird das Carry-bit als invertiert ausgefasst. Downloads Sourcedatei und Highlighter-Datei (3kB) MPLAB-X  Assembler-code erkennt der Compiler XC16 automatisch an der Erweiterung “.s”. Man kann  MPLAB-X also auch als IDE mit Assembler verwenden.    
für Assembler - Programmierer

Programm Aufbau, Prinzip

für Assembler - Programmierer
Für Assembler Programme gelten nach meiner Ansicht ganz andere Regeln wie für eine Hochsprache. Hier will ich mal beschreiben welche Regeln sich bei meiner Programmier Art bewährt haben. Der Aufbau ist wie im Bild zu sehen immer gleich, abgesehen von ganz kleinen Programmen. Nach dem Reset kommt erstmal die Initialisierung. Dieser Teil wird nur einmal nach einem Reset aktiv. Darauf folgt die Hauptschleife. Hier werden Programme in einer Endlosschleife hintereinander gesetzt. In dieser Hauptschleife gelten die folgenden Regeln. Die Steuerung und der Datentransfer erfolgt ausschließlich über den RAM, keine direkte Variablen Übergabe. Der RAM bildet einen Datenbus auf dem alle Programme ohne Beschränkung Zugriff haben. Damit das funktioniert wird der RAM in einer einzigen Datei (ram.inc) definiert und als global deklariert. Es ist wichtig, alle Daten, Formate und deren Zweck genau zu beschreiben. Als Kommentar in der “ram.inc” mache ich das nicht. Zu viel Kommentare machen einen Code sehr schnell unübersichtlich. Ich habe schon Listings gesehen wo man vor lauter Kommentare den Code nicht mehr findet. Das mache ich in einen extra Text-Dokument. Damit hat man auch bessere Möglichkeiten und genug Platz. Dieses RAM- Dokument erstelle ich bevor auch nur eine einzige Zeile Code geschrieben wird. Zusätzlich wird hier der Datenfluss zwischen den Programmen und die Rechengänge beschrieben. Beim Programmieren, der Fehlersuche oder bei späteren Erweiterungen ist dieses Dokument das wichtigste Hilfsmittel. Man sollte das bis zum Schluss aktuell halten. Die Programme in der Hauptschleife sollten folgende Regeln einhalten: müssen sich separat testen lassen. nur für eine einzige komplette Aufgabe zuständig die in einen kurzen Text beschreibbar ist Ablauf mit Hilfe einer Sprungtabelle in einzelne kurze Schritte, nach dem Motto: “fasse Dich kurz” Warteschleifen sind verboten. es darf keine Rolle spielen, wo es in der Hauptschleife sitzt nur an einer einzigen Stelle in der Hauptschleife darf auf einen CPU-Port zugegriffen werden, mal abgesehen von begründeten Ausnahmen. Einige Beispiel über den Aufbau der Programme in der Hauptschleife. Zeiten: In vielen Anwendungen sind Wartezeiten nötig. Zum Beispiel reagieren Relais, Displays oder Mechanik viel zu langsam für den sehr viel schnelleren Mikrokontroller. Warteschleifen sollte man aber auf keinen Fall einsetzen. Nur zur Erinnerung: eine Millisekunde sind eine Millionen Nanosekunden! Dazu verwende ich ein Programm in der Hauptschleife, das ich traditionell “Timer” nenne. In den ersten Zeilen wird ermittelt, ob inzwischen eine Zeit von z.B. 100us abgelaufen ist. Das mache ich entweder durch Abfrage eines CPU-Timers im Polling oder mit Hilfe eines Bits, das per Interrupt getaktet wird. Ablauf: siehe Diagramm links. Bei meinen letzten Projekt (Erodiermaschine V2) hatte ich 12 unabhängige Zeiten auf diese Art realisiert. Das Diagramm rechts zeigt wie ein Programm diese Zeitzähler abfragt. Unter dem Sprungziel 1 wird z.B.ein Relais geschaltet und ein Zeitzähler im RAM auf 10ms (also auf 100 wegen der 100us im Timer) gesetzt. Dann folgt ein Return. Unter dem Sprungziel 2 geht es erst dann weiter wenn dieser Zeitzähler auf 0 steht. CPU-Port schalten / abfragen: Die einzelnen Programme in der Hauptschleife greifen nie direkt auf ein Port zu. Immer nur über den RAM. Ein Relais wird geschaltet indem ein Bit im RAM gesetzt/gelöscht wird. Die Abfrage eines Eingangspegels geht ebenfalls über den RAM. Nur ein einziges Programm in der Hauptschleife  darf das. Dies nenne ich traditionell InOut. Darin werden die richtigen Pins ausgegeben, die Eingänge entprellt und im RAM ausgegeben. Ebenso die analogen Eingänge. Die werden nach Bedarf umgerechnet usw und im RAM ausgegeben. Diese Verfahren ist von Vorteil wenn Pins getauscht werden müssen wegen z.B. Layout-Änderungen. Außerdem ist es übersichtlicher, verhindert Überschneidungen und informiert die übrigen Programme über den aktuellen Zustand an den Pins.  Es gibt aber Ausnahmen. Anzeigen Um Texte, Ziffern usw auf ein LCD zu bringen, verwende ich zwei Programme in der Hauptschleife. Die nenne ich traditionell “Monitor” und “LCDout”. Monitor arbeitet unabhängig, die anderen Programme brauchen sich um die Anzeige ihrer Daten und Texte nicht zu kümmern. Mit Hilfe der einzelnen Schrittzählern der Programme erkennt Monitor was wo angezeigt werden muss. Die Daten stehen immer bereit im RAM. Dazu ist es wichtig, das der RAM vollständig dokumentiert wurde. Monitor übergibt einen (meist kurzen) ASCII-Text mit Steuerzeichen in einen Puffer und startet LCDout. LCDout sendet dann immer nur ein einziges Byte (oder Nible wenn 4-bit Modus) ans LCD. Ein Zeitzähler im Kopf von LCDout verzögert diese Ausgabe weil die LCDs langsamer arbeiten. Wenn LCDout das Endezeichen erkennt wird sein Schrittzähler auf 0 gesetzt worauf Monitor den folgenden Puffer aufbereitet. Dieses Verfahren mag auf den ersten Blick umständlich erscheinen. Hat aber entscheidende Vorteile. Die Ausgabe ans LCD kann beliebig langsam erfolgen ohne das die CPU aus gebremst werden muss. Weil nur Monitor für die komplette Anzeige zuständig ist, wird immer alles richtig angezeigt was angezeigt werden muss. Überschneidungen wie z.B. gegenseitiges überschreiben wird vermieden. Das wichtigste Element: Sprungtabellen Als Beispiel zeige ich hier den Anfang von “Monitor”. In den ersten Zeilen wird entschieden, ob dieses Programm aktiviert werden soll/kann. Dann wird zu einen Label gesprungen auf welches ein Schrittzeiger zeigt. Hier im Beispiel sind lcdsta ein Schrittzeiger für LCDout und monsta für Monitor. Die Unterteilung der Programme über einzelne Schritte macht Echtzeit  möglich. Der Ablauf eines Programms ist einfach zu verfolgen. Jeder Schritt macht nur eine möglichst kurze Aktion, die durch Überschriften über jeden Schritt im Listing erklärt wird. Pro Durchlauf wird nur ein Schritt ausgeführt. Dabei ist es egal ob es immer der gleiche ist, oder der Reihe nach oder auf irgend einen anderen Schritt gesetzt wird. Der Boss Ein Programm in der Hauptschleife muss den Boss machen. Um die Anzeige braucht es sich nicht kümmern, das macht Monitor selber. Es muss aber den kompletten Ablauf steuern, also entscheiden wer was machen soll usw. Solch ein Programm wird sehr schnell umfangreich und unübersichtlich. Eine grafische Darstellung mit Flussdiagramm macht es übersichtlicher. Mir ist es egal ob das gut aussieht oder streng nach Norm ist, Hauptsache es erfüllt seinen Zweck. Mit welcher Software? Nach umfangreichen Recherchen bin ich bei SmartDraw gelandet. Meine Version V6 gab es sogar in deutsch. Damit kann man einigermaßen schnell arbeiten ohne überflüssige klickerei. Die Schritte in meinen Programmen sind durchnummeriert ab 0. Innerhalb eines Schrittes setze ich a, b, c... dran. Diese Nummerierungen sollten alle auch im Flussdiagramm auftauchen. Damit eine verfolgbare Verbindung zum Soucecode bleibt. Fürs Flussdiagramm sollte man sich genug Zeit lassen und bis in die Details ausarbeiten. Danach geht das Schreiben des Sourcecodes wie von selbst. Hier ein kurzes Beispiel Trotz allem ist meine aufwändige Dokumentation von einen anderen Programmierer immer noch schwer durchschaubar. Ist mich selber ist diese Dokumentation wichtig. (wird später fortgesetzt)
Home Seiten Anfang Seite 3 Seite 3