Ansteuerung
von LCD-Modul, Textausgabe, Zahlenausgabe
Programmierkurs für PIC-Mikrocontroller in C (CC5X Compiler)
Teil 6
Bei programmieren eines
Mikrocontrollers ist es seltsam das es kein Print- Befehl gibt. Wen man mit
einer neuer Programmiersprache anfängt lernt man als erstes Ausgabebefehle
und Eingabebefehle. Mikrokontroller hat keine Ein/Ausgabegeräte. Deswegen
wollen wir ein anschlissen. In frage kommen dabei: Pesowandler, LEDs, Siebensegment-Anzeigen,
LCD. Aber als Preisgünstigste und dabei mit fielen Einsatzmöglichkeiten haben
sich Alphanumerische LCD Displays erwiesen. Ich benutze LCD
162F (LED LCD-MODUL 16X2 M.BEL. für 18.65 Euro bei Reichelt).Wen es um
messen geht, kann man Zahlen mit viel stellen und Messeinheiten anzeigen.
Auch Menüs und kurze Mitteilungen lassen sich bequem mit LCD-Anzeige ausgeben.
Diese LCD- Modul hat einen HD44780 Controller,
der ist in letzte Zeit Standard Controller für LCD-Displays geworden. LCD-Modul
hat 8 Datenleitungen, und 3 Steuerleitungen CS, RS, R/W. LCD-Module können
im 4Bit-Modus arbeiten, dabei werden 4 Datenleitungen, CS(Clock),RS(Befehl/Zeichen)
benutzt. Bei einem Mikrocontrollerport sind dann noch 2 Pins für andere Zwecke
verwendbar.
Im WWW gibt es einige Programme zum Ansteuerung von LCD-Module im Assembler
und C. Eine davon hat Holger Klabunde geschrieben. Sein Quellcode musste ich
an einigen stellen verändern, um es auf dem PIC16F84 (4MHz) und PIC16F871(20MHz)
laufen zu lassen. Außerdem musste bei Initialisierung des LCD ein zusätzlicher
Byte rein, sonst ging nicht. Und es ist jetzt möglich beliebige 8Bit-Port
des Mikrocontrollers zum Kommunikation mit LCD einzustellen.
Anschlussplan zum Programm. Foto des Versuchsaufbau.
Hier ist Beispielprogramm für PIC16F84.
|
// Ansteuerung von LCD-Anzeige
4MHz //
Testprogramm //
Michael Dworkin //
02.06.2003 //
Compiler CC5x #include
<C:\cc5\16F84.H> #pragma config |=
0b.1111.1111.0010 // Konfigurations-Wort #define LCD_RS 0b.00000001 //RS-Pin ist Bit0, LCD
Register Select #define LCD_CS 0b.00001000 //E-Pin ist Bit3, LCD
Chip Select #pragma char PORTQ @ PORTB //PORT auswählen,
DB7-Bit7, DB6-Bit6, DB5-Bit5, DB4-Bit4 #include "delay4.c" #include "lcd.c" void main(void) // Hauptprogramm { PORTB=0x00; TRISB=0b00000000; //Alles Ausgänge lcdport=0; Delay1ms(1000); // 1s warten LCDInit(); // LSD Initialisieren anfang: LCDCls(); // Bildschirm löschen LCDPos(1,0); // Position der ersten Zeichen 1 Zeile, Position 0 LCDString("Programmierer"); //
String Anzeigen LCDPos(2,0); // Position der ersten Zeichen 2 Zeile, Position 0 LCDString("Michael Dworkin"); // String
Anzeigen Delay1ms(2000); // Warte 2s zeit zum lesen. LCDCls(); LCDPos(1,0); LCDString("Mischa_D@mail.ru"); LCDPos(2,2); LCDString("CC5X.DE.VU"); Delay1ms(2000); LCDCls(); // Umlaute Testen LCDPos(2,3); // Zeile 2, Position 3 LCDString("ÜüÄäÖöß"); Delay1ms(2000); goto anfang ; } |
Am Anfang des Programms wird 1sekunde abgewartet, das ist eigentlich nicht nötig. Wenn man unterschiedliche Texte ausgibt, darf man nicht vergessen vorher zu löschen, sonst werden Texte überlappen. Man kann löschen ganze Bildschirm oder nur Bereich wo neue Text erscheinen soll. Kann sein dass bei erstem Einschalten LCD-Bildschirm nichts zeigt, versuchen Sie Helligkeit mit dem Potentiometer einzustellen.
LCD-Ansteuerung
mit PIC16F871 bei Quarzfrequenz 20MHz
Hauptprogramm bleibt die gleiche. Anstatt des PortB wird, zu Kommunikation
mit LCD, PortD benutzt. Treiber für LCD bleibt der gleiche "lcd.c". Nur
Unterprogramm für Zeiterzögerung "delay4.c" muss man für 20MHz benutzen
"delay20.c". Hier ist Anschlussplan.
Hier eine Foto meiner Testplatine für PIC16F871.
// Ansteuerung von LCD-Anzeige // Testprogramm // Michael Dworkin // 02.06.2003 // Compiler CC5x #include <C:\cc5\16F871.H> //
Speihersutz121345=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an,NiendervoltProgr7=aus // NiederVoltReset6=an,EinschaltTimer3=an,WachDogTimer2=aus,Oszilator01=HC #pragma config |= 0b.11.111101.11.00.10 #define LCD_RS 0b.00000001 //RS-Pin
ist Bit0, LCD Register Select #define LCD_CS 0b.00001000 //E-Pin
ist Bit3, LCD Chip Select #pragma char PORTQ @
PORTD //PORT auswählen, DB7-Bit7, DB6-Bit6, DB5-Bit5, DB4-Bit4, #include "delay20.c" #include "lcd.c" void main(void) // Hauptprogramm { TRISD=0b00000000; //Alles Ausgänge PORTD=0x00; lcdport=0; LCDInit(); anfang: LCDCls(); LCDPos(1,0); LCDString("Programmierer"); LCDPos(2,0); LCDString("Michael
Dworkin"); Delay1ms(2000); LCDCls(); LCDPos(1,0); LCDString("Mischa_D@mail.ru"); LCDPos(2,2); LCDString("CC5X.DE.VU"); Delay1ms(2000); LCDCls(); LCDPos(2,3); LCDString("ÜüÄäÖöß"); Delay1ms(2000); goto anfang ; } |
|
Wie kann ich Inhalt einer Variable als Zahl auf LCD darstellen?
Ich habe
Unterprogramm geschrieben die Inhalt einer Integer-Variable auf dem LCD-Bildschirm
darstellt .
Es wird 5-stellige Zahl ausgegeben. Die Nullen vorne sind durch Leerzeichen
ersetzt.
Zum Beispiel: Zahl 587 wird so angezeigt "__587" , Zahl 3 - "____3",
Zahl 12345 - "12345"
Wenn Sie genau wissen Stellenanzahl Ihrer ausgegebener Zahl, dann können Sie
Anzahl auszugebenen Stellen einstellen in dem Sie Variable "Dez"
mit kleinerem Wert laden. Bei 2 Stellen Dez=10 (Zahlen bis 99), Bei 3 Stellen
Dez=100 (Zahlen bis 999), und so weiter.
Wenn Nullen links(nicht besetzte stellen vor der Zahl) erwünscht sind dann
ersetzen Sie k=0 gegen k=1.
// Ansteuerung von LCD-Anzeige
// Testprogramm für Zahlenausgabe
// Michael Dworkin
// 26.03.2004
// Compiler CC5x
#include <d:\cc5\16F871.H>
#pragma config |= 0b.11.111101.11.00.10
#pragma origin 100 // Ab Adresse 100 im Programmspeicher
#define LCD_RS 0b.00000001 // RS-Pin ist Bit0, LCD Register Select
#define LCD_CS 0b.00001000 // E-Pin ist Bit3, LCD Chip Select
#pragma char PORTQ @ PORTD // PORT auswählen, DB7-Bit7, DB6-Bit6, DB5-Bit5, DB4-Bit4,
#include "delay20.c"
#include "lcd.c"
void LCDStringExtra(const char *__putstr,uns16 Zeit)
{
char __ps;
__ps = *__putstr;
while(__ps>0)
{
__putstr++;
if (__ps== 0) break;
LCDWriteChar(__ps);
Delay1ms(Zeit);
__ps = *__putstr;
}
}
//******* Unterprogramm zum Anzeigen von 16Bit Zahlen auf LCD *****************
void ZalString(uns16 z)
{
uns16 i,temp,Dez;
bit k; // Merker ob vorne 0 ist
k=0;
Dez=10000; // Dezimalstellen, z.B. bei 2 Stellen 10 eintragen
while (Dez) // Solange Dezimalstelle nicht 0 ist
{
if(Dez==1) k=1; // Um ein einzige 0 anzeigen können
i=z/Dez; // Wert der jeweilige Dezimalstelle bestimmen
temp=i*Dez;
z=z-temp;
if(i||k) // Damit wir vorne keine Nullen stehen haben.
{
LCDWriteChar((char)i+0x30);
k=1; // es gab schon eine Zahl die nicht 0 ist
}
else // wen 0 ist und vorne keine Zahl war, dann
{
LCDWriteChar(' '); // Leerzeichen ausgeben
}
Dez=Dez/10;
}
}
//*******************************************************
// Hauptprogramm
//*******************************************************
void main()
{
TRISD=0b00000000; // Alles Ausgänge
PORTD=0x00;
lcdport=0;
Delay1ms(1000); // 1s abwarten
LCDInit(); // LCD Initialisieren
LCDCls(); // Bildschirn löschen
LCDPos(1,0); // Position des Textes
LCDString("Test für Zahlen"); // Text ausgeben
uns16 X;
X=0;
while(1) // Endlosschleife
{
LCDPos(2,0); // Position der Zahl
ZalString(X); // Zahl ausgeben
X++; // Hier wird jede 0,5s hochgezählt
Delay1ms(500); // 0,5s abwarten
}
}
Theorie:
Wie funktioniert das ?
Wenn man etwas misst und Ergebnisse auf LCD anzeigen möchte, muss man aus
Integer - Variable 3 Zeichen bilden.
Zum Beispiel wir wollen Zahl 136 darstellen.
Dafür muss man "1", "3", "6" zum LCD senden.
Nach ASCII-Tabelle entsprechen diesen Zeichen folgende ASCII-Code: 49, 51,
54. Wenn wir diese zahlen nacheinander zum LCD senden bekommen wir 136 angezeigt.
Zuerst müssen wir ein Weg finden Zahl 136 auf Dezimalstellen zu zerlegen.
Wir nennen Variablen wie Dezimalstellen:
Hundert
Zen
Eins
Temp - als Zwischenablage
Berechnen:
Hundert = 136/100
=1
Temp = 136 - Hundert * 100 = 36
Zen = Temp/10 =3
Eins = Temp - Zen * 10 = 6
Jetzt haben
wir:
Hundert =1
Zen =3
Eins = 6
Und wie kommen wir zu ASCII-Code?
Ganz einfach: wir addieren zu unseren Variablen Zahl 48 !
Hundert = Hundert + 48
Zen = Zen + 48
Eins = Eins + 48
48+1=49
48+3=51
48+6=54
|
|
![]() |
Letzte Änderung 16.06.04
|