Hallo,
ich möchte mit drei Tastern eine switch case Verzweigung üben.
-Taster1 soll PA3 schalten
-Taster2 soll PB1 schalten
-Taster3 soll PA7 schalten
und später soll es dann eine FMS werden, aber dazu will ich erstmal den
grundliegenden switch case kennenlernen.
da ich aber nicht wirklich etwas bei google finde, und mit dem avr
tutorial hier im forum alleine nicht weiter komme bitte ich euch um
hilfe.
Als anfang will ich an PA3 eine LED über PA0 einschalten. doch das
bereitet mir schon riesige probleme. so wie ich das verstanden habe
arbeitet das ganze über variablen und habe folgendes probiert. da kommt
dann gleich eine riesen fehlerliste. kann mir hier bitte jemand den
richtigen einstieg zeigen?
/*
* switch_case.c
*
* Created: 11.08.2016 08:37:07
* Author: Huber
*/
#include <avr/io.h>
int main(void)
{ //Ausgänge festlegen
DDRA|= (1<<PA3)|(1<<PA7);
DDRB|= (1<<PB1);
//Eingänge festlegen pullups
PORTA|= (1<<PA0)|(1<<PA1)|(1<<PA2);
int AUF = PA0; // hier dachte ich, wenn ich jetzt PA0 drücke,
dann geht PA3 an,Wo ist mein dekfehler?
switch (AUF) {
case 1: PORTA|=(1<<PA3); // Anweisungen für diesen
Zweig,variable ==
break;
default: // Anweisungen wenn keine der oben definierten
Bedingungen erfüllt ist
break;
}
while(1)
{
//TODO:: Please write your application code
}
}
Huber M. schrieb:> int AUF = PA0; // hier dachte ich, wenn ich jetzt PA0 drücke,
Das funktioniert so nicht, denn du musst ja das PIN Register von Port A,
also PINA erstmal einlesen.
denkbar wäre bei negativer Logik (Pin wird vom Taster auf low gezogen):
1
#define PINMASK (1<<PA0)|(1<<PA1)|(1<<PA2)
2
3
uint8_tn=~PINA;// lese Pins invertiert
4
n&=PINMASK;// ausmaskieren unbenutzter Pins
5
switch(n){
6
case(1<<PA0):// Taster 0 gedrückt tue was
7
break;
8
case(1<<PA1):// Taster 1 gedrückt
9
break;
10
case(1<<PA2):// Taster 2 gedrückt
11
break;
12
case((1<<PA0)|(1<<PA1)):// zwei Taster gleichzeitig gedrückt
13
break;
14
}
zugegeben, das auslesen der Pins ist mit der Maskiererei eine Zeile
länger, aber damit vermeidet man unnötige Seiteneffekte. Man kann auch
bei negativer Logik bleiben (also die Pins nicht invertieren), aber dann
wird das switch case etwas unübersichtlicher. Es gibt viele Wege nach
Rom und das werden hier sicher auch einige noch anmerken.
ok, so ungefähr hatte ich mir das vorgestellt, nur erstmal ohne
invertieren. damit ich das ganze von grundauf richtig verstehe. Jetzt
habe ich das mal aus dem Tutorial Mehrfachabzweigung raus kopiert.Es
wären auch noch ein paar beispiele aufgeführt, aber alle in Asembler.
Und davon verstehe ich garnix.
wie bekomme ich nachfolgendes dazu, dass mir im case1 PA0 (eingang) PA3
(Ausgang) schaltet. Am besten für den anfang, wenn das mit int= möglich
ist.
switch (variable) {
case 1: // Anweisungen für diesen Zweig, wenn variable == 1
break;
case 17: // Anweisungen für diesen Zweig, wenn variable == 17
break;
case 33: // Anweisungen für diesen Zweig, wenn variable == 33
break;
case 9: // Anweisungen für diesen Zweig, wenn variable == 9
break;
case 22: // Anweisungen für diesen Zweig, wenn variable == 22
break;
default: // Anweisungen wenn keine der oben definierten
Bedingungen erfüllt ist
break;
}
[c]
switch (variable) {
case 1: // Anweisungen für diesen Zweig, wenn variable == 1
PORTA |= (1<<PA3);
break;
case 17: // Anweisungen für diesen Zweig, wenn variable == 17
break;
case 33: // Anweisungen für diesen Zweig, wenn variable == 33
break;
case 9: // Anweisungen für diesen Zweig, wenn variable == 9
break;
case 22: // Anweisungen für diesen Zweig, wenn variable == 22
break;
default: // Anweisungen wenn keine der oben definierten
Bedingungen erfüllt ist
break;
}
es tut mir wirklich leid, aber ich bringe es nicht zum laufen. Ich check
den Anfang schon nicht. Hab mir zich videos etc. angesehen gelesen. Ich
weiss was es machen soll, aber ich kanns einfach nicht umsetzen. Selbst
wenn ich den geschriebenen code von mathias sch. ein kopiere. Aber jetzt
noch mal zum letzten was mache ich den hier falsch?
/*
* switch_case_1.c
*
* Created: 11.08.2016 12:41:22
* Author: Huber
*/
#include <avr/io.h>
int main(void)
{//Ausgänge festlegen
DDRA|= (1<<PA3);
//Eingänge festlegen
PORTA|= (1<<PA1);
int n= (1<<PA1);
switch (n) {
case 1: // Anweisungen für diesen Zweig, wenn variable == 1
PORTA |= (1<<PA3);
break;
case 17: // Anweisungen für diesen Zweig, wenn variable == 17
break;
case 33: // Anweisungen für diesen Zweig, wenn variable == 33
break;
case 9: // Anweisungen für diesen Zweig, wenn variable == 9
break;
case 22: // Anweisungen für diesen Zweig, wenn variable == 22
break;
default: //
break;
}
oh, hier nochmal
/*
* switch_case_1.c
*
* Created: 11.08.2016 12:41:22
* Author: Huber
*/
#include <avr/io.h>
int main(void)
{//Ausgänge festlegen
DDRA|= (1<<PA3);
//Eingänge festlegen
PORTA|= (1<<PA1);
char n= (1<<PA1);
switch (n) {
case 1: // Anweisungen für diesen Zweig, wenn variable == 1
PORTA |= (1<<PA3);
break;
case 17: // Anweisungen für diesen Zweig, wenn variable == 17
break;
case 33: // Anweisungen für diesen Zweig, wenn variable == 33
break;
case 9: // Anweisungen für diesen Zweig, wenn variable == 9
break;
case 22: // Anweisungen für diesen Zweig, wenn variable == 22
break;
default: //
break;
}
while(1)
{
//TODO:: Please write your application code
}
}
Dein Problem ist... du ließt den Pin nicht ein, zumindest nicht so wie
du das denkst:
Huber M. schrieb:> int n= (1<<PA1);
damit schreibst du bloß in die Variable n ein 0b0000010... da wird kein
Pin abgefragt oder sonstwas.
Matthias S. schrieb:
1
#define PINMASK (1<<PA0)|(1<<PA1)|(1<<PA2)
2
3
uint8_tn=~PINA;// lese Pins invertiert
4
n&=PINMASK;// ausmaskieren unbenutzter Pins
5
switch(n){
6
case(1<<PA0):// Taster 0 gedrückt tue was
7
PORTA|=(1<<PA3);// <--- Deine Anweisung
8
break;
9
case(1<<PA1):// Taster 1 gedrückt
10
break;
11
case(1<<PA2):// Taster 2 gedrückt
12
break;
13
case((1<<PA0)|(1<<PA1)):// zwei Taster gleichzeitig
14
gedrückt
15
break;
16
}
Das ist das in welche Richtung es geht. In PINx liegen die aktuellen
Zustände der Pins und nicht in PAx.
Desweiteren hat dein gesamtes Programm einen fundamentalen Fehler. Es
läuft einmal durch und das wars. Du brauchst eine Dauerschleife.
1
/*
2
* switch_case_1.c
3
*
4
* Created: 11.08.2016 12:41:22
5
* Author: Huber
6
*/
7
8
9
#include<avr/io.h>
10
11
#define PINMASK (1<<PA0)|(1<<PA1)|(1<<PA2)
12
13
intmain(void)
14
{
15
//Als Ausgang definieren
16
DDRA|=(1<<PA3);
17
18
//DDRA wäre sowieso 0b00001000 somit PA01,1,2 auf Eingang aber um
19
//es nochmal zu zeigen wie auf Eingang gestellt wird:
20
DDRA&=~((1<<PA0)|(1<<PA1)|(1<<PA2));
21
22
//Hier wird NICHT auf Eingang gestellt, sondern der Pullup gezogen!
23
PORTA|=(1<<PA0)|(1<<PA1)|(1<<PA2);
24
25
while(1)// Die Dauerschleife!
26
{
27
uint8_tn=~PINA;// lese Pins invertiert
28
n&=PINMASK;// ausmaskieren unbenutzter Pins
29
switch(n){
30
case(1<<PA0):// Taster 0 gedrückt tue was
31
PORTA|=(1<<PA3);// <--- Deine Anweisung
32
break;
33
case(1<<PA1):// Taster 1 gedrückt
34
break;
35
case(1<<PA2):// Taster 2 gedrückt
36
break;
37
}// Ende der Dauerschleife
38
}
Das dürfte funktionieren, habs aber nicht getestet nur
runtergeschrieben.
Arbeite das
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
mal bis einschliesslich Kapitel 9 durch.
Dann kannst Du auch Deinen Switch-Case programmieren :-)
Dir fehlen schlicht alle Grundlagen - die musst Du Dir halt erst mal
erarbeiten.
Danke dir, jetzt kann ich das langsam nachvollziehen, aber es gibt nur
noch ein Problem. Beim kompilieren kommt noch ein fehler. kann aber
nicht sehen was fehlen würde oder zuviel da wäre. Ich bekomme bald nen
Nervenzusammenbruch :-).
Error 1 expected declaration or statement at end of input
C:\Dokumente und Einstellungen\Huber\Eigene Dateien\Atmel
Studio\6.2\GccApplication16\GccApplication16\GccApplication16.c 38 1
GccApplication16
@dieter.f. da hast du schon recht. Da bin ich ja dabei, aber ich wollte
das mit den case üben. Da ich eine Alternative zur if Anweisung brauche.
Und mit interrupts habe ich auch kein problem. Ich wollte schon länger
den case switch verstehen. Ich tu mich nur leichter, wenn sich was
bewegt auf meiner platine :-)
Für die Abfrage einzelner Bits ist switch/case nicht geeignet, da die
Nachbarbits mit eingehen.
Außerdem ist kein Mensch in der Lage, aus CPU-Sicht 2 Tasten
gleichzeitig zu drücken (innerhalb 50ns) oder loszulassen.
In der Regel ist eine direkte Portabfrage auch nicht sinnvoll, da Tasten
oftmals entprellt werden müssen, bevor man sie auswerten kann.
Die Entprellroutine kann dann auch ein Intervall für Gleichzeitigkeit
bereitstellen (z.B. 500ms). Oder für lang/kurz drücken.
Danke nochmal für die Mühe.Es ist rüber gespielt. Gehe ich jetzt recht
der Annahme, wenn ich an PA0 einen Taster (0,1uf entprellt) anschliesse,
diesen betättige,dann sollte PA3 einschalten? Es funktioniert nämlich
nicht. Ja ich habe die Hardware überprüft verkabelung usw. mehrmals,
wenn ich es mit ner if Anweisung mache gehts. Es muss doch nur noch ne
Kleinigkeit sein, aber welche?
Huber M. schrieb:> wenn ich es mit ner if Anweisung mache gehts.
Damit hast Du schön bewiesen, welches Werkzeug das richtige dafür ist.
Warum willst Du unbedingt das falsche nehmen?
weil ich endlich mal mit der Switch Case anweisung arbeiten will. Und
ich will das ja dann mal ausweiten, wenn ich einmal den PA3
eingeschaltet bekomme.Wie ich anfangs ja schon schrieb, will ich mich in
ferner Zukunft an eine state machine ran arbeiten.
-Aber es müsste doch jetzt eigentlich funktionieren. Kann sich keiner
vorstellen, warum das nicht geht. Habe an PA0 nen Taster dran und an PA3
eine LED, aber es tut sich nichts, ja die Led ist nicht defekt, oder die
anderen komponenten, es liegt nur an mir und diesem Code.
/*
* switch_case_1.c
*
* Created: 11.08.2016 12:41:22
* Author: Huber
*/
#include <avr/io.h>
#define PINMASK (1<<PA0)|(1<<PA1)|(1<<PA2)
int main(void)
{
//Als Ausgang definieren
DDRA |= (1<<PA3);
//DDRA wäre sowieso 0b00001000 somit PA01,1,2 auf Eingang aber um
//es nochmal zu zeigen wie auf Eingang gestellt wird:
DDRA &= ~((1<<PA0) | (1<<PA1) |(1<<PA2));
//Hier wird NICHT auf Eingang gestellt, sondern der Pullup gezogen!
PORTA|= (1<<PA0) | (1<<PA1) | (1<<PA2);
while(1) // Die Dauerschleife!
{
uint8_t n = ~PINA; // lese Pins invertiert
n &= PINMASK; // ausmaskieren unbenutzter Pins
switch (n) {
case (1 << PA0) : // Taster 0 gedrückt tue was
PORTA |= (1<<PA3); // <--- Deine Anweisung
break;
case (1 << PA1) : // Taster 1 gedrückt
break;
case (1 << PA2) : // Taster 2 gedrückt
break;
} // <---- Die Schleife hatte gefehlt.
} // Ende der Dauerschleife
}
Ich habs mal eben im Simulator getestet und es funktioniert so wie
erwartet. Allerdings wird PA3 ja nur einmal im ganzen Programm auf high
gesetzt und dann nie wieder zurück. Um es besser zu testen, kannst du in
ein anderes 'case' mal
PA3 &= ~(1<<PA3);
einsetzen, um den Pin wieder auszuschalten.
Peter D. schrieb:> Für die Abfrage einzelner Bits ist switch/case nicht geeignet, da die> Nachbarbits mit eingehen.
Doch, ist ja oben schon gemacht worden. Deswegen werden auch die Pins
mit Knöpfen maskiert.
Switch-Case ist immer dann sinnvoll, wenn nur eine Funktion aus vielen
ausgeführt werden soll. Das kann auch zur Verriegelung von Tasten oder
für Mehrfachkombinationen benutzt werden.
Wenn man so einen Buttoninterpreter baut, sollte man ihn allerdings
nicht mit der vollen Tektfrequenz durchrennen lassen, sondern mit ein
paar ms Intervall. Dann klappt das schon recht gut.
Guten Morgen,
ok, das was du hier beschreibtst, soll es auch irgendwann mal werden.
und zwar soll es am Gartenteich eine Schiebetür nach oben und unten mit
drei Sensoren immer auf den mittleren Pegel-Stand gehalten werden, je
nach Wasserstand.Aber dazu muss ich die switch case verstehen.Und da bin
ich noch weit entfernt.
Matthias S. schrieb:> Switch-Case ist immer dann sinnvoll, wenn nur eine Funktion aus vielen> ausgeführt werden soll.
Genau.
Tasten sind aber unabhängig voneinander, daher nimmt man if.
Z.B. eine Taste klemmt oder hat ne Zinnbrücke und schon suchst Du ewig
und 3 Tage, warum die andere Taste nicht mehr funktioniert.
Programmieren heißt nicht nur, es wird schon irgendwie funktionieren,
sondern es funktioniert immer zuverlässig und Fehler oder Defekte lassen
sich schnell debuggen und finden.
ah, ok, dann werd ich es mir mit if else auf schreiben. Trotzdem Danke
für die Mühe, denn ich wollte schon länger mit case switch basteln.
Jetzt läuft es ja soweit zum testen.
zitat.:Programmieren heißt nicht nur, es wird schon irgendwie
funktionieren,
sondern es funktioniert immer zuverlässig und Fehler oder Defekte lassen
sich schnell debuggen und finden.
Genau das will ich mir erarbeiten. Ich habe eigentlich genaue
Vorstellung davon wie es funktionieren soll, nur bin ich auch auf der
Suche mit welchen Code, und meinen noch wenigen Fähigkeiten ich das
umsetzen soll. Jetzt bin ich dem ganzen schon wieder ein Stück näher.
Ich habe einen Frequenzumrichter eine Platine mit relais und diversen
stift leisten bestückt, die in ein Alugehäuse passt. Und die ich mit dem
avr mk2 isp programmieren kann. Muss nur noch meinen Algoryhtmus da rein
bringen :-)
Ps.: jetzt erstmal zwei wochen Urlaub
Huber M. schrieb:> Ps.: jetzt erstmal zwei wochen Urlaub
Ja, nach der Strapaze auch verdient. "C" zehrt unheimlich an den
Reserven des Benutzers.
:)
mfG Paul
switch/case ist ideal für Statemachines und darin kann man dann z.B.
Ereignisse abfragen:
1
switch(state){
2
caseSTATE_X:if(key_pressed(KEY_UP))
3
state=STATE_Y;
4
break;
5
caseSTATE_Y:
6
// usw.
7
}
Ereignisse deshalb, weil nur selten der Zustand interessiert, sondern
oft das Ereignis, daß gerade jemand drauf gedrückt hat.
Es gibt zu jedem Werkzeug dazu passende Aufgaben (und umgekehrt).
Guten tag mal wieder,
ich dachte jetzt habe ich die Logik der case verzweigung endlich mal
richtig verstanden, das ich es selbstständig schreiben kann. Und vor
allem möchte ich das ganze im absolouten anfänger beispiel testen. Ohne
Bits invertiert zu lesen. wenn ich es im AVR Simulator debugge und so
schreibe.
1
uint8_tx=1;// oder x = 2 dann springt er in die zweite zeile
2
3
switch(x)
4
5
case1:PORTD|=(1<<PD0);break;
6
case2:PORTD|=(1<<PD0);break;
klappt es, und ich kann es absolout nachvollziehen. Will ich es aber mit
einem Tatster machen, komme ich einfach nicht klar. Wenn ich
nachfolgendes flashe dann fängt PD0 einfach dauerhaft an zu leuchten.
Und direkt am controller kann ich es nicht debuggen ( Tasterpin im I/O
view ansehen), weil mein MK2 das nicht unterstützt. Wie kann ich das
jetzt ohne invertieren umsetzen
grüsse huber
Huber M. schrieb:> Wie kann ich das> jetzt ohne invertieren umsetzenhttps://www.mikrocontroller.net/articles/Bitmanipulation
Was soll das
Huber M. schrieb:> DDRC &= (1<<PC5); //Eingang
und das bewirken?
Huber M. schrieb:> PORTC = (1<<PC5); //Pullup Eingang> DDRD = (1<<PD0); //Ausgang LED
Wozu gibt es & und | ?
Was macht man, um EIN Bit auf 0 bzw. auf 1 zu setzen?
Mal abgesehen davon, das Du Dir auch mal den Artikel über
Tasten-Entprellung durchlesen solltest (und versuchen, es zu verstehen
...).
Übrigens ist das
Huber M. schrieb:> uint8_t x = 1; // oder x = 2 dann springt er in die zweite zeile>> switch(x)>> case 1: PORTD |= (1<<PD0); break;> case 2: PORTD |= (1<<PD0); break;
vollkommen sinnfrei, wenn Du bei jedem Zustand das Gleiche ausführst. Da
dürfte auch ein Test schwer fallen :-)
Dieter F. schrieb:> vollkommen sinnfrei, wenn Du bei jedem Zustand das Gleiche ausführst. Da> dürfte auch ein Test schwer fallen :-)
das ist mir schon klar, ich wil ja nur mit einem tastendruck mal in die
Schleife kommen, dann kann ich mir mal was überlegen was ein bischen
Sinn macht.
Huber M. schrieb:> das ist mir schon klarHuber M. schrieb:> wenn ich es im AVR Simulator debugge und so> schreibe.>> uint8_t x = 1; // oder x = 2 dann springt er in die zweite zeile>> switch(x)>> case 1: PORTD |= (1<<PD0); break;> case 2: PORTD |= (1<<PD0); break;>> klappt es, und ich kann es absolout nachvollziehen.
Was kannst Du DA nachvollziehen? Das PIND0 immer 1 ist? Egal, welchen
Wert X hat? Quatsch ... :-)
Versuche "Bitmanipulation" zu verstehen ...
Huber M. schrieb:> while(1)> {> uint8_t n = tasterpins;>> switch (n)> {> case (1<<PC5) :>> PORTD |= (1<<PD0); // soll led an PD0> einschalten>> break;> }>> }> }
Dein switch-ase bearbeitet den Fall, das PC5 auf high ist. Und das ist
er dank Pullup immer, wenn der Taster nicht gedrückt ist.
Entweder schreibst du die Case Bedingung um oder das Switch Argument
1
uint8_tn=~(PINC);// oder eben das richtige Pinregister deiner Taster invertiert einlesen
2
switch(n){
3
4
case(1<<PC5):PORTD|=(1<<PD0);break;// LED ein bei Taste PC5
5
case(1<<PC4):PORTD&=~(1<<PD0);break;// LED aus bei Taste PC4
Matthias S. schrieb:> Dein switch-ase bearbeitet den Fall, das PC5 auf high ist. Und das ist> er dank Pullup immer, wenn der Taster nicht gedrückt ist.> Entweder schreibst du die Case Bedingung um oder das Switch Argument
Ok,das leuchtet ein, das heisst, wenn ich Taster an PC5 drücke sollte
PD0 angehen oder ?
1
/*
2
* GccApplication2.c
3
*
4
* Created: 09.10.2016 14:48:27
5
* Author: HUBER M
6
*/
7
8
9
#include<avr/io.h>
10
11
#define tasterpins (1<<PC5)
12
13
intmain(void)
14
{
15
PORTC|=(1<<PC5);//Pullup Eingang
16
DDRD|=(1<<PD0);//Ausgang LED
17
18
voidtastertest()
19
{
20
if(!(PINC&(1<<PC5)))
21
{
22
PORTD|=(1<<PD0);
23
}
24
else
25
{
26
PORTD&=~(1<<PD0);
27
}
28
}
29
while(1)
30
{
31
32
33
uint8_tn=~(PINC);// oder eben das richtige Pinregister deiner Taster invertiert einlesen
34
switch(n)
35
{
36
37
case(1<<PC5):PORTD|=(1<<PD0);break;// LED ein bei Taste PC5
38
case(1<<PC4):PORTD&=~(1<<PD0);break;// LED aus bei Taste PC4
39
}
40
41
42
}
43
}
weshalb leuchtet hier PD0 nicht?
wenn ich meine tastertest Funktion in die while schleife schreibe. Und
die Taste drücke dann leuchtet PD0. Also an der Verkabelung kann es
schon mal nicht liegen
1
while(1)
2
{
3
4
tastertest();
5
// uint8_t n = ~(PINC); // oder eben das richtige Pinregister deiner Taster invertiert einlesen
6
//switch (n)
7
// {
8
9
// case (1 << PC5) : PORTD |= (1 << PD0); break; // LED ein bei Taste PC5
10
// case (1 << PC4) : PORTD &= ~(1 << PD0); break; // LED aus bei Taste PC4
Uups, dir muss man ja alles vorkauen, aber gut. Du solltest die Buttons
natürlich ausmaskieren, und nicht den gesamten Ausdruck verwenden, der
aus dem Pinregister kommt.
Am übersichtlichsten wird das mit defines:
Morgen,
ich weiß schon, ich bin schlimm, war wohl schon wieder zu lange davor
gesessen. Hatte eine totale Hirnblockade, aber trotzdem Danke für deine
Mühe.
so, jetzt habe ich nochmal ein Problem. Und zwar würde ich gerne einen
Fall bearbeiten , wenn ein taster nicht gedrückt ist, mach irgend was.
Jetzt, wenn ich bei PA0 eine 0 reinschreibe funktioniert das auch wunder
bar, bei PA0. Bei PA1 das selbe und er meckert beim compilieren
:::duplicate case value:::
ich habe natürlich auch schon probiert ~(1<<PA0)invertiert das in der
klammer doch ?
&= ~(1<<PA0) löscht das bit.
(PINA&(1<<PA0)) wenn bit high
(!(PINA&(1<<PA0))) wenn bit low
oder muss ich hier extra nochmal definieren?
ja, aber ich hatte es ja schon mal hinbekommen vor ein paar wochen, habs
mir aber wieder gelöscht :-(, und vergessen wie ich es gemacht habe. Und
ich stelle mir das so vor, wenn ich mir ein paar Taster anschließe, die
dann in der Praxis drücke und danach drauf komme, den fall hatte ich
hier nicht mit berechnent, dann schreib ich mir einfach einen neuen fall
dazu, so in etwa.Und ich bin wieder glücklich.
Peter D. schrieb:> Du hast den Sinn von switch/case immer noch nicht verstanden.
das "Nicht verstehen" fängt doch schon ganz unten an, bei
Bitmanipulation und Pinabfrage, und hat mit switch/case (noch) nix zu
tun
@TE: leg den µC beiseite und lern erstmal die C Grundlagen 'normal' am
PC, ohne Hardwarebezug, bevor du dich dann an µCs wagst...
habe seit vorletzter Woche das buch C programmiern von anfang an. Darin
übe ich mich mit Codeblocks. Und Avr microcontroller in c Programmieren
schon etwas länger. Das einzige das ich momentan damit nicht zu hundert
prozent durcharbeiten kann, ist zb. taster beim debuggen im I/O view
beobachten. da mir zu anfang der mk2 isp programmer empfohlen worden
ist. und der keine debugg Funktion hat. Und deshalb tu ich mich da so
schwer das zu verstehen. Brauche erstmal dennächst den avr dragon o.ä.
dann muss ich auch nicht mehr soviel fragen.
Der Debugger kann Dir auch nichts anderes dazu sagen:
1 Taster = 1 IO-Pin = 1 Bit.
Da noch Nachbarpins hinein zu verwursten, muß in die Hose gehen und geht
auch in die Hose, wie Du ja gemerkt hast.
Schau Dir einfach mal an, wie andere ihre Tasten auswerten.
Ein Dragon ändert weder was dan den Compilerfehlermeldungen, die dein
Code versursacht, noch an deinem fehlenden grundlegenden Verständnis der
Sprache C. Da wirst du erst mal die Grundlagen lernen müssen. Danach ist
der natürlich eine gute Hilfe.
Oliver
Oliver S. schrieb:> Ein Dragon ändert weder was dan den Compilerfehlermeldungen, die dein> Code versursacht
das ist mir schon klar, dann wäre ich aber gleich viel eher drauf
gekommen.
Peter D. schrieb:> Schau Dir einfach mal an, wie andere ihre Tasten auswerten.
warscheinlich mit if..else if....
ich habe auch kein grösseres Problem mir ne state maschine zu bauen, wie
beispielsweise bei ner Ampel. Ich dachte ich habe mal gelesen das die
case verzweigung eine elegantere Lösung für die if abfrage ist. Da habe
ich wohl irgendwas falsch verstanden
ps.: ich glaube bei ner rollo taster schaltung wurde die case mal zu mir
gesagt. weil man da jeden Fall abdecken kann.
Huber M. schrieb:> warscheinlich mit if..else if....
Eher ohne "else".
Es sei denn, Du willst explizit verbieten, daß mehrere Tasten betätigt
werden dürfen.
Auch fragt man Tasten nie im Code direkt ab, sondern nur die Ereignisse,
die eine Entprellroutine liefert.
Switch überprüft immer, ob ein Wert gleich einer Konstante ist. Du hast
aber folgende situation:
1
if(x&(1<<0)){// ist bit 1 gesetzt?
2
}
3
if(x&((1<<1)|(1<<2))){// ist bit 2 oder bit 3 gesetzt?
4
}
Das kann man nicht mit switch case abbilden, denn es ist kein Vergleich
ob ein Wert gleich einem anderen ist, sonderneine Verundung, bei der die
Werte in der Bitmaske übrig bleiben, und auf nicht gleich 0 getestet
werden. Das ist kein Vergleich zwischen x und der Bitmaske/konstante,
ergo nicht mit switch case abbildbar. (ausser man macht 128 cases pro
prüfung bei 8 bit)