Forum: Mikrocontroller und Digitale Elektronik sobald Taste betätigt sein wird => LED mit PWM-Funktion blinken lassen. Controller LM3S811


von Hel B. (helbi)


Angehängte Dateien:

Lesenswert?

Guten Tag,

als Anfänger bitte ich um Ihre Tipps beim Schreiben von einem Programm 
für MikroController LM3S811 (enthält Evaluationsboard) : Solange Taste 
USER (PC4) betätigt sein wird => die LED PC5 sollte mit Hilfe von 
PWM-Einsatz blinken.

Das Programm (nicht fertig, Roh-Variante) ist im Anhang.

Vom Programmanfang bis zur Stelle

//Idee wen Taste User....

wurde einfach LED5 (Port C) einfach zum leuchten gebracht. Das hat 
funktioniert.
Aber weiter wollte ich ein Programm schreiben, so dass beim Betätigen 
von der Taste USER (PC4) sollte LED PC5 blinken. Frequenz und 
Puls-weiten-Verhältnis sollte beim Programmieren eingestellt wrden.

Ab der Stelle

while (1)

habe ich ein fremden Programmuster (Original_version von Datenblatt) 
genommen, welcher ich an diese Aufgabe und dieses Programm anpassen 
will. Nur habe ich dorthin die Bediengung

if (GPIO_PORTC_DATA_R & 16) // Wenn Taste PC4 gedrückt ist

..................
..................

else
{
GPIO_PORTC_DATA_R &= ~32; //sonst LED PC5 aus
}

eingeführt.

Ich bitte Sie, zu mir nicht zu streng sein, da ich ein Einsteiger bin 
und von Programmierung manche Basis-Sachen noch kennenlernen werde.

In diesem Zusttand passiert beim betätigen von Taste PC4 nichts...

Frage 1: Periode setzen:

// Set the period. For a 50 KHz frequency, the period = 1/50,000, or 20
// microseconds. For a 20 MHz clock, this translates to 400 clock ticks.
// Use this value to set the period.

Das ist klar dass 50kHz entspricht 20 mikrosekunden.
Wie kommt man bei 20 MHz auf 400 clock ticks ?
20 MHZ entsprocht 0,05 mikrosekunden. Wie kommt man davon auf 400 clock 
tics?

Frage 2: Was bedeuten das Zeichen ~
in Zeilen

GPIO_PORTC_DIR_R &= ~16; // Port 4 weil 16=2^4

GPIO_PORTC_DATA_R &= ~32; //sonst LED PC5 aus


Frage 3:

Ist die Bediengung

if (GPIO_PORTC_DATA_R & 16) // Wenn Taste PC4 gedrückt ist

an der richtigen Stelle eingesetzt?

von W.S. (Gast)


Lesenswert?

Hel B. schrieb:
> als Anfänger bitte ich um Ihre Tipps beim Schreiben von einem Programm
> für MikroController LM3S811

Hmm.. das ist doch so ein Cortex M3 (Stellaris --> TI), gelle? Also 
vermutlich mal wieder ein Teil, das keinen eigenen Bootlader mitbringt, 
sondern allenfalls einen Einmal-Lader im User-Flash hat.

Der allererste Rat wäre, dir ein funktionables Programmier-Geschirre 
zuzulegen und damit vertraut zu werden - sofern du das nicht bereits 
hast.

Der nächste Rat ist der nach einer funktionablen Toolchain. Sollte für 
nen Cortex M3 ja wohl keine Hürde sein.

Aber was du da an Programm bzw. Idee zu einem Programm gezeigt hast, ist 
für mich ..nun ja.. eher unverständlich.

Ich gehe da deutlich formaler vor:
1. Ich habe grundsätzlich meinen eigenen Startupcode für den Controller, 
wo ich genau weiß, was der leisten soll und wie er funktioniert
2. Ich fasse alle Grund-Konfigurationen in einer separaten Quelle (z.b. 
config.c) zusammen, so daß danach die Zuordnungen der Pins zu den 
gewünschten Funktionen getroffen ist, die Systemtakte aufgesetzt sind, 
die benötigten Peripheriecores freigeschaltet und mit Takt versorgt sind 
und eventuelle externe Peripherie (z.B. externer SDRAM) initialisiert 
und benutzbar ist.
3. Die Einrichtung der Peripherie findet bei mir in dn zugehörigen 
Treibern statt - und die befinden sich in separaten Quellen.
4. Ich richte mir immer eine Systemuhr ein, zumeist mit 1 ms oder 10 ms 
Schritten (kommt auf den verwendeten Systemtakt an). Das ist gerade bei 
den Cortexen mittels deren System-Tick eine ganz leichte Angelegenheit. 
Und bedenke du mal, daß man bei allen Steuerungsaufgaben Zeiten und 
damit eine Art Systemuhr benötigt.

