Forum: Mikrocontroller und Digitale Elektronik Hilfe bei Parallel-IO dringend (AVR)


von Denis G. (vlplayer)


Lesenswert?

Hey Leute ich sollte ein Prog schreiben das man auf einen Tastendruck 
wartet und dann (jenachdem) welche Taste gedrückt wurde ein bestimmtes 
Muster an den Led's ausgibt.. nun habe ich folgendes Problem habe 
zuhause nur AVRstudio und den Simulator und es läuft einfach nicht 
richtig das Programm..... ich zerbrech mir schon Tagelang den Kopf hoffe 
Ihr könnt mir helfen .....

#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>

#define MAX_PATLEN 10

void delay_ms(unsigned int ms);


struct Pattern
{
  char PatArray[MAX_PATLEN];
  unsigned char patlen;
};

void putPattern(const struct Pattern* pPat, double delay);
void putSelPattern(unsigned char num);
unsigned char waitforKey();
unsigned char getKeyNum (unsigned char sw);
void initport();



int main()
{
  initport();


  putSelPattern(getKeyNum (waitforKey()));

  while(1);
  return 0;

}



void initport(void)
{
    DDRD = 0x00;       // PORT A als EINGANG
  PORTD = 0xff;      // Pull-up wird gesetzt

  DDRB=0xff;                 // Port B auf Ausgang
    PORTB=0x00;                // Alle Ausg�nge auf 0
}



void putPattern(const struct Pattern* pPat, double delay)
{
  int i;

for(i=0;i<pPat->patlen;i++)  //Ausgabe der Bytes
  {
    PORTB=pPat->PatArray[i];
    _delay_ms(100);      //Wartezeit
  }

}

void putSelPattern(unsigned char num)
{

const struct Pattern 
P0={{0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80},9};
const struct Pattern P1={{0x18,0x24,0x42,0x81},4};
const struct Pattern 
P2={{0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00},10};
const struct Pattern P3={{0xff,0x00,0xff},3};
const struct Pattern P4={{0xc0},1};
const struct Pattern P5={{0x03},1};
const struct Pattern P6={{0xff,0x00},2};




switch(num)
{

  case 0:

  putPattern(&P0,250);
  break;

  case 1:

  putPattern (&P1,250);
  break;

  case 2:

  putPattern (&P2,250);
  break;

  case 3:

  putPattern (&P3,125);
  break;

  case 4:

  putPattern (&P4,1000);
  break;

  case 5:

  putPattern (&P5,1000);
  break;

  case 6:

  putPattern (&P6,1000);
  break;

  default:
    PORTB = 0xAA;

}
}

unsigned char waitforKey()
{
  uint8_t Key;

  Key = 0;
  while(Key == 0)
  {
    while(PIND==0xff);  // wartet bis irgendeine der 8 Tasten gedrueckt 
ist
    _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
    while(PIND!=0xff)
    {
      Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
      _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
    }
  }
  return Key;
}

unsigned char getKeyNum(unsigned char sw)
{
  if (sw==0x01)
    return 0;
  else if(sw==0x02)
    return 1;
  else if(sw==0x04)
    return 2;
  else if(sw==0x08)
    return 3;
  else if(sw==0x10)
    return 4;
  else if(sw==0x20)
    return 5;
  else if(sw==0x40)
    return 6;
  else if(sw==0x80)
    return 7;
  else
    return 255;

}

von Klaus (Gast)


Lesenswert?

Wichtige Regeln - erst lesen, dann posten!

    * Groß- und Kleinschreibung verwenden
    * Längeren Sourcecode nicht im Text einfügen, sondern als 
Dateianhang

von Gast (Gast)


Lesenswert?

Was funktioniert nicht?
Warum nimmst du Teile deines Progamms nicht einzeln in Betrieb?
z.B. Taster einlesen, Muster an LEDs ausgeben.

von Denis G. (vlplayer)


Lesenswert?

also das programm läuft einfach nicht rund..... zuhause hier in dem 
Simulator ist es eine absolute katastrophe da er bei 
"putSelPattern(getKeyNum (waitforKey()));" dieser funktion hängen 
bleibt, da ich ja eine taste drücken muss was ich jedoch am simulator 
nicht so hinkriege. in der fh war es so das wenn ich eine Taste gedrückt 
hatte  das ein muster kam jedoch hat es sich danach aufgehängt .
der prof meinte ich sollte mir das nochmal angucken

void putPattern(const struct Pattern* pPat, double delay)
{
  int i;

for(i=0;i<pPat->patlen;i++)  //Ausgabe der Bytes
  {
    PORTB=pPat->PatArray[i];
    _delay_ms(100);      //Wartezeit
  }

}

von Hc Z. (mizch)


Lesenswert?

Denis G. schrieb:
> in der fh war es so das wenn ich eine Taste gedrückt
> hatte  das ein muster kam jedoch hat es sich danach aufgehängt .

Es hat sich nicht aufgehängt, sondern es ist so geschrieben:  Nach einem 
Tastendruck bleibt das Programm in while(1) hängen.  Es tut also nur, 
was ihm gesagt wurde.

von ... .. (docean) Benutzerseite


Lesenswert?

du solltest über deine main nochmal nachdenken... zur zeit tut das prg 
nicht viel...

und der simulator kann auch tasten simulieren, du kannst einfach die 
passenden kästchen anklicken...

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

1
int main()
2
{
3
  initport();
4
  putSelPattern(getKeyNum (waitforKey()));
5
  while(1);
6
  return 0;
7
}

Was macht Dein Programm da?

