Microsoft Word - Gen.. - von Gunthard Kraus
Microsoft Word - Gen.. - von Gunthard Kraus
Microsoft Word - Gen.. - von Gunthard Kraus
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Microcontroller-Projekt:<br />
Sinus-Rechteck-<strong>Gen</strong>erator mit Drucktastensteuerung und LCD-Display-Anzeige<br />
Autor: <strong>Gunthard</strong> <strong>Kraus</strong> OSTR, Elektronikschule Tettnang<br />
1. Aufgabenstellung und Entwicklungsschritte<br />
Mit diesem Projekt sollen nacheinander folgende Lernziele erreicht werden:<br />
a) Prinzip der Erzeugung <strong>von</strong> Analogsignalen mit dem Mikrocontroller verstehen<br />
b) Wertetabellen zur Ausgabe unterschiedlicher Kurvenformen erstellen und benutzen können<br />
c) Drucktastensteuerungen unter Verwendung <strong>von</strong> Flags (= „Merkern“) programmieren können<br />
d) Menüführung über LCD-Display programmieren können<br />
e) Den Code-Umfang durch Einsatz <strong>von</strong> Funktionen mit Parameter-Übergabe reduzieren können.<br />
Dabei wird die D-A-Wandler-Platine über ein Flachbandkabel an Port P1 angeschlossen und mit dem Oszilloskop<br />
das erzeugte Analogsignal an ihrem Analogausgang beobachtet.<br />
Folgende Entwicklungsschritte sind dabei vorgesehen:<br />
Step 1:<br />
Step 2:<br />
Step 3:<br />
Step 4:<br />
Step 5:<br />
Erzeugung einer Sinusspannung mit f = 50 Hz<br />
Erweiterung der Sinuserzeugung um 2 Drucktasten (AUS / EIN)<br />
Zusätzlicher Einbau eines Displays (Anzeigen: „<strong>Gen</strong>erator AUS“ bzw. „Sinus f = 50Hz“)<br />
Umschaltmöglichkeit zwischen drei Sinus-Signalen ( 50 Hz / 100 Hz / 200 Hz) mit<br />
entsprechender Displayanzeige und Vereinfachung des Programmcodes durch Funktionen mit<br />
Parameter-Übergabe<br />
Steuerung über 7 Drucktasten: Sinus 50 Hz / 100 Hz / 200 Hz<br />
Rechteck 50 Hz / 100 Hz / 200 Hz<br />
mit Display-Anzeige<br />
--------------------------------------------------------------------------------------------------------------------------<br />
Step 1: Erzeugung einer Sinusspannung mit der Frequenz f = 50 Hz<br />
Dazu wird eine Periode einer Sinusspannung durch eine Folge <strong>von</strong> 72 Werten dargestellt ( das ergibt 5 Grad –<br />
Schritte). Diese Sinustabelle wird in das EPROM des Controllers eingebrannt und schrittweise ausgelesen. Über<br />
unterschiedliche Wartezeiten nach jedem Ausleseschritt kann die Frequenz verändert werden.
Zur Erstellung der Wertetabelle ist folgende Überlegung nötig:<br />
Dieser Spannungsverlauf entspricht der Summe aus einer Gleichspannung und einer sinusförmigen<br />
Wechselspannung. Also kann man schreiben:<br />
Wert = 127 + 127*sinus(α) = 127 *[1+ sinus(α)]<br />
Die Tabelle berechnet man entweder mit dem Taschenrechner nach der rechten Formel (mit 5 Grad-Schritten<br />
beim Winkel) oder man erledigt die Sache mit Excel. Kommastellen werden nicht benötigt -- Bitte also auf- oder<br />
abrunden.<br />
Zur Kontrolle:<br />
Winkel in Grad | 0 | 5 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80<br />
-------------------------------------------------------------------------------------------------------------------------------------------------------<br />
Wert | 127 | 138 | 149 | 160 | 170 | 181 | 191 | 200 | 209 | 217 | 224 | 231 | 237 | 242 | 246 | 250 | 252<br />
Winkel in Grad | 85 | 90 | 95 | 100 | 105 | 110| 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165<br />
-------------------------------------------------------------------------------------------------------------------------------------------------------<br />
Wert | 254 | 254 | 254 | 252 | 250 | 246 | 242 | 237 | 231 | 224 | 217 | 209 | 200 | 191 | 181 | 170 | 160<br />
Winkel in Grad | 170 | 175 | 180 | 185 | 190 | 195 | 200 | 205 | 210 | 215 | 220 | 225 | 230 | 235 | 240 | 245 | 250<br />
-------------------------------------------------------------------------------------------------------------------------------------------------------<br />
Wert | 149 | 138 | 127 | 116 | 105 | 95 | 84 | 73 | 64 | 54 | 45 | 37 | 30 | 23 | 17 | 12 | 7<br />
Winkel in Grad | 255 | 260 | 265 | 270 | 275 | 280 | 285 | 290 | 295 | 300 | 305 | 310 | 315 | 320 | 325 | 330 | 335<br />
-------------------------------------------------------------------------------------------------------------------------------------------------------<br />
Wert | 4 | 2 | 0 | 0 | 0 | 2 | 4 | 7 | 12 | 17 | 23 | 30 | 37 | 45 | 54 | 64 | 73<br />
Winkel in Grad | 340 | 345 | 350 | 355 |<br />
---------------------------------------------------------<br />
Wert | 84 | 95 | 105 | 116 |<br />
Diese Tabelle wird nun als Array in das EPROM des Controllers gebrannt und Schritt für Schritt ausgelesen.<br />
Nach jedem Auslesen eines Schrittes wird die für eine Frequenz <strong>von</strong> f = 50 Hz erforderliche Wartezeit aufgerufen.<br />
Sie beträgt<br />
T Warte = ( 20 Millisekunden ) / 72 = 278 Mikrosekunden.<br />
Sind alle Werte ausgelesen, dann beginnt der Vorgang neu.<br />
Achtung: Die Wartezeit ist nur geschätzt. Bitte mit dem Oszilloskop oder dem<br />
Frequenzzähler das Signal nachprüfen und ggf. den Wert korrigieren!<br />
Musterlösung: Siehe nächstes Blatt
Musterlösung:<br />
Erzeugung einer 50 Hz – Sinusschwingung (Ausgabe des Datenbytes an Port 1)<br />
//Sinus_01.c<br />
//Erstellt am 10.02.2006 durch G. <strong>Kraus</strong><br />
#include<br />
#include<br />
sfr ausgang=0x90;<br />
void warten(void);<br />
// Port P1 wird der Digital-Ausgang<br />
// Prototyp<br />
code unsigned char Sinus[72]=<br />
{ 127,138,149,160,170,181,191,200,209,217,224,231,237,242,246,250,252,<br />
253,254,253,252,250,246,242,237,231,224,217,209,200,191,181,170,160,<br />
149,138,127,116,105,95,84,73,64,54,45,37,30,23,17,12,7,<br />
4,2,1,0,1,2,4,7,12,17,23,30,37,45,54,64,73,84,95,105,116<br />
};<br />
void main(void)<br />
{ while(1)<br />
{<br />
unsigned char x;<br />
for(x=0;x
Step 2: Erweiterung der Sinuserzeugung um 2 Drucktasten (AUS / EIN)<br />
Dazu wird das Programm um eine „Tasten-Abfragefunktion“ erweitert. Sie wird in der Ruhestellung des<br />
<strong>Gen</strong>erators dauernd, bei der Sinuserzeugung dagegen nach jeder vollen erzeugten Sinusschwingung aufgerufen,<br />
fragt die beiden Drucktasten ab und speichert das Abfrage-Ergebnis in zwei „Merkern“ (= Bits = Flags).<br />
Die gewählte Betriebsart ( = AUS oder SINUS 50 Hz) wird dann solange ausgeführt, wie das entsprechende Flag<br />
gesetzt ist.<br />
// Sinus_02.c, erstellt am 10.02.2006 durch G. <strong>Kraus</strong><br />
#include<br />
#include<br />
sfr ausgang=0x90;<br />
sbit Taste_AUS=P4^0;<br />
sbit Taste_Sin50Hz=P4^1;<br />
bit AUS;<br />
bit Sin50Hz;<br />
void warten(void);<br />
void Tastenabfrage(void);<br />
// Port P1 wird der Digital-Ausgang<br />
// Tastendeklaration<br />
// Merker-Deklaration<br />
// Prototyp<br />
code unsigned char Sinus[72]=<br />
{ 127,138,149,160,170,181,191,200,209,217,224,231,237,242,246,250,252,<br />
253,254,253,252,250,246,242,237,231,224,217,209,200,191,181,170,160,<br />
149,138,127,116,105,95,84,73,64,54,45,37,30,23,17,12,7,<br />
4,2,1,0,1,2,4,7,12,17,23,30,37,45,54,64,73,84,95,105,116<br />
};<br />
void main(void)<br />
{ unsigned char x; // Adressierung des Arrayplatzes<br />
AUS=1;<br />
// <strong>Gen</strong>erator ausschalten<br />
while(1)<br />
{<br />
while(AUS==1)<br />
// <strong>Gen</strong>erator ausgeschaltet<br />
{ Tastenabfrage();<br />
}<br />
}<br />
}<br />
while(Sin50Hz==1)<br />
// Sinus 50 Hz wird erzeugt<br />
{ for(x=0;x
Step 3: Zusätzlicher Einbau eines Displays (Anzeigen: „<strong>Gen</strong>erator AUS“ bzw.<br />
„Sinus f = 50Hz“) unter Beibehaltung der Drucktastensteuerung<br />
Hierfür ist die zusätzliche Einbindung der Datei „LCD_CTRL_new.c“ in das Projekt erforderlich, da diese alle für<br />
den korrekten Betrieb des Displays nötigen Steuerfunktionen enthält (Listing dieser Datei: Siehe Anhang).<br />
Außerdem werden alle Prototypen der dort entwickelten Anzeigefunktionen übernommen.<br />
Zusätzlich müssen noch zwei Texte als Arrays im EPROM des Controllerboards angelegt werden, nämlich die<br />
Anzeigen für „<strong>Gen</strong>erator AUS“ und „Sinus f = 50 Hz“.<br />
Bitte beachten: bei den LCD-Displays sind normalerweise 4 Zeilen zu je 20 Zeichen vorgesehen. Wird der Text<br />
pro Zeile zu lang gewählt, dann gilt folgende „Überlauf-Regel“:<br />
Nach Zeile 1 kommt Zeile 3 und nach Zeile 2 geht es in Zeile 4 weiter!<br />
Man sollte es sich auch zum Prinzip machen, „unveränderliche“ Texte IMMER im EPROM des Controllerboards<br />
anzulegen, um kostbaren RAM-Speicherplatz zu sparen. Außerdem muss man bei solchen Character-Texten<br />
immer etwas aufpassen und mitzählen:<br />
21 Arrayplätze müssen vorgesehen werden, aber beim auszugebenden Text dürfen nur 20 Zeichen<br />
zwischen den Anführungszeichen im Array stehen!<br />
(Grund: an solche Zeichenketten-Arrays wird immer automatisch vom C-Compiler das zusätzliche Zeichen „0x00“<br />
angehängt. Es markiert das Ende des Arrays und die Display-Anzeigefunktion „show_text(….);“ sucht immer nach<br />
diesem Zeichen um herauszufinden, wo der Text endet!).<br />
Das Beschreiben der Anzeige mit dem gewünschten Text erfolgt in der Tastenabfrage. Wird eine gedrückte Taste<br />
erkannt, dann wird der zugehörige Merker erkannt UND der passende Text auf dem Display ausgegeben.<br />
Achtung: Die Wartezeit ist nur geschätzt. Bitte mit dem Oszilloskop oder dem<br />
Frequenzzähler das Signal nachprüfen und ggf. den Wert korrigieren!<br />
// Sinus_03.c<br />
// Erstellt am 10.02.2006 durch G. <strong>Kraus</strong><br />
#include<br />
#include<br />
sfr ausgang=0x90;<br />
sbit Taste_AUS=P4^0;<br />
sbit Taste_Sin50Hz=P4^1;<br />
bit AUS;<br />
bit Sin50Hz;<br />
void warten(void);<br />
void Tastenabfrage(void);<br />
// Port P1 wird der Digital-Ausgang<br />
// Tastendeklaration<br />
// Merker-Deklaration<br />
// Prototypen<br />
void zeit_s(void);<br />
void zeit_l(void);<br />
void lcd_com(void);<br />
void lcd_ein(void);<br />
void lcd_ini1(void);<br />
void switch_z1(void);<br />
void switch_z2(void);<br />
void switch_z3(void);<br />
void switch_z4(void);<br />
void show_text(char *ptr);<br />
void show_char(char *zeichen);
code unsigned char Sinus[72]=<br />
{ 127,138,149,160,170,181,191,200,209,217,224,231,237,242,246,250,252,<br />
253,254,253,252,250,246,242,237,231,224,217,209,200,191,181,170,160,<br />
149,138,127,116,105,95,84,73,64,54,45,37,30,23,17,12,7,<br />
4,2,1,0,1,2,4,7,12,17,23,30,37,45,54,64,73,84,95,105,116<br />
};<br />
code unsigned char Text_Aus[21]={"<strong>Gen</strong>erator AUS "};<br />
code unsigned char Text_Sinus_50Hz[21]={"Sinus f = 50 Hz "};<br />
void main(void)<br />
{ unsigned char x; // Adressierung des Arrayplatzes<br />
lcd_ein();<br />
lcd_ini1();<br />
switch_z1();<br />
show_text(Text_Aus);<br />
AUS=1;<br />
// <strong>Gen</strong>erator ausschalten<br />
while(1)<br />
{<br />
while(AUS==1)<br />
{ Tastenabfrage();<br />
}<br />
// <strong>Gen</strong>erator ausgeschaltet<br />
}<br />
}<br />
while(Sin50Hz==1)<br />
// Sinus 50 Hz wird erzeugt<br />
{ for(x=0;x
Step 4: Umschaltmöglichkeit zwischen drei Sinus-Signalen ( 50 Hz / 100 Hz /<br />
200 Hz) mit Displayanzeige und Vereinfachung des Programmcodes durch<br />
Funktionen mit Parameter-Übergabe<br />
Sobald mehrfach dieselbe Funktion mit unterschiedlichen Werten ausgeführt werden soll (hier: Erzeugung <strong>von</strong><br />
Sinuskurven mit unterschiedlichen Frequenzen), schreibt man nur eine „Grundfunktion“. Ihr übergibt man die<br />
Informationen über den gerade gewünschten Wert als Parameter. So spart man Programmcode und Rechenzeit.<br />
Lösung:<br />
z. B. für die Sinus-Erzeugung schreibt man im Hauptprogramm<br />
Sinusper(82); // das ergibt eine Schwingung mit f = 50 Hz<br />
----------------------------------------------------------------------------<br />
Dazu ist folgende Prototypen-Anmeldung nötig:<br />
void Sinusper(unsigned char Wert);<br />
----------------------------------------------------------------------------<br />
Die Funktion selbst sieht so aus:<br />
void Sinusper(unsigned char Wert)<br />
{ unsigned char x,y;<br />
for(x=0;x
void switch_z2(void);<br />
void switch_z3(void);<br />
void switch_z4(void);<br />
void show_text(char *ptr);<br />
void show_char(char *zeichen);<br />
code unsigned char Sinus[72]=<br />
{ 127,138,149,160,170,181,191,200,209,217,224,231,237,242,246,250,252,<br />
253,254,253,252,250,246,242,237,231,224,217,209,200,191,181,170,160,<br />
149,138,127,116,105,95,84,73,64,54,45,37,30,23,17,12,7,<br />
4,2,1,0,1,2,4,7,12,17,23,30,37,45,54,64,73,84,95,105,116<br />
};<br />
code unsigned char Text_Aus[21]={"<strong>Gen</strong>erator AUS "};<br />
code unsigned char Text_Sinus_50Hz[21]={"Sinus f = 50 Hz "};<br />
code unsigned char Text_Sinus_100Hz[21]={"Sinus f = 100 Hz "};<br />
code unsigned char Text_Sinus_200Hz[21]={"Sinus f = 200 Hz "};<br />
void main(void)<br />
{ lcd_ein();<br />
lcd_ini1();<br />
switch_z1();<br />
show_text(Text_Aus);<br />
AUS=1;<br />
while(1)<br />
{<br />
while(AUS==1)<br />
{ Tastenabfrage();<br />
}<br />
while(Sin50Hz==1)<br />
{ Sinusper(82);<br />
Tastenabfrage();<br />
}<br />
while(Sin100Hz==1)<br />
{ Sinusper(36);<br />
Tastenabfrage();<br />
}<br />
while(Sin200Hz==1)<br />
{ Sinusper(13);<br />
Tastenabfrage();<br />
}<br />
// <strong>Gen</strong>erator ausschalten<br />
// <strong>Gen</strong>erator ausgeschaltet<br />
// Sinus 50 Hz wird erzeugt<br />
// Sinus 100 Hz wird erzeugt<br />
// Sinus 200 Hz wird erzeugt<br />
}<br />
}<br />
void Sinusper(unsigned char Wert)<br />
// Wartezeit<br />
{ unsigned char x,y;<br />
for(x=0;x
if(Taste_Sin50Hz==0) // Taste Sinus-50Hz gedrückt?<br />
{ AUS=0;<br />
Sin50Hz=1;<br />
Sin100Hz=0;<br />
Sin200Hz=0;<br />
switch_z1();<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
show_text(Text_Sinus_50Hz); // Text anzeigen<br />
}<br />
if(Taste_Sin100Hz==0)<br />
{ AUS=0;<br />
Sin50Hz=0;<br />
Sin100Hz=1;<br />
Sin200Hz=0;<br />
switch_z1();<br />
show_text(Text_Sinus_100Hz);<br />
}<br />
if(Taste_Sin200Hz==0)<br />
{ AUS=0;<br />
Sin50Hz=0;<br />
Sin100Hz=0;<br />
Sin200Hz=1;<br />
switch_z1();<br />
show_text(Text_Sinus_200Hz);<br />
}<br />
// Taste Sinus-100Hz gedrückt?<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
// Text anzeigen<br />
// Taste Sinus-200Hz gedrückt?<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
// Text anzeigen<br />
}<br />
Bitte beim Zusammenstellen des Projektes die „Startup.A51 – Datei“ sowie die „LCD_CTRL_new.c“ – Datei nicht<br />
vergessen!
Step 5:<br />
Steuerung mit Display-Anzeige über 7 Drucktasten:<br />
Sinus<br />
Rechteck<br />
AUS<br />
50 Hz / 100 Hz / 200 Hz<br />
50 Hz / 100 Hz / 200 Hz<br />
Für die Rechteck-Erzeugung muss (da wir ja ein komplettes Byte <strong>von</strong> Port 1 an den D-A-Wandler übergeben)<br />
folgendes Programm geschrieben werden:<br />
Man gibt an Port P1 abwechselnd für die halbe Periodendauer den Wert Null (= 0x00) bzw. 255 (= 0xFF)<br />
aus.<br />
Da jedoch bei f = 50 Hz bereits eine Wartezeit <strong>von</strong> 10 Millisekunden erforderlich ist, muss man den Zahlentyp<br />
beim Übergabeparameter auf „ unsigned int“ ändern (und kann damit Verzögerungszeiten bis 65 Millisekunden<br />
erzielen).<br />
Zu schreibende Funktion:<br />
void Rechteckper (unsigned int Wert)<br />
{ unsigned int y;<br />
}<br />
ausgang=0x00;<br />
for(y=0;y
void Rechteckper(int Wert);<br />
void Sinusper(char Wert);<br />
void Tastenabfrage(void);<br />
void zeit_s(void);<br />
void zeit_l(void);<br />
void lcd_com(void);<br />
void lcd_ein(void);<br />
void lcd_ini1(void);<br />
void switch_z1(void);<br />
void switch_z2(void);<br />
void switch_z3(void);<br />
void switch_z4(void);<br />
void show_text(char *ptr);<br />
void show_char(char *zeichen);<br />
code unsigned char Sinus[72]=<br />
{ 127,138,149,160,170,181,191,200,209,217,224,231,237,242,246,250,252,<br />
253,254,253,252,250,246,242,237,231,224,217,209,200,191,181,170,160,<br />
149,138,127,116,105,95,84,73,64,54,45,37,30,23,17,12,7,<br />
4,2,1,0,1,2,4,7,12,17,23,30,37,45,54,64,73,84,95,105,116<br />
};<br />
code unsigned char Text_Aus[21]={"<strong>Gen</strong>erator AUS "};<br />
code unsigned char Text_Sinus_50Hz[21]={"Sinus f = 50 Hz "};<br />
code unsigned char Text_Sinus_100Hz[21]={"Sinus f = 100 Hz "};<br />
code unsigned char Text_Sinus_200Hz[21]={"Sinus f = 200 Hz "};<br />
code unsigned char Text_Rechteck_50Hz[21]={"Rechteck f = 50 Hz "};<br />
code unsigned char Text_Rechteck_100Hz[21]={"Rechteck f = 100 Hz "};<br />
code unsigned char Text_Rechteck_200Hz[21]={"Rechteck f = 200 Hz "};<br />
void main(void)<br />
{ lcd_ein();<br />
lcd_ini1();<br />
switch_z1();<br />
show_text(Text_Aus);<br />
AUS=1;<br />
while(1)<br />
{<br />
while(AUS==1)<br />
{ Tastenabfrage();<br />
}<br />
while(Sin50Hz==1)<br />
{ Sinusper(82);<br />
Tastenabfrage();<br />
}<br />
while(Sin100Hz==1)<br />
{ Sinusper(36);<br />
Tastenabfrage();<br />
}<br />
while(Sin200Hz==1)<br />
{ Sinusper(13);<br />
Tastenabfrage();<br />
}<br />
while(Rechteck50Hz==1)<br />
{ Rechteckper(750);<br />
Tastenabfrage();<br />
}<br />
while(Rechteck100Hz==1)<br />
{ Rechteckper(375);<br />
Tastenabfrage();<br />
// <strong>Gen</strong>erator ausschalten<br />
// <strong>Gen</strong>erator ausgeschaltet<br />
// Sinus 50 Hz wird erzeugt<br />
// Sinus 100 Hz wird erzeugt<br />
// Sinus 200 Hz wird erzeugt<br />
// Rechteck 50 Hz wird erzeugt<br />
// Rechteck 50 Hz wird erzeugt
}<br />
while(Rechteck200Hz==1)<br />
{ Rechteckper(185);<br />
Tastenabfrage();<br />
}<br />
// Rechteck 50 Hz wird erzeugt<br />
}<br />
}<br />
void Sinusper(unsigned char Wert)<br />
{ unsigned char x,y;<br />
for(x=0;x
}<br />
Rechteck50Hz=0;<br />
Rechteck100Hz=0;<br />
Rechteck200Hz=0;<br />
switch_z1();<br />
show_text(Text_Sinus_200Hz);<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
// Text anzeigen<br />
}<br />
if(Taste_Rechteck_50Hz==0)<br />
{ AUS=0;<br />
Sin50Hz=0;<br />
Sin100Hz=0;<br />
Sin200Hz=0;<br />
Rechteck50Hz=1;<br />
Rechteck100Hz=0;<br />
Rechteck200Hz=0;<br />
switch_z1();<br />
show_text(Text_Rechteck_50Hz);<br />
}<br />
if(Taste_Rechteck_100Hz==0)<br />
{ AUS=0;<br />
Sin50Hz=0;<br />
Sin100Hz=0;<br />
Sin200Hz=0;<br />
Rechteck50Hz=0;<br />
Rechteck100Hz=1;<br />
Rechteck200Hz=0;<br />
switch_z1();<br />
show_text(Text_Rechteck_100Hz);<br />
}<br />
if(Taste_Rechteck_200Hz==0)<br />
{ AUS=0;<br />
Sin50Hz=0;<br />
Sin100Hz=0;<br />
Sin200Hz=0;<br />
Rechteck50Hz=0;<br />
Rechteck100Hz=0;<br />
Rechteck200Hz=1;<br />
switch_z1();<br />
show_text(Text_Rechteck_200Hz);<br />
}<br />
// Rechteck 50Hz-Taste gedrückt?<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
// Text anzeigen<br />
// Rechteck 100Hz-Taste gedrückt?<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
// Text anzeigen<br />
// Rechteck 200Hz-Taste gedrückt?<br />
// Auf den Anfang <strong>von</strong> Zeile 1 schalten<br />
// Text anzeigen
Anhang: Listing des LCD-Steuerprogramms „LCD_CTRL_new.c“<br />
/*----------------------------------------------------------------<br />
LCD_CTRL_new.c<br />
C-Programm-Modul zur Ausgabe <strong>von</strong> Texten auf dem LCD-Display<br />
12.02.2006 / G. <strong>Kraus</strong><br />
-----------------------------------------------------------------*/<br />
#include <br />
#include <br />
void zeit_s(void);<br />
void zeit_l(void);<br />
void lcd_com(void);<br />
void lcd_ein(void);<br />
void lcd_ini1(void);<br />
void switch_z1(void);<br />
void switch_z2(void);<br />
void switch_z3(void);<br />
void switch_z4(void);<br />
void show_text(char *ptr);<br />
void show_char(char *zeichen);<br />
sfr ausg_lcd=0xF8;<br />
sbit enable=ausg_lcd^4;<br />
sbit RW_LCD=ausg_lcd^5;<br />
sbit RS_LCD=ausg_lcd^6;<br />
// Port 5 als Display-Ausgang<br />
// Portpin P5.4 ist "enable"<br />
// Portpin P5.5 ist "READ - WRITE"<br />
// Portpin P5.6 ist "Register - Select"<br />
/*-----------------------------------------------------------------------<br />
Zusatzfunktionen<br />
-------------------------------------------------------------------------*/<br />
void zeit_s(void)<br />
{<br />
unsigned char x;<br />
for(x=0;x
lcd_com();<br />
ausg_lcd=0x08;<br />
lcd_com();<br />
ausg_lcd=0x00;<br />
lcd_com();<br />
ausg_lcd=0x08;<br />
lcd_com();<br />
ausg_lcd=0x00;<br />
lcd_com();<br />
ausg_lcd=0x01;<br />
lcd_com();<br />
zeit_l();<br />
ausg_lcd=0x00;<br />
lcd_com();<br />
ausg_lcd=0x06;<br />
lcd_com();<br />
ausg_lcd=0x00;<br />
lcd_com();<br />
ausg_lcd=0x0c;<br />
// losschicken<br />
// Unteres Nibble für "4 Bit / 2 Zeilen / 5x7 dots"<br />
// losschicken<br />
// Oberes Nibble <strong>von</strong> "Display OFF"<br />
// losschicken<br />
// Unteres Nibble <strong>von</strong> "Display OFF"<br />
// losschicken<br />
// Oberes Nibble <strong>von</strong> "Clear all"<br />
// losschicken<br />
// Unteres Nibble <strong>von</strong> "Clear all"<br />
// losschicken<br />
// Beim Löschen ist hier eine lange Wartezeit nötig<br />
/* Oberes Nibble <strong>von</strong> "Entry mode" (Cursor steht, Display<br />
wandert nach rechts */<br />
// losschicken<br />
/* Unteres Nibble <strong>von</strong> "Entry mode" (Cursor steht, Display wandert<br />
nach rechts */<br />
// losschicken<br />
// Oberes Nibble <strong>von</strong> "Display ON, Cursor OFF, Kein Blinken"<br />
// losschicken<br />
// Unteres Nibble <strong>von</strong> "Display ON, Cursor OFF, Kein Blinken"<br />
}<br />
lcd_com();<br />
// losschicken<br />
void lcd_com(void)<br />
{ unsigned char x;<br />
enable=1;<br />
for(x=0;x
void switch_z3(void)<br />
// Schalte auf Zeile 3 um und stelle den Cursor an den Anfang der Zeile<br />
{ ausg_lcd=0x09; // Erforderliches Codewort hat als oberes Nibble "1001B" = 0x09<br />
lcd_com();<br />
// losschicken<br />
ausg_lcd=0x04; // Erforderliches Codewort hat als unteres Nibble "0100B = 0x04<br />
lcd_com();<br />
// losschicken<br />
}<br />
void switch_z4(void)<br />
// Schalte auf Zeile 4 um und stelle den Cursor an den Anfang der Zeile<br />
{ ausg_lcd=0x0D; // Erforderliches Codewort hat als oberes Nibble "1101B" = 0x0D<br />
lcd_com();<br />
// losschicken<br />
ausg_lcd=0x04; // Erforderliches Codewort hat als oberes Nibble "0100" = 0x04<br />
lcd_com();<br />
// losschicken<br />
}<br />
void show_text(char *ptr)<br />
{<br />
while(*ptr)<br />
{<br />
ausg_lcd=(*ptr/0x10)|0x40;<br />
// Anzeige eines Textes, als Array vorgegeben<br />
/* Startadresse des Arrays wird übergeben. Schleife wird solange<br />
wiederholt, bis Code "0x00" (entspricht dem Zeichen "\0") gefunden<br />
wird. */<br />
/* Oberes Nibble des Zeichen-Bytes wird um 4 Stellen<br />
nach rechts geschoben und anschließend um die<br />
erforderlichen Steuersignale ergänzt. */<br />
lcd_com(); // Oberes Nibble losschicken<br />
ausg_lcd=(*ptr&0x0f)|0x40;<br />
/* Unteres Nibble des Zeichen-Bytes wird durch<br />
Löschen des oberen Nibbles gewonnen und<br />
anschließend um die erforderlichen Steuersignale<br />
ergänzt. */<br />
lcd_com(); // Unteres Nibble losschicken<br />
}<br />
}<br />
ptr++;<br />
// Nächstes Zeichen des Arrays adressieren<br />
void show_char(char *ptr)<br />
{<br />
ausg_lcd=(*ptr/0x10)|0x40;<br />
lcd_com();<br />
ausg_lcd=(*ptr&0x0f)|0x40;<br />
// Anzeige eines einzigen ASCII-Zeichens. Adresse wird übergeben.<br />
/* Oberes Nibble des Zeichen-Bytes wird um 4 Stellen nach<br />
rechts geschoben und anschließend um die erforderlichen<br />
Steuersignale (für Datenübertragung) ergänzt. */<br />
// Oberes Nibble losschicken<br />
/* Unteres Nibble des Zeichen-Bytes wird durch Löschen des<br />
oberen Nibbles gewonnen und anschließend um die<br />
erforderlichen Steuersignale (für Datenübertragung) ergänzt. */<br />
}<br />
lcd_com();<br />
// Unteres Nibble losschicken