Ja, zu einer vernünftig aufgebauten Firmware gehört auch eine 
vernünftige Form der zugehörigen Quellen. Mach also kein 
Kraut&Rüben-Projekt draus.

Nochwas: Konstrukte wie "while(bedingung)anweisung;" dienen eigentlich 
einer bedingten Abarbeitung. Für den finalen Zweck einer unbedingten 
Schleife dient in C wie auch in vielen anderen Programmiersprachen das 
Setzen einer Marke und ein "goto marke;" Die dazu benötigten 
Ausdrucksmitten Marke und goto sind Grundbestandteil von C - und mir ist 
bislang noch kein einziger C-Programmierer begegnet, der den Mißbrauch 
von while für solchen Zweck mir hat plausibel begründen können (es gibt 
nämlich keinen plausiblen Grund dafür). Das Einzige, was man immer 
wieder hört ist "das ist mir so beigebracht worden, es so zu schreiben" 
oder "goto hat mir mein Lehrer verboten".

Schau dir dein Quellcode-Beispiel mal an, was da nach dem 
while(true).. Konstrukt kommt.

Im Grunde sieht ein sinnvolles main etwa so aus:
main(..)
{ InitPeripherie1();
  InitPeripherie2();
  ..etc.

immerzu:
  KümmereDichUmDies();
  KümmereDichUmDas();
goto immerzu;
}

W.S.

von Hel B. (helbi)


Lesenswert?

Vielen Dank für die ausführliche Antwort.
Eine Menge von Fragen kommt noch.

Nur jetzt vielleicht eine: warum der Frequenz 20 MHz entsprechen 400 
clock tics?

von Achim S. (Gast)


Lesenswert?

Hel B. schrieb:
> Nur jetzt vielleicht eine: warum der Frequenz 20 MHz entsprechen 400
> clock tics?

Das hasat du doch selbst schon längst ausgerechnet:

Hel B. schrieb:
> Das ist klar dass 50kHz entspricht 20 mikrosekunden.
> Wie kommt man bei 20 MHz auf 400 clock ticks ?
> 20 MHZ entsprocht 0,05 mikrosekunden.

Wie viele Intervalle von 0,05µs braucht man, bis man 20µs zusammen hat?

von U. C. (Gast)


Lesenswert?

W.S. schrieb:
> und mir ist
> bislang noch kein einziger C-Programmierer begegnet, der den Mißbrauch
> von while für solchen Zweck mir hat plausibel begründen können

Da machst du ja ein völlig unsinniges Fass auf.

Dass an der Stelle eine Endlosschleife sinnvoll ist, ist sicherlich 
unbezweifelbar.
Und ob du:
1. while(1)
2. for(;;)
3. Lable: goto
verwendest ist aus Logik Sicht irrelevant.
Den Programmablauf störts nicht.
Und der Compiler macht (heutzutage) sowieso das gleiche draus....

Früher war Variante 2 üblich.
Heutzutage schreibt man eher Variante 1

Variante 3 leidet unter dem schlechte Ruf des Goto. Und liefert uns 
keinen Block/Gültigkeitsbereich für lokale Variablen.

Doktrin: Jedes vermiedene Goto ist ein gutes Goto!
Und hier kann man es ohne jeden Schmerz vermeiden.
Wenn ich ein Goto an der Stelle, und zu dem Zweck, vorfinden würde, 
würde ich mir Gedanken um den Geisteszustand des Autors machen. Und im 
weiteren Code noch viel viel schlimmere Dinge erwarten.


Ich plädiere für das "Prinzip der geringsten Verwunderung".
Verwende while(1), das machen alle so, und es gibt keinen Grund davon 
abzuweichen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.