In den vergangenen Folgen haben wir uns um die absoluten Grundlagen der Programmiersprache „C“ gekümmert und uns an das Arbeiten mit Compiler, Linker und Emulator gewöhnt.
Programmieren lernt man aber nur durch Programmieren.
Es ist also höchste Zeit für ein kleines Projekt, um das bisher Erlernte zu üben, die Themen zu vertiefen und auch neue Dinge an einem konkreten Beispiel kennenzulernen.
Die Anwendung der Programmierung an einem konkreten Projekt macht zudem mehr Spaß.
Ich habe mir das so vorgestellt.
Als Beispielprojekt würde ich gern die Zähleinrichtung eines Kaffeeautomaten programmieren.
Der Kaffeeautomat
Der Kaffeeautomat besteht aus einem Münzeinwurf, in dem Euro- und Cent-Münzen eingeworfen werden können. Das eingeworfene Geld wird von einer Hardware erkannt und je nach dem welcher Münzwert erkannt wird ein Port-Bit gesetzt.
Wir verwenden den Port 1 und nutzen folgende Zuordnung.
![]()
Wird also ein 2 Ct-Stück eingeworfen, wird das Bit Nr. 1 (von rechts mit 0 beginnend) auf „1“ gesetzt. Der Einwurf eines 2 Euro-Stücks setzt das höchstwertige Bit, also Bit Nr. 7.
Das Geld muss gezählt werden
Unsere Programm für die Zähleinrichtung soll das eingeworfene Geld zählen.
Dies kann man machen, indem man den aktuellen Betrag in einer Variablen speichert und bei Einwurf eines weiteren Geldstücks den Betrag entsprechend erhöht.
Das Geld wird also eingeworfen. Nachdem die ENTER-Taste betätigt worden ist, soll das Geld dem Guthaben gutgeschrieben werden. Hinweis: Bitte vor dem Druck auf die ENTER-Taste in das Fenster für die serielle Schnittstelle wechseln, damit der Simulator die Eingabe interpretieren kann.
Das aktuelle Guthaben soll ausgegeben werden.
Jetzt bist Du an der Reihe
Jetzt geht es für Dich darum, die Zähleinrichtung zu programmieren. Eine mögliche Lösung werde ich in der nächsten Folge vorstellen, bevor es dann weiter um die Getränkeausgabe geht.
Dieser Artikel ist Teil des Mikrocontroller-Kurses auf ET-Tutorials.de.
[ >> Hier geht es zurück zur Übersichtsseite des Mikrocontroller-Kurses .]
Hat Dir der Artikel geholfen? - Dann hilf dem Artikel ;-)
|
Ähnliche Artikel
Folgende Artikel aus der gleichen Kategorie könnten Dich ebenfalls interessieren:Programmierung der Getränkeausgabe In der vergangenen Woche haben wir eine mögliche Lösung für eine Zähleinrichtung der Geldeingabe für...
Bitweise Manipulation Der Kaffeeautomat funktioniert ja schon im Prinzip. Aber zumindest beim Geldeinwurf gibt es noch ein...
Kaffeeautomat-Funktion für die Münzauswertung Nach einem Ausflug in das Reich der Funktionen, geht es nun zurück zur Programmierung des Kaffeeauto...
Lösung der Aufgabe und SHIFT Operator In der letzten Folge habe ich das Element Array vorgestellt. Mit einem Array kann man eine Struktur ...