1. Ports initialisieren
2. Auf Tastendruck warten, in Tastennummer umrechnen, Pattern ausgeben.
3. Endlosschleife   <=== !!!

> in der fh war es so das wenn ich eine Taste gedrückt
> hatte  das ein muster kam jedoch hat es sich danach aufgehängt .
Also passiert genau das, was Du hier beschreibst.

von Denis G. (vlplayer)


Lesenswert?

ja aber bevor das prog in die whil schleife läuft muss es ja durch diese 
funktion putSelPattern(getKeyNum (waitforKey()));
 das heisst er holt sich den tastendruck , dann guckt er was zu dem 
tastendruck zugewiessen wurde und führt dann das muster aus  UND DANN 
ERST GEHTS IN DIE WHILE schleife oder????
also so wars gedacht nur er kommt nicht mal zu der funktion nich mal 
wenn ich an der funktion ein breakpoint setzte

von Denis G. (vlplayer)


Lesenswert?

ich kann keine pins anklicken im simulator selbst wenn ich das Value 
änder passiert nix habs auch schon mit dem prog Hapsim versucht aber nix

von Hc Z. (mizch)


Lesenswert?

Nach ein Punkt, der auffällt:
1
>     while(PIND!=0xff)
2
>     {
3
>       Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
4
>       _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
5
>     }

Hier nimmst Du an, dass sich PIND nicht ändern kann zwischen 
while-Bedingung und Key-Zuweisung.  Das muss nicht der Fall sein.  Du 
kannst so durchaus ab und zu Key auf 0xff zurückbekommen (auch wenn es 
nicht sehr wahrscheinlich ist).

Allgemein zum Programmierstil:  Sauberes Einrücken ist nicht für 
Weicheier, sondern drückt aus, dass Du Dein Programm sauber durchdacht 
und strukturiert hast.  Das hast Du aber doch, oder?  Warum zeigt Dein 
Programm dann das nicht, sondern sieht aus wie Kraut und Rüben?

von Denis G. (vlplayer)


Lesenswert?

tja das sagt mir jeder prof nur leider hab ich es mir schon fast 
angewohnt so "unsauber " zu proggen vielleicht kommt hinzu das man unter 
zeitdruck steht .... muss es mir abgewöhnen

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> ja aber bevor das prog in die whil schleife läuft muss es ja durch diese
> funktion putSelPattern(getKeyNum (waitforKey()));
>  das heisst er holt sich den tastendruck , dann guckt er was zu dem
> tastendruck zugewiessen wurde und führt dann das muster aus  UND DANN
> ERST GEHTS IN DIE WHILE schleife oder????
> also so wars gedacht nur er kommt nicht mal zu der funktion nich mal
> wenn ich an der funktion ein breakpoint setzte

Welche der hier beteiligten Funktionen? Das sind mehrere.
Eventuell mal in getrennte Zeilen aufteilen.

Einfach mal drei LEDs anschließen und diese als AUS vorbelegen.
Dann in jeder der betroffenen Funktione eine der LEDs einschalten.
Somit kannst Du auch ohne Debugger sehen, welche Funktion noch 
ausgeführt wird.

von Denis G. (vlplayer)


Lesenswert?

Hazeh Zimmerer schrieb:
> Nach ein Punkt, der auffällt:
>
1
>>     while(PIND!=0xff)
2
>>     {
3
>>       Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
4
>>       _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
5
>>     }
6
>
>
> Hier nimmst Du an, dass sich PIND nicht ändern kann zwischen
> while-Bedingung und Key-Zuweisung.  Das muss nicht der Fall sein.  Du
> kannst so durchaus ab und zu Key auf 0xff zurückbekommen (auch wenn es
> nicht sehr wahrscheinlich ist).
>
>

Gut aber das kann ja nicht der hauptgrund sein?!

von MeinerEiner (Gast)


Lesenswert?

> ... vielleicht kommt hinzu das man unter zeitdruck steht

Die Zeit, die du da sparst, verschleuderst du später vielfach bei der 
Fehlersuche.

von Denis G. (vlplayer)


Lesenswert?

>
> Welche der hier beteiligten Funktionen? Das sind mehrere.
> Eventuell mal in getrennte Zeilen aufteilen.
>
> Einfach mal drei LEDs anschließen und diese als AUS vorbelegen.
> Dann in jeder der betroffenen Funktione eine der LEDs einschalten.
> Somit kannst Du auch ohne Debugger sehen, welche Funktion noch
> ausgeführt wird.

also wenn ich mein debugger starte geht er in die funktion initport(); 
anschliessend nix mehr ..... einfach erklärt

von Denis G. (vlplayer)


Lesenswert?

MeinerEiner schrieb:
>> ... vielleicht kommt hinzu das man unter zeitdruck steht
>
> Die Zeit, die du da sparst, verschleuderst du später vielfach bei der
> Fehlersuche.

da hast du wohl recht

von Hc Z. (mizch)


Lesenswert?

> Gut aber das kann ja nicht der hauptgrund sein?!

Nein.  Der Hauptgrund ist, was ich und viele andere schon schrieben: 
Dein Programm ist so aufgebaut, dass es nach einem Tastendruck in eine 
ewige Schleife geht.  Das Verhalten, das Du als Fehler beschreibst, ist 
nichts als das, was das Programm vorschreibt.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> tja das sagt mir jeder prof nur leider hab ich es mir schon fast
> angewohnt so "unsauber " zu proggen vielleicht kommt hinzu das man unter
> zeitdruck steht .... muss es mir abgewöhnen

