Programmierkurs für PIC-Mikrocontroller in C (CC5X
Compiler)
Teil 3 Fehlersuche
Sehr oft, besonders wenn man hat erst angefangen
zu programmieren, schleichen Fehlern in Programm ein. Und bei einem Mikrocontroller
ist schwierig sie zu suchen . Weil es gibt wenig Möglichkeiten zu erfahren,
was geht da wirklich ab. Einer der Möglichkeiten ist Assemblerprogramm im
MPLAB zu kompilieren und anschließend zu simulieren. Auf diese weise lassen
sich Variableninhalte, Schleifen, und Programmablauf beobachten. Auf diese Weise lassen sich logische Fehlern
finden. Sobald Signale von außen in Spiel sind und Signale sind zeitbezogen,
wird simulieren auf PC unmöglich.
Trotzdem gibt es kleine Tricks, welche helfen raus zu kriegen an welche Stelle
bricht sich Programm ab.
Breakpoint läst sich mit einem Taster realisieren.
Programm lauft bis einer Stelle und bleibt da stehen bis Taster betätigt wird.
Während Programm in Schleife lauft, kann
man Spannungspegeln an Pins mit dem Voltmeter messen oder mit Digitaltester anschauen.
Dann wird Taster betätigt und Programm läuft
zum nächsten Breackpoint.
Andere Möglichkeit ist, an einem Pin ein Piezowandler
anzuschließen und Piepstöne ausgeben. In folgendem Programm sind 6 Piepstöne eingebaut. Durch
Zählen der Piepstöne finden wir die
Stelle oder wenigstens Abschnitt mit dem Fehler.
// Taktfrequenz 4MHz
#include <C:\cc5\16F84.h> // Prozessor-Typ definieren
#pragma config |= 0b.1111.1111.0010 // Konfigurations-Wort
bit beep @ PORTB.0; // Port definieren an dem Piezowandler ist angeschlossen
bit Taster @ PORTB.1; //
Port definieren an dem Taster ist angeschlossen
#include <PipTast.c> // Hier befinden sich Unterprogramme pip()
und tast()
void main(void)
{
TRISB = 0b.1111.1110; // Pin
6 –Ausgang (Piezowandler), alle andere Eingänge
pip(); // Nachdem Einschalten 2 mal piepsen
pip(); // und so mit Betriebsbereitschaft
signalisieren
tast(); // Hier warten bis Knopf betätigt und losgelassen
wird
pip(); // Danach ein mal Piepsen
tast(); // Wieder warten bis Knopf betätigt und losgelassen
wird
pip();
pip(); // 3 mal Piepsen
pip();
}
Wenn wir Programm ausprobieren, dann wissen
wir genau, an welcher Stelle in Quellcode es sich befindet.
Wenn ein Speicherosziloskop zu Hand ist, kann
man Ausgabe des Mikrocontrollers auf Bildschirm beobachten. Das ist praktisch
einzige Möglichkeit Programm-Ablauf-Dauer
zu messen. Aber meistens kann man es durch Nachzählen von Assemblerbefehls
ausrechnen.
Alle Befehle brauchen Zeit f/4 , außer Sprungbefehlen
RETURN, RETLW, RETFILE, GOTO, CALL, die brauchen f/8. Befehle DECFSZ, INCFSZ, BTFSC, BTFSS in normal
Fall f/4, wenn nachfolgende Befehl übersprungen wird, dann f/8.
| Mit einem Logiktester lässt sich Pin - Zustand anzeigen. Grün - 0, Rot - 1, Beide - Pin ist hochohmig , gar keiner - keine Spannungsversorgung. Ein Piezowandler macht hörbar schmale Impulse, welche an LED nicht sichtbar sind. | ![]() |
Eine große Hilfe leistet ein einfacher Adapter
zu seriellr Schnittstelle des Rechners und Unterprogramm zur seriellen
Kommunikation. Damit kann man Variablen auslesen , Werte ins Programm übertragen.
Eine Terminalprogramm am Rechner sendet und empfängt Zeichen von PIC. Ich verwende ttermpro.exe oder ein
selbstgemachtes Programm (wobei eigene ist bequemer,
weil die empfangene Zeichen auch als Zahlen dardestellt werden ). Beispiel
der Verwendung serielles Unterprogramms: PIC sendet und empfängt Daten mit 9600 Baud, kein Paritätsbit ,8 Bit,1 Stop-Bit.
Wenn ein Zeichen von PC erwartet wird, bleibt Programm stehen, bis Zeichen
empfangen ist.
// 4 MHz
#include <C:\cc5\16F84.H>
#pragma
bit Opin @ PORTA.0 // Ausgang für
serielle Daten definieren
#pragma
bit Ipin @ PORTA.1 // Eingang für
serielle Daten definieren
#include
<Seriel4.c>
// Beinhaltet Treiber
zu serieller Kommunikation
void
main(void)
{
TRISA = 0b.1111.1110;
// Nicht vergessen,
Ein/Ausgänge einstellen
TRISB =
0b.0000.0000;
anfang:
PORTB = empfang(); // Zeichen
empfangen und ins Register PORTB übertragen
senden(PORTB); // Wert des
PORTB seriell senden
goto anfang;
}
Funktion „empfang()“ übergibt eine 8-Bit-Zahl (0..255). Funktion „senden(7)“
braucht ein Parameter , Zahl die gesendet wird. Zum Beispiel senden(170); senden(‚K’);. Funktion SerString("Ein1");
sendet ganzes Wort oder Satz. Hier ist
Foto des Testaufbaus.
Zum Schaltung: Sie wundern sich wahrscheinlich, dass TTL – IC an seriellem
Port des Rechners einfach so angeschlossen ist. Es funktioniert aber. Nach
Tabellenbuch „1“ist -3V...-15V und
„0“ ist +3V...+15V. Durch Experimente habe ich festgestellt, dass 0V als „1“
erkannt werden und mehrer als +3V als „0“ erkannt. Und dies alles mit einem
Nullmodemkabel mit 2m Länge funktioniert ziemlich sicher. Ausgangspannung
der seriellen Schnittstelle (-12V...+12V) wird mit einer Zehnerdiode auf
–0,7V...+5,1V stabilisiert.
Programmentwicklung
Am Anfang gibt es eine Idee. Funktion des Gerätes ausdenken. Hardware
ausdenken, Anbindungen an andere ICs. Versuchsaufbau. Einzelne Programmchen
entwickeln, die Hardware ansprechen. Einzelne Hardwareteile per Programmchen
testen. Diese einzelne Testprogramme in Unterprogramme umbauen und universeller
machen( Treibern bilden ). Hauptprogramm machen in dem man Zusammenspiel einzelner
Hardwareteilen bestimmt.
(Ich plane sogenannte Treibern, die ich benutze, auf dieser Homepage auszulegen
)
Wenn Ihnen gelungen ist das etwas funktioniert, dann speichern Sie das
Programm. Wenn Sie weiter am Programm arbeiten
und es geht nichts mehr, dann haben Sie Möglichkeit zurück an dem Punkt zu
gehen, wo es noch funktioniert hat. Man kann dann auch alte Version mit neuen
vergleichen um Raszufinden wie neue Code funktionierendes Programm beeinflusst
.
Mögliche Fehlern
Ein C-Programm ist erfolgreich kompiliert und
in PIC gebrannt . Mikrocontroller macht nichts.
Spannungsversorgung prüfen.
Mit Osziloskop prüfen, ob Quarz schwingt. Wenn
nicht, Einstellung des Konfigurationswortes prüfen.
Wenn Quarz schwingt, Spannungspegel an MCLR - Pin prüfen, er soll 5V sein. (sonst Dauerreset)
Ermitteln Schaltzustände an Pins: High, Low
oder hochohmig. Mit Port-Einstellung in Programm vergleichen. TRISx-Befehl.
Nachschauen, welchem Programmteil entsprechen
diese Port–Zustände.
Mikrocontroller macht etwas.
In Programmcode suchen. Wen alles logisch und richtig scheint zu sein,
und PIC trotz dem Unsinn macht, und Sie wissen nicht weiter, dann gehen Sie
schlafen. Am nächsten, Tag am besten morgen, durchdenken Sie das Programm.(Wirksamste
Methode bei mir ).
Fallen: Speicherbank vergessen umzuschalten,
Speicherbank zurückschalten, Ein/Ausgänge falsch konfiguriert. Interrupt ausersehen
aktiviert, benutzen gleicher Variable in geschachtelten Schleifen, Unterprogramm
ruft Unterprogramm geschachtelt mehr als 8 mal.