{ 14 Kommentare… sie unten lesen oder einen hinzufügen }
Hallo Wolfgang,
gestattest Du eine Frage, die nicht unbedingt mit diesem Kursteil zusammenhängt?
Was man mit den Ausgängen eines Controllers tun kann, lerne ich hier im Kurs. Auch die Ausgaben auf externe Geräte oder Baugruppen kann ich mir schon ein bischen vorstellen (z. B. über Transistoren und/oder Relais). Wo mir noch ein Überblick fehlt, ist der Eingang. Als einfachste Möglichkeit stelle ich mir einen Taster mit einem Flipflop vor. Aber da gibt es sicher viele Möglichkeiten.
Kennst Du ein praxisorientiertes Werk, das sich mit Sensoren für die Eingabe von Eingangssignalen für MC befasst?
Freundliche Grüße
Willi
Hallo Willi,
Ports als Eingang werden wir im 2. Teil des Kurses, also wo es um die spezielle Programmierung des Mikrocontrollers geht, ebenfalls behandeln.
Grob gesagt hat man 2 Möglichkeiten.
Entweder man hat digitale Eingänge (Schalter, Taster, digitale ICs (z.B. TTL), die Sensoren digital auswerten, vielleicht in Flipflops zwischenspeichern, … also letztendlich digitale Signale, z.B. 0V oder 5V.
oder
Man hat analoge Spannungen. Die werden dann AD (analog-digital) gewandelt. Man macht also aus analogen Werten digitale Werte. Die AD-Wandlung werden wir uns auch im 2. Teil angucken.
Eine dritte Möglichkeit gibt es auch noch. Die Sensoren werden über ein Bus-System angeschlossen, z.B. I²C, SPI. o.ä. . Dies würde dann aber erst in einem eventuellen dritten Teil angesprochen werden.
(Ich muss mir zunächst einmal Gedanken machen, wie ich ohne Hardware den Anschluss von Bus-Systemen programmieren/simulieren kann).
Ein spezielles Buch zur Hardwareansteuerung kann ich leider nicht empfehlen.
Vielleicht hat jemand der anderen Kursteilnehmer einen Vorschlag … ??
Hallo Wolfgang,
vielen Dank für den Ausblick. Ich werde mich gedulden.
Gruß Willi
Hallo,
ich habe ein Problem.
Es wird kein Fehler angezeigt, das Programm funktioniert trotzdem nicht.
Hat jemand eine Idee? Ist mein Ansatz überhaupt richtig?
Viele Grüße
Christian Vitt
/*——————————————————————————
Der Kaffeeautomat
——————————————————————————*/
#include /* special function register declarations */
/* for the intended 8051 derivative */
#include /* prototype declarations for I/O functions */
/*————————————————
The main C function. Program execution starts
here after stack initialization.
————————————————*/
void main (void)
{
int e;
e=0; //Variable e auf 0 setzen
while (1)
{
switch (P1) //Der Wert der Variablen P1 wird abgefragt
{
case 1: //1 Cent wurde eingeworfen / 1 steht für das Bit 0
e=e+1; //addiere den Wert 1 zur Variablen e
break;
case 2: //2 Cent wurde eingeworfen / 2 steht für das Bit 1
e=e+2;
break;
case 4: //5 Cent wurde eingeworfen / 4 steht für das Bit 2
e=e+5;
break;
case 8: //10 Cent wurde eingeworfen
e=e+10;
break;
case 16: //20 Cent wurde eingeworfen
e=e+20;
break;
case 32: //50 Cent wurde eingeworfen
e=e+50;
break;
case 64: //100 Cent wurde eingeworfen
e=e+100;
break;
case 128: //200 Cent wurde eingeworfen
e=e+200;
break;
default:
printf(“Bitte Geld einwerfen\n”);
getchar();
printf(“Sie haben %d Cent eingeworfen\n”,e);
}
}
}
Hallo Vitt,
zwei Dinge fallen mir auf.
1.) Hast Du die Initialisierung der Seriellen Schnittestellen gelöscht oder hier nur nicht reinkopiert?
Ohne die Initialisierung der seriellen Schnittstelle funktioniert printf() nicht.
2.) Du musst den Port wieder auf 0 setzen, sonst wird e laufend hochgezählt.
LG
Charles
Hallo!
Ist denn gesichert, dass immer nur ein Bit auf 1gesetzt wurde? Ansonsten würde ich vorschlagen, nicht nach dem Zahlenwert zu gucken, sondern zu schauen, welche Bits tatsächlich eins sind, also ist die zahl größer 128, wenn ja, zähle ich die 200 Cent und ziehe 128 ab, und teste die nächst kleineren Werte, wenn nicht, fahre ich ohne aufsummieren fort.
Ist evtl mit der Aufgabenstellung nicht vorgesehen, aber wie schaut es denn hier mit der Synchronisation aus? kann mein Port mehrfach verändert werden, bevor meine while-schleife zurück kommt zum Auslesen?
Schöne Grüße,
Tim
Hallo Tim,
eine interessante Frage.
Um die Aufgabe einfacher zu gestalten, bin ich zunächst davonausgegangen, dass nur eine Münze eingeworfen wird.
Die Aufgabenstellung kann man aber auc dahingehend erweitern, dass auch mehrere Münzen eingeworfen sein könnten.
In einer der folgenden Artikel werden wir uns um das bitweise Auslesen und Setzen eines Bytes kümmern.
Deine Aufgabenerwweiterung könnte damit auch sehr schön gelöst werden.
Dein Lösungsweg geht sicher aus. Wenn Du Lust hast, kann Du ja eine Lösung programmieren und dann vorstellen. Entweder hier als Kommentar oder per Email. Ich drehe dann ein kleines Video dazu.
Ich habe ein Problem mit den Anweisungen. Ich habe einiges versucht aber bisher ohne Erfolg. Wieviel kostet der Kaffee? Ohne diese Info kann ich auch nur 1 Cent einwerfen und bekomme einen Kaffee. Und wann kommt das nächste Video? Bin schon gespannt darauf.
/*——————————————————————————
HELLO.C
Copyright 1995-2005 Keil Software, Inc.
——————————————————————————*/
#include /* special function register declarations */
/* for the intended 8051 derivative */
#include /* prototype declarations for I/O functions */
#ifdef MONITOR51 /* Debugging with Monitor-51 needs */
char code reserve [3] _at_ 0×23; /* space for serial interrupt if */
#endif /* Stop Exection with Serial Intr. */
/* is enabled */
/*————————————————
The main C function. Program execution starts
here after stack initialization.
————————————————*/
void main (void)
{
int Guthaben;
Guthaben=0;
P1=0;
//Variable e auf 0 setzen
/*————————————————
Setup the serial port for 1200 baud at 16MHz.
————————————————*/
#ifndef MONITOR51
SCON = 0×50; /* SCON: mode 1, 8-bit UART, enable rcvr */
TMOD |= 0×20; /* TMOD: timer 1, mode 2, 8-bit reload */
TH1 = 221; /* TH1: reload value for 1200 baud @ 16MHz */
TR1 = 1; /* TR1: timer 1 run */
TI = 1; /* TI: set TI to send first char of UART */
#endif
/*————————————————
Note that an embedded program never exits (because
there is no operating system to return to). It
must loop and execute forever.
————————————————*/
while (1)
{
if (Guthaben==0)
{
switch (P1)
{
case 1: Guthaben=Guthaben+1;
break;
case 2: Guthaben=Guthaben+2;
break;
case 4: Guthaben=Guthaben+5;
break;
case 8: Guthaben=Guthaben+10;
break;
case 16: Guthaben=Guthaben+20;
break;
case 32: Guthaben=Guthaben+50;
break;
case 64: Guthaben=Guthaben+100;
break;
case 128: Guthaben=Guthaben+200;
break;
default:
printf(“Bitte Geld einwerfen\n”);
}
P1=0;
}
else if (Guthaben != 430)
{
switch (P1)
{
case 1: Guthaben=Guthaben+1;
break;
case 2: Guthaben=Guthaben+2;
break;
case 4: Guthaben=Guthaben+5;
break;
case 8: Guthaben=Guthaben+10;
break;
case 16: Guthaben=Guthaben+20;
break;
case 32: Guthaben=Guthaben+50;
break;
case 64: Guthaben=Guthaben+100;
break;
case 128: Guthaben=Guthaben+200;
break;
default:
printf(“Bitte noch Geld einwerfen\n”);
}
P1=0;
}
else if (Guthaben==430)
{
P1=0;
printf(“Sie erhalten in kürze ihren Kaffee\n”);
Guthaben=0;
}
printf(“Sie haben %d Cent eingeworfen\n”,Guthaben);
getchar();
}
}
Ich weiss eine etwas lange Lösung, hoffe das Ihr eine bessere habt. Habe auch einen bestimmten Preis ( 4,30€) eingebaut.
Hallo,
es freut mich, dass die Aufgabenstellung so gut angenommen wird und zum Teil auch erweitert wird.
Genau das ist die richtige Vorgehensweise. Zunächst das Problem angehen und dann weiterdenken und die Fragestellung erweitern.
Die nächste Folge habe ich heute vormittag online gestellt – dort findet Ihr auch eine mögliche Lösung und die Folgeaufgabe, bei der es dann um die Abrechnung der Getränke geht.
Hallo, kann es sein das ein Fehler in der Aufgabenstellung existiert? Hab lange auf den Text gestart und ihn zuerst nicht ganz verstanden.
Dort heist es:
” Wird also ein 2 Ct-Stück eingeworfen, wird das Bit Nr. 1 (von links mit 0 beginnend) auf „1“ gesetzt. ”
Muss es nicht heißen von rechts mit 0 beginnend?
Oder habe ich einen Gedankenfehler? Denn das 1Bit sagt doch es sind 2 Cent eingeworfen. Laut der Tabelle ist 2Cent auf Bit 1 und zwar von rechts gesehen oder? :/
Hallo Markus,
Du hast recht. Scheinbar ist der Fehler bislang von allen überlesen worden. Zumindest bist Du der erste, der sich gemeldet hat. – Vielen Dank dafür !
Ich habe den Text geändert, jetzt stimmt er.
Nochmals, vielen Dank!
Hallo
Ich brauche Hilfe. Die Simulation funktioniert bei mir nicht. Die entwicklungsumgebung habe neu installiert, alle ok. Bei complieren funktioniert , aber wenn ich die Simulation aufrufe, kommt ein error meldung “can´t find file, error 56″.
Asgedom
Ist das Programm vielleicht größer als 2k geworden ?