Dann solltest Du dir dringend einen anderen Programmierstil zulegen. Mit 
dieser Einstellung wirst Du nie ein längeres Projekt bestehen können.
Was passiert wohl, wenn Du wärend eines größeren Projektes mal eine 
Woche Urlaub hast. Danach musst Du Dein Programm nochmal neu verstehen 
lernen oder nochmal komplett neu schreiben, da das einfach schneller 
geht.

Auch solltest Du dir dringend eine ordentliche Kommentierung angewöhnen.

> for(i=0;i<pPat->patlen;i++)  //Ausgabe der Bytes

Aha, was wird da ausgegeben?

> _delay_ms(100);      //Wartezeit

Ach neee, hätte nicht gedacht, dass das Programm hier wartet.

Du solltest nicht schreiben was passiert, sondern warum Du es gerade 
so gemacht hast.

von Denis G. (vlplayer)


Lesenswert?

so habe nun mal das probiert :

putSelPattern(getKeyNum (3));//waitforKey()));

da müsste er mir ja mein 3.Muster ausgeben.?!?

kommt aber dann mein default muster raus
also tut sich wenigstens etwas

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> also wenn ich mein debugger starte geht er in die funktion initport();
> anschliessend nix mehr ..... einfach erklärt

Aha, dann zeige uns mal die Endlosschleife in initport().
Ich würde mich als Prozessor jedenfalls nicht lange darin aufhalten.

von Denis G. (vlplayer)


Lesenswert?

Christian H. schrieb:

>
> Dann solltest Du dir dringend einen anderen Programmierstil zulegen. Mit
> dieser Einstellung wirst Du nie ein längeres Projekt bestehen können.
> Was passiert wohl, wenn Du wärend eines größeren Projektes mal eine
> Woche Urlaub hast. Danach musst Du Dein Programm nochmal neu verstehen
> lernen oder nochmal komplett neu schreiben, da das einfach schneller
> geht.
>
> Auch solltest Du dir dringend eine ordentliche Kommentierung angewöhnen.
>
>> for(i=0;i<pPat->patlen;i++)  //Ausgabe der Bytes
>
> Aha, was wird da ausgegeben?
>
>> _delay_ms(100);      //Wartezeit
>
> Ach neee, hätte nicht gedacht, dass das Programm hier wartet.
>
> Du solltest nicht schreiben was passiert, sondern warum Du es gerade
> so gemacht hast.


also vielleicht nochmal zu meinen Hintergründen sollte keine 
entschuldigung sein hole mir gerne tipps von programieren aber ich 
studier energie.-elektronik.- und Umwelttechnik habe nur die Grundlagen 
. auch wenn mich proggen nicht wirklich überzeugt gehört es nunmal zu 
meinem studium dazu jedoch entschuldigt das vielleicht mein Stil !

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> so habe nun mal das probiert :
>
> putSelPattern(getKeyNum (3));//waitforKey()));
>
> da müsste er mir ja mein 3.Muster ausgeben.?!?

Nein, denn 3 wird in Deinem getKeyNum() immer mit 255 beantwortet.
Das 3. Muster wäre getKeyNum(4).

von Denis G. (vlplayer)


Lesenswert?

>> putSelPattern(getKeyNum (4));//waitforKey()));
>>
Reaktion = Keine

von Denis G. (vlplayer)


Lesenswert?

Christian H. schrieb:
> Denis G. schrieb:
>> also wenn ich mein debugger starte geht er in die funktion initport();
>> anschliessend nix mehr ..... einfach erklärt
>
> Aha, dann zeige uns mal die Endlosschleife in initport().
> Ich würde mich als Prozessor jedenfalls nicht lange darin aufhalten.

im initport() habe ich keine while schleife

von Denis G. (vlplayer)


Lesenswert?

putSelPattern(getKeyNum (0x20));//waitforKey()));

Reaktion== LED 1 und LED 0 werden eingeschaltet das funktioniert 
schonmal

von krishna (Gast)


Lesenswert?

>void delay_ms(unsigned int ms);

Wo findet man diese Funktion ?

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

_delay_ms(100);      //Wartezeit

Läuft wahrscheinlich zu schnell, so dass Du die ersten Pattern nicht 
siehst, sondern nur das letzte in Deiner Kette. Beim 3. Muster also 
0x00.

Stimmt das mit der eingesetzten Taktfrequenz überein?
> #define F_CPU 1000000

von Denis G. (vlplayer)


Lesenswert?

Christian H. schrieb:
> _delay_ms(100);      //Wartezeit
>
> Läuft wahrscheinlich zu schnell, so dass Du die ersten Pattern nicht
> siehst, sondern nur das letzte in Deiner Kette. Beim 3. Muster also
> 0x00.
>
> Stimmt das mit der eingesetzten Taktfrequenz überein?
>> #define F_CPU 1000000

da kannst du recht haben denn ich hab eben mal probiert LED 1 und LED 0 
einmal ein und wieder aus zu schalten und siehe da ich sehe nix nur das 
sie aus sind

wie kann ich die taktfrequenz heraus finden? in der fh haben wir diese 
genommen

von krishna (Gast)


Lesenswert?

1
    while(PIND!=0xff)
2
    {
3
      Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
4
      _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
5
    }

Überleg mal genau, was worst-case aus diesem Stückchen rauskommen könnte
Vor allem in Verbindung mit der (tschuldigung) Schrott-Fkt "getKeyNum" 
(Hast du mal was von "shiften" gehört ?

von krishna (Gast)


Lesenswert?

Schreib das Programm komplett neu.
Es ist 5 Mal länger als es sein müßte.

Und versuch erstmal die Warnings (die da bestimmt auftreten) zu 
eliminieren.

Dann erst debuggen.

von Denis G. (vlplayer)


Lesenswert?

krishna schrieb:
>
1
>     while(PIND!=0xff)
2
>     {
3
>       Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
4
>       _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
5
>     }
6
>
>
> Überleg mal genau, was worst-case aus diesem Stückchen rauskommen könnte
> Vor allem in Verbindung mit der (tschuldigung) Schrott-Fkt "getKeyNum"
> (Hast du mal was von "shiften" gehört ?

ja wenn die taste losgelassen ist wird der inhalt invertierend 
zurückgegeben das an der gedrückten taste eine 1 ist.

um tastenprellen zu verhindern dann das delay

sorry sollten die Fkt so machen war aufgabenstellung .

von Denis G. (vlplayer)


Lesenswert?

krishna schrieb:
> Schreib das Programm komplett neu.
> Es ist 5 Mal länger als es sein müßte.
>
> Und versuch erstmal die Warnings (die da bestimmt auftreten) zu
> eliminieren.
>
> Dann erst debuggen.

0 errorrs 0 warnings

von Denis G. (vlplayer)


Angehängte Dateien:

Lesenswert?

o errors 0 warnings

von krishna (Gast)


Lesenswert?

was ist wenn sich zwischen

>     while(PIND!=0xff)

und

>       Key = ~PIND;

der Wert von PIND ändert ? Z.b. von 2 auf 255 ?

Was steht dann in Key ?

:-)



Schreibs komplett neu. Da sind noch mehr Fehler drin, das mach keinen 
Spaß.

von Denis G. (vlplayer)


Lesenswert?

krishna schrieb:
> was ist wenn sich zwischen
>
>>     while(PIND!=0xff)
>
> und
>
>>       Key = ~PIND;
>
> der Wert von PIND ändert ? Z.b. von 2 auf 255 ?
>
> Was steht dann in Key ?
>
> Schreibs komplett neu. Da sind noch mehr Fehler drin, das mach keinen
> Spaß.

wieso sollte er sich ändern

von Denis G. (vlplayer)


Lesenswert?

also es is absolut scheisse von dir .... ich sitzt seit 1 woche an dem 
prog und der prof sagt es kann nur noch ein kleiner fehler sein .... und 
du sagst machs neu?
ich hab gedacht das is ein forum wo geholfen werden kann ?!

von Denis G. (vlplayer)


Lesenswert?

nochmal ne frage dazu

const struct Pattern 
P0={{0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80},9};
const struct Pattern P1={{0x18,0x24,0x42,0x81},4};
const struct Pattern 
P2={{0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00},10};
const struct Pattern P3={{0xff,0x00},2};
const struct Pattern P4={{0xc0,0x00},2};
const struct Pattern P5={{0x03,0x00},2};
const struct Pattern P6={{0xff,0x00},2};

0. lauflicht recht ->links
1. lauflicht von mitte nach aussen
2. alle 5mal ein und aus
3. alle einmal ein und aus
4. LED 7 und 6 einmal ein und aus
5. led 1 und 0 einmal ein und aus
6. alle ein und aus

von krishna (Gast)


Lesenswert?

>wieso sollte er sich ändern

Wann ändert sich der Wert von PIND denn ? :-)

Du hast auch immer noch nicht verraten, wo man
>void delay_ms(unsigned int ms);

findet. Ok, es wird zwar nicht benutzt, aber...

von Denis G. (vlplayer)


Lesenswert?

krishna schrieb:
>>wieso sollte er sich ändern
>
> Wann ändert sich der Wert von PIND denn ? :-)
>
> Du hast auch immer noch nicht verraten, wo man
>>void delay_ms(unsigned int ms);
>
> findet. Ok, es wird zwar nicht benutzt, aber...

er ändert sich wenn ich es drücke bzw loslasse....

mit dem delay hatte ich vorher versucht ..... bis ich bemerkt habe das 
ich es eigentlich nicht brauche ....


guck mal bitte über meine putPattern funktion ob ich die richtig gemacht 
habe !?

von Klaus W. (mfgkw)


Lesenswert?

Also dann mal reale Hilfe:
- die bisherigen Tipps zumindest mal ins Auge fassen
- lesbaren, vernünftig kommentierten und formatierten
  Quelltext präsentieren
- Tipps zum Programmieren nicht einfach wegwischen mit der
  Begründung "mein Stil ist halt schlecht"

Ein lesbarer Quelltext ist zum einen für dich eine Hilfe;
aber auch wenn du darauf verzichten magst, mutest du
dennoch den Leuten, die dir helfen sollen, denselben Quelltext
zu.

Den Quelltext ordentlich zu formatieren und (wie beim Schreiben
jedes Posts hier im Forum wenige Zentimeter drüber verlangt)
als C-Quelltext zu markieren, sollte man noch schaffen.
Wie gesagt zumindest aus Höflichkeit den Helfern gegenüber.

von Denis G. (vlplayer)


Lesenswert?

also immoment ist es so das wenn ich es im code änder 
putSelPattern(getKeyNum (0x08));//waitforKey())); das es funktioniert .

wenn ich nun aber putSelPattern(getKeyNum (waitforKey())); mache macht 
er nix , logisch da er auf ein Key wartet nun will ich im simulator ein 
bit setzen , macht er aber nicht ....

von Denis G. (vlplayer)


Lesenswert?

Klaus Wachtler schrieb:
> Also dann mal reale Hilfe:
> - die bisherigen Tipps zumindest mal ins Auge fassen
> - lesbaren, vernünftig kommentierten und formatierten
>   Quelltext präsentieren
> - Tipps zum Programmieren nicht einfach wegwischen mit der
>   Begründung "mein Stil ist halt schlecht"
>

Natürlich gebe ich dir recht . ich wisch es nicht einfach so weg ich 
habe gesagt ich nehme jede hilfe von programieren dankend an und versuch 
sie halt umzusetzen bin auch jedem dankbar der seine Zeit opfert und 
hilft ...

von krishna (Gast)


Lesenswert?

Und drüber nachdenken, warum du diese Schleife

>  while(Key == 0) {..}

gemacht hast, und ob sie überhaupt notwenig ist.

Mach zumindest die Tastenabfrage komplett neu.

Es sind vermutlich noch mehr Fehler drin, aber ich verliere grade die 
Lust :-)

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Btw.: In deinem Screenshot deiner Entwicklungsumgebung wird links die 
Geschwindigkeit 4MHz genannt. In Deinem Code aber 1MHz.

von Denis G. (vlplayer)


Lesenswert?

krishna schrieb:
> Und drüber nachdenken, warum du diese Schleife
>
>>  while(Key == 0) {..}
>
> gemacht hast, und ob sie überhaupt notwenig ist.
>
> Mach zumindest die Tastenabfrage komplett neu.
>
> Es sind vermutlich noch mehr Fehler drin, aber ich verliere grade die
> Lust :-)

ja kann ich mir vorstellen =) und versetzt dich mal in meine lage ich 
probier und probier und hab die lust schon fast am programiieren 
verloren obwohl ich erst damit angefangen habe =)

wenn ich es neu schreiben würde , würde ich es so machen denn DAS ist 
meine überlegung dafür . ich initialiser mein key mit 0 und warte bis 
die taste gedrückt ist und invertiere den PIND damit ich eine 1 habe und 
wird im KEY gespeichert und zurückgegeben

von Denis G. (vlplayer)


Lesenswert?

also ich bin jetzt soweit das ich mir auf jedenfall denke das es am 
waitforKey liegt denn wenn ich es im code änder werden die muster alle 
ausgeführt......

wie kann ich mein wait for key am besten ändern

von MeinerEiner (Gast)


Lesenswert?

> Btw.: In deinem Screenshot deiner Entwicklungsumgebung wird links die
> Geschwindigkeit 4MHz genannt. In Deinem Code aber 1MHz.

Ist ne Standard-"Krankheit" vom AVR-Studio.
Das nimmt zu Beginn eines Debug-Ablaufes immer die 4MHz, unabhängig von 
dem, was man verwendet.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Rate mal, was passiert, wenn Du die Taste wärend des ersten Delay wieder 
loslässt?

Genau, die zweite Schleife wird nicht ausgeführt, da PIND = 0xff.

darauf folgt:
Key = 0 => getKeyNum(0) = 255 => Defaultpattern

von krishna (Gast)


Lesenswert?

1. Da Dein Programm in Main nach einmaliger Ausgabe sowieso in eine 
endlosschleife geht, brauchst du nichts entprellen.

2. Da du nicht entprellen musst, warte einfach nur darauf, daß eine 
Taste Gedrück wird... ist erstmal einfacher für dich.

von Denis G. (vlplayer)


Lesenswert?

MeinerEiner schrieb:
>> Btw.: In deinem Screenshot deiner Entwicklungsumgebung wird links die
>> Geschwindigkeit 4MHz genannt. In Deinem Code aber 1MHz.
>
> Ist ne Standard-"Krankheit" vom AVR-Studio.
> Das nimmt zu Beginn eines Debug-Ablaufes immer die 4MHz, unabhängig von
> dem, was man verwendet.

ja ok macht aber immoment nix da ich hapsim benutzt und da meine muster 
an den leds sehe und in der uni selbst benutzten wir eclipse

von Denis G. (vlplayer)


Lesenswert?

Christian H. schrieb:
> Rate mal, was passiert, wenn Du die Taste wärend des ersten Delay wieder
> loslässt?
>
> Genau, die zweite Schleife wird nicht ausgeführt, da PIND = 0xff.
>
> darauf folgt:
> Key = 0 => getKeyNum(0) = 255 => Defaultpattern

ja gut aber wer kann denn innerhalb von 100ms die taste loslassen?!

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Christian H. schrieb:
> Rate mal, was passiert, wenn Du die Taste wärend des ersten Delay wieder
> loslässt?
>
> Genau, die zweite Schleife wird nicht ausgeführt, da PIND = 0xff.
>
> darauf folgt:

Sorry, hatte die äußere While-Schleife übersehen.
Key = 0 => genau diese Schleife wird nicht beendet.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> ja gut aber wer kann denn innerhalb von 100ms die taste loslassen?!

Das ist 1/10 Sekunde, also eine Ewigkeit.

von Denis G. (vlplayer)


Lesenswert?

Christian H. schrieb:
> Denis G. schrieb:
>> ja gut aber wer kann denn innerhalb von 100ms die taste loslassen?!
>
> Das ist 1/10 Sekunde, also eine Ewigkeit.

das heisst?! delay kürzer machen oder weg?!

von krishna (Gast)


Lesenswert?

Nochmal, du Du wartest nur auf einen einzigen Tastendruck, da brauchst 
du nicht zu entprellen. Danach ist das Programm (nach einigem anderem 
Kram) sowieso zuende.

von MeinerEiner (Gast)


Lesenswert?

> ja gut aber wer kann denn innerhalb von 100ms die taste loslassen?!

Der Taster selbst... Stichwort Prellen.
Der erste Puls wird niemals 100ms erreichen.

von Denis G. (vlplayer)


Lesenswert?

unsigned char waitforKey()
Wartet auf eine Eingabe vom Benutzer über die an PortA angeschlossenen 
Tasten. Dabei soll es egal sein,
welche Taste bzw. ob mehr als eine Taste gedrückt wird. Gibt den 
invertierten Inhalt zurück, den das
PIND-Register bei Tastendruck hat, so dass der Rückgabewert an der 
Position einer gedrückten Taste eine
1 enthält.
Hinweise:
Beachten Sie, dass PIND den Inhalt 0xff hat, wenn keine Taste gedrückt 
ist. Der Tastendruck ist erst
abgeschlossen, wenn der Benutzer die Taste wieder losgelassen hat. Um 
eine Reaktion des Programms
auf evtl. auftretendes Tastenprellen zu verhindern, sollte die Funktion 
mit Hilfe von delay_ms eine kurze
Zeit abwarten ehe sie zurückkehrt.

unsigned char getKeyNum(unsigned char sw)
Wandelt den Wert, den waitforKey() liefert, in die Nummer der gedrückten 
Taste um, so wie sie auf dem
Evaluationsboard bezeichnet sind (niederwertigstes Bit entspricht der 
Taste 0, höchstwertiges Bit der Taste

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> Wartet auf eine Eingabe vom Benutzer über die an PortA angeschlossenen
> Tasten.

> Beachten Sie, dass PIND den Inhalt 0xff hat, wenn keine Taste gedrückt

PortA != PIND

von Denis G. (vlplayer)


Lesenswert?

Christian H. schrieb:
> Denis G. schrieb:
>> Wartet auf eine Eingabe vom Benutzer über die an PortA angeschlossenen
>> Tasten.
>
>> Beachten Sie, dass PIND den Inhalt 0xff hat, wenn keine Taste gedrückt
>
> PortA != PIND

sorry für anfänger das heisst?

von MeinerEiner (Gast)


Lesenswert?

Wenn die Taster an PortA angeschlossen sind, bringt es nichts, PinD 
abzufragen.

von Denis G. (vlplayer)


Lesenswert?

ja aber im simulator ist es ja theoretisch egal erstmal oder?!

von Denis G. (vlplayer)


Lesenswert?

AHh jetzt fällts mir wieder ein in der fh waren die taster aber an port 
D deshalb

von MeinerEiner (Gast)


Lesenswert?

So wird das nie was. Machs doch gleich richtig, nimm die Ports her, wo 
das Zeug dranhängt. Da kommt sonst nur noch mehr Chaos rein.

von Denis G. (vlplayer)


Lesenswert?

SOrry hab nicht mehr dran gedacht das die Taster an PortD im Labor 
angeschlossen waren


vielleicht hab ich auch einfach ein problem mit dem simulator 
umzugehen?!
wenn ich ihn laufen lasse kann ich an PIND ein Bit anklicken um ihn als 
Taste einzuschalten?! richtig!=?

von krishna (Gast)


Lesenswert?

Einfachst-Variante:

//Warten auf Tastendruck: (Also solange, bis PIND != 255 ist)
do ( key=~PIND } while (!key);
_delay_ms(100); //"Entprellen"
//Warten auf Taste Loslassen:
while (PIND!=255);
_delay_ms(100); //Tasten können auch beim loslassen prellen.

Tippfehler darfste behalten.

>Dabei soll es egal sein,
>welche Taste bzw. ob mehr als eine Taste gedrückt wird.

Das muss dann aber auch in getKeyNum beachtet werden. Derzeit wird es 
nicht beachtet.

von krishna (Gast)


Lesenswert?

Achne, du gibst ja dann 255 zurück. Tschuldigung.

von Denis G. (vlplayer)


Lesenswert?

gut aber im simulator klappt das nicht mit taste drücken

von Karl H. (kbuchegg)


Lesenswert?

Und noch ein Tip.
Arbeite in Schritten.
Wenn du Probleme mit der Tastenabfrage hast, dann mach dir ein Programm, 
welches erstmal nur die Tastenabfrage testet. Zb in dem das von den 
Tasten eingelesene Muster einfach nur auf den LED ausgegeben wird.
1
int main()
2
{
3
  DDRD = 0xFF;
4
  PORTD = 0xFF;
5
6
  while( 1 ) {
7
    PORTB = waitforKey();
8
  }
9
}

Solange das nicht zuverlässig funktioniert, hat es keinen Sinn sich da 
noch zusätzliche Fehlerquellen in Form von Auswertungen und 
Muster-Ausgaben einzubauen.

Wenn es funktioniert, dann hängst du als nächstes getKeyNum ein und 
kontrollierst wieder anhand deiner LED, ob diese Auswertung stimmt
1
int main()
2
{
3
  DDRD = 0xFF;
4
  PORTD = 0xFF;
5
6
  while( 1 ) {
7
    PORTB = getKeyNum( waitforKey() );
8
  }
9
}

Du musst dir angewöhnen, dass ein komplettes Projekt darin besteht, dass 
man sich von einem Zwischenziel zum nächsten hangelt, wobei jedes der 
Zwischenziele getestet werden muss!

Anfänger arbeiten gerne nach dem Muster: Ich programmiere erst mal 
trocken alles runter, so wie ich denke das es funktionieren sollte.
Das Ergebnis ist dann: Sie stehen mit einem Haufen Code da, der 
natürlich nicht funktioniert und wissen nicht, wo sie mit der 
Fehlersuche anfangen sollen. Denn natürlich ist keine einzige der 
Teilkomponenten jemals für sich getestet worden. Im Regelfall sind 
solche Programme dann voll mit Fehlern, wobei man als Helfer nicht weiß 
wo man mit den Korrekturen anfangen soll. Da wird dann auf Teufel komm 
raus an einzelnen Stellen 'korrigiert' anstatt das einzig sinnvolle zu 
tun: Das Programm beiseite zu legen und ein neues anzufangen. In das 
neue Programm dann nach und nach die Einzelteile des Originalprogramms 
übernehmen auch wenn man sie kurzfristig etwas verändern muss um sie 
lauffähig zu bekommen. Aber diesmal: Jede einzelne Komponente die neu 
übernommen wird, wird auf Herz und Nieren getestet!

Und das nächste mal arbeitest du gleich so
(und achtest auch darauf, dass dein Code sauber aussieht. Formatierung 
und eine halbwegs übersichtliche optische Aufteilung sind kein 
Selbstzweck sondern vitale und wichtige Hilfsmittel im Kampf gegen 
Fehler. Gerade wenn man im Zeitdruck ist, nimmt ein übersichtliches 
Programm schon mal einen erklecklichen Anteil des Drucks aus dem Projekt 
heraus. Alleine das Gefühl, die Übersicht zu behalten ist schon die 
halbe Miete)


Und ja:
Auch Profis arbeiten in Schritten. Nur sind bei ihnen die Teilschritte 
umfangreicher. Das ist aber letztendlich nur eine Frage der Übung.
Profis fangen meistens damit an, sich Gedanken über die Teilschritte zu 
machen, die Reihenfolge wie man die Teilschritte abarbeitet, so dass die 
Teile aufeinander aufbauen und auch wie man jeden Schritt testen kann. 
Es ist nicht ungewöhnlich, dass man in den frühen Phasen eines Projekts 
viel Zeit in Testcode steckt, der im Endprodukt nicht mehr auftaucht.
Letztenendes kostet das aber keine Zeit. Die Zeit die man in das Testen 
der Einzelkomponenten investiert, bekommt man gegen Projektende 
hundertfach zurück.

Das ist bei Profis nicht anders als bei dir.

von Karl H. (kbuchegg)


Lesenswert?

Denis G. schrieb:
> gut aber im simulator klappt das nicht mit taste drücken

Doch. Das klappt dort genauso.
Eventuell musst du berücksichtigen, dass der Simulator wesentlich 
längsamer arbeitet als die reale Hardware. Aber grundsätzlich 
funktioniert das schon.

von krishna (Gast)


Lesenswert?

Wenn deine Tastenroutine dann läuft (scheint sie ja, sonst gäbe es eine 
Rückmeldung :-) , kannst Du hier nochmal gucken:

>in der fh war es so das wenn ich eine Taste gedrückt
hatte  das ein muster kam jedoch hat es sich danach aufgehängt

Dabei inbesondere noch mal das "while(1);" in deiner main() ins Visir 
nehmen.. und ein wenig drüber nachdenken.

von Denis G. (vlplayer)


Lesenswert?

kann vielleicht mal jemand das prog ins seinen controller reinhauen und 
gucken obs klappt?

von Karl H. (kbuchegg)


Lesenswert?

Wie simulierst du?

Im AVR-Simulator kannst du Änderungen an den I/O Registern nur dann 
vornehmen, wenn der Debugger das Programm unterbrochen hat (zumindest 
war das mal so). Setz dir also einen Haltepunkt auf das Einlesen des PIN 
Registers. Ist das Programm dort, dann ändere mit der Maus das 
entsprechende I/O Register und geh mit F10 einen Schritt weiter und sieh 
dir an, was das Programm nacht.
Und bedenke auch: Jedesmal wenn du im Simulator einen F10 machst, hat 
dein realer Benutzer auch die Möglichkeit die Taste just in diesem 
Moment zu drücken oder loszulassen.
Es ist daher nicht unbedingt verkehrt, die Manipulation am I/O Register 
nicht unbedingt bei der Abfrage des PIN Registers zu machen, sondern 
irgendwann davor oder danach um zu sehen, ob das Programm richtig 
reagiert. Es ist auch nicht verkehrt, daran zu denken, dass aus 
Programmsicht der Benutzer schnarchlangsam ist. So eine Abfrageschleife, 
wie du sie hast, dauert in der Realität hundert Millisekunden (aber auch 
nur wegen dem delay). Kein Mensch kann so schnell eine Taste drücken und 
wieder loslassen. Dein Programm wird daher diese Schleife ein paar mal 
abarbeiten. Auch das solltest du in Einzelschritten simulieren um zu 
sehen, ob deine Gedankengänge richtig sind.

von Denis G. (vlplayer)


Lesenswert?

also
sobald ich mein prog so starte
mit dieser main
int main()
{
  initport();


  putSelPattern(getKeyNum (waitforKey()));

  //while(1);
  return 0;

}

wird nicht mal meine ports initialisiert!!

wenn ich

int main()
{
  initport();
         putSelPattern(getKeyNum (0x04));

  //while(1);
  return 0;

}

klappts

komisch?!

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Bau das ganze doch mal in Natura auf.
Ich kann mir nicht vorstellen, dass eine Einrückung im Quelltext die 
Initialisierung der Ports durcheinander bringt.

von Nick M. (Gast)


Lesenswert?

Was ist das für Lehrfach? Ballistische Programmierung?


Gruß,
Nick

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Naja, sehe ich gerade, Du hast ja beim zweiten Mal noch waitForKey durch 
0x04 ersetzt - trotzdem.

Mir scheint, dass entweder Dein Simulator Murx ist, oder Du ihn nicht 
bedienen kannst.

Was sagt Dir, dass die Initialisierung nicht ausgeführt wird?

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Nick Müller schrieb:
> Was ist das für Lehrfach? Ballistische Programmierung?
Stochern im Nebel.

von Karl H. (kbuchegg)


Lesenswert?

> sobald ich mein prog so starte

Wie startest du?
F5, also Run?

Da siehst du nicht viel.

Bei den ersten paar mal geht man das Programm mit F10 bzw. F11 durch.
(Siehe die Menüpunkte im Debug Menü vom AVR-Studio)

von Nick M. (Gast)


Lesenswert?

Christian H. schrieb:
> Stochern im Nebel.

Das ist die Parallelvorlesung "Fehler-orakeln". :-)

Zerleg doch mal dein Programm und bring die Teile Schritt *für* 
Schritt zum laufen.

Hat doch keinen Sinn unsystematisch in der kompletten Code-Suppe 
rumzustochern.


Gruß,
Nick

von Klaus W. (mfgkw)


Lesenswert?

Der Tipp kam hier schon öfter; klarer Fall von Beratungsresistenz.

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Der Tipp kam hier schon öfter; klarer Fall von Beratungsresistenz.

Eher klarer Fall von:
Ich will einfach nicht wahr haben, dass so etwas vermeintlich Simples 
nicht in einem Zug gemacht werden kann und mein derzeitiges Verständnis 
überfordert.
Irgendwann lernt es jeder, dass Programmieren in der Realität nicht so 
einfach ist, wie einem Film und Fernsehen das immer wieder suggerieren.

von Denis G. (vlplayer)


Lesenswert?

doch es klappt jetzt nur immoment ist er bei meiner waitforKey funktion 
und ich hab ein breakpoint gesetzt um dann ein bit zuschalten .... aber 
er springt dann immer

 while(PIND!=0xff)
    {
      Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
      _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
    }

hier hin und her

von Naja (Gast)


Lesenswert?

Das erinnert mich an die Geschichte mit der Milliarde Affen, von denen 
dann einer in einer Million Jahren mal ein Meisterwerk verfasst. Woher 
bekomme ich nun für eine Million Jahre Popcorn?

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Denis G. schrieb:
> doch es klappt jetzt nur immoment ist er bei meiner waitforKey funktion
> und ich hab ein breakpoint gesetzt um dann ein bit zuschalten .... aber
> er springt dann immer
>
>  while(PIND!=0xff)
>     {
>       Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
>       _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
>     }
>
> hier hin und her

Wo springt er hin und her?
Wo hast Du den Breakpoint gesetzt?

Hast Du diesen Tip nicht gelesen? 
Beitrag "Re: Hilfe bei Parallel-IO dringend (AVR)"
Wenn ja, warum hältst Du immer noch an Deinem Code fest?

von Karl H. (kbuchegg)


Lesenswert?

Denis G. schrieb:
> doch es klappt jetzt nur immoment ist er bei meiner waitforKey funktion
> und ich hab ein breakpoint gesetzt um dann ein bit zuschalten .... aber
> er springt dann immer
>
>  while(PIND!=0xff)
>     {
>       Key = ~PIND;  // wartet bis alle Tasten wieder losgelassen sind
>       _delay_ms(100);    // Prellzeit der Taste abwarten: 100ms warten
>     }
>
> hier hin und her

Da hier darauf gewartet wird, bis die Taste wieder losgelassen wird, 
musst du das im Simulator natürlich auch tun. Im I/O Fenster das 
Loslassen der Taste simulieren, indem du das Bit am PIND wieder 
wegschaltest. Denn genau darauf wartet ja

    while( PIND != 0xFF )

Da gehts nur dann wieder raus, wenn in PIND wieder alle simulierten 
Eingänge ein Häkchen haben (gefüllt sind).

Du musst beim Simulieren schon auch ein wenig nachdenken, was du dem 
Simulator vorgaukeln musst um deine Hardware zu simulieren.

Wenn dein Programm also davon ausgeht, dass "alle Bits in PIND" gesetzt 
bedeutet "kein Taster gedrückt", dann musst du diesen Zustand auch 
herstellen, indem du bei Programmstart erst mal in alle PIND Bits eine 1 
reinmachst.

PS: Deine Tasten sind offensichtlich Low-Aktiv.
Das heißt: Der Grundzustand ist: Das entsprechende Bit im PIND ist high 
(im Simulator: es ist gefüllt).
Der Simulator kann das nicht wissen, also musst DU diesen Zustand 
herstellen und die nicht gedrückten Tasten durch entsprechende High-Bits 
im PIND einstellen. Ein simulierter Tastendruck besteht dann darin, dass 
du die Füllung am entsprechenden Bit rausmachst und das Loslassen der 
Taste ist das Bit wieder zu füllen.

Wie gesagt. Ein bischen mitdenken muss man schon auch.

von gchglaubsjanicht (Gast)


Lesenswert?

.... Du kannst noch so lange an deinem Code herumdebuggen, richtiger 
wird er davon nicht.

Oben steht doch eine Lösung, die musst du nur rauskopieren...Hergott 
nochmal.
Es wäre sinnvoller die Lösung von oben zu debuggen - um sie zu 
verstehen.

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.