www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430F2012 Lotto Programm (6 aus 49) Zeitmultiplexen der Ausgänge


Autor: m. S. (marek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute ich mal wider.
Sitze gerade an nem Lottoprogramm welches mir eine Zahl aus 4 ( ohne 0) 
und eine Zahl aus 9 (mit 0(außer bei 00))generieren soll. Ich hab da 
auch soweit fertig, dass wenn ich die Einzellnen 7 Segmentanzeigen 
ansteuere werden, sie auch machen was sie sollen. Ich weis nur nicht wie 
ich die beiden Anzeigen Verbinden kann das es so aussieht als ob sie 
gleichzeitig die zahl erstellen so das man denk eine Zahl aus 49 wird 
erzeugt. Ich hab da so an Multiplexen gedacht. Ich stelle aml den Code 
rein wenn jemand ne idee hat bitte was zu schreiben. Fals fragen kommen 
solten weis ich nicht wann ich die beantworten kann komme erst relatiev 
spät nach hause. Ich danke schon jetzt für eure Hilfe.

mfg
Marek

#include <msp430x20x2.h>
#include <stdlib.h>
int x, a, i, f;
int Z1, Z10;
short int start = 0; // Variable für Tastendruck
long int pause; //länge der Pause zwische den Zahlen

int genZahl(int modu){
  x = (rand()%modu); // "Zufaellige generierung von 0 bis 9  bzw. 4
  return x;
}

int Zahl(int z, int funz){
  if ( funz == 0){
    x = 10;
  }

  switch (x){
      case 0: P1OUT = 0x7E; break;
       case 1: P1OUT = 0x0C; break; // Die jeweiligen Segmenteder
       case 2: P1OUT = 0xB6; break; // Anzeige werden angesprochen
       case 3: P1OUT = 0x9E; break;
       case 4: P1OUT = 0xCC; break;
       case 5: P1OUT = 0xDA; break;
       case 6: P1OUT = 0xF8; break;
      case 7: P1OUT = 0x0E; break;
      case 8: P1OUT = 0xFE; break;
      case 9: P1OUT = 0xDE; break;
      case 10: P1OUT &= 0x00; break;
    }
  return x;
}

void delay(long int p){//Verzögerungsfunktion
  while(p > 0) {
  p--;
  }
}

int main(void){
  WDTCTL = WDTPW + WDTHOLD;  // Watchdog aus
  P1SEL &= 0x00; //I/O funktion festgelegt
  P1DIR &= 0x00; //
  P1DIR |= 0xFE; //P1.0 Eingang rest Ausgang
  P1OUT &= 0x00; //Ausgange auf 0
  P1IN &= 0x00; //Eingange auf 0
  P1REN |= 0x01; //Internen Widerstand zuschalten

  P2SEL &= 0x00; // I/O funktion festgelegt
  P2DIR &= 0x00; //

  pause = 2500; // länge der pause

  while(1){
    // Generirung der Zufallszahl und merken ob knopf gedrückt oder 
nicht
    if (P1IN & 0x01){
    start = 1;

    if(start == 1){
      while(pause < 15000){
             P2DIR |= 0x80;//P2.7 Ausgang (Zehnerstelle) Ansteuerung der 
//einen 7 Segmentanzeige
      Z10=genZahl(4);  // Z10 moduol 4 generierte Zahl
      if (Z10 == 0)f = 0; // Wenn Z10=0  wird für dei Null das Display 
//ausgeschaltet
      else f = 1;
      Zahl(Z10, f);  // Ausgabe

      //P2DIR |= 0x40; // P2.6 Ausgang (Einerstelle) Ansteuerung der 
//zweiten 7 Segmentanzeige
      //Z1=genZahl(9); // Z1 modulo 9 generierte Zahl
      //if (Z1 == 0) f = 1; //Hier wird das display bei //Null nicht 
//ausgeschaltet Problem erst bei 0 0 aber erstmal uninteresant
      //Zahl(Z1, f);      // Ausgabe

      delay(pause);// Aufruf der verzögerungs Funktion
      pause = pause + 500; // Pause verlangern
    }

      pause = 2500;   //Auf Anfangswert zurücksetzen
    start = 0;
      }
  }
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marek S. schrieb:

> und eine Zahl aus 9 (mit 0(außer bei 00))generieren soll. Ich hab da
> auch soweit fertig, dass wenn ich die Einzellnen 7 Segmentanzeigen
> ansteuere werden, sie auch machen was sie sollen. Ich weis nur nicht wie
> ich die beiden Anzeigen Verbinden kann das es so aussieht als ob sie
> gleichzeitig die zahl erstellen so das man denk eine Zahl aus 49 wird
> erzeugt. Ich hab da so an Multiplexen gedacht.

Du bist jetzt soweit, dass du ohne Timer (oder etwas gelichwertiges, 
aber auf jeden Fall ohne irgendwelche delay Funktionen) nicht mehr 
weiter kommst.
Du musst die Generierung von der Anzeige trennen.
Das wollte ich dir eigentlich beim Würfelbeispiel schon rüberschmieren, 
allerdings ist es dort nicht unbedingt ersichtlich, warum das so ist.
Hier geht es vernünftigerweise nicht mehr anders.

Also:
Schritt 1:   keine delays
Schritt 2:   Die Ansteuerung der Anzeige von irgendwelchen
             Generierfunktionen trennen

Dein Programm muss ständig das hier machen (minimum)
...

int main()
{
   ....

  while( 1 ) {

    ....

    if( zeige_Stelle_1 )
      die Pins für die eine 7_Segment einstellen

    else
      die Pins für die andere 7_Segment einstellen
    ....
  }
}

Dazu brauchst du 2 Variablen, die dir sagen welche Segmente bei der 
einen Anzeige bzw. bei der anderen aufleuchten sollen. Dadurch dass die 
Hauptschleife ständig durchläuft, wird der INhalt der beiden Variablen 
ständig auf die jeweilige 7-Segment ausgegeben.
Willst du eine anderen Wert angezeigt haben, dann weist du diesen 
Variablen ihre neue Belegung zu und die ständig laufende Ausgabe bringt 
das dann zur Anzeige.

Besser wäre allerdings, wenn man die eigentliche Übertragung auf die 
7_Segmentanzeigen in einem Timer Interrupt machen würde. Die Anzeige 
wäre dann gleichmässiger und ist nicht mehr davon abhängig, dass der 
Ausgabeteil regelmässig innerhalb der while Schleife aufgerufen wird.

Autor: m. S. (marek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann muß ich mir das morgen noch mal durch den Kopf gehen lassen wie man 
das machen kann. Hab jetzt leider keine Zeit für. Wenn ich wider was 
haben solte Problem oder Frage melde ich mich, wird bestimmt noch 
kommen. Aber danke schon mal.

mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marek S. schrieb:
> Dann muß ich mir das morgen noch mal durch den Kopf gehen lassen wie man
> das machen kann. Hab jetzt leider keine Zeit für. Wenn ich wider was
> haben solte Problem oder Frage melde ich mich, wird bestimmt noch
> kommen.

Versuchs erst mal selber anhand deiner Unterlagen, die du übers Semester 
gesammelt hast.

Autor: m. S. (marek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich hab da mal was zum laufen bekommen vielleicht interesiert es dich 
ja deswegen stelle ich das mla hir rein. Hat jetzt keine ausrollfunktion 
aber egal. Kanst ja dann sagen was du von hältzt.

mfg
#include <msp430x20x2.h>
#include <stdlib.h>
int x, f;
int Z1, Z10;
short int start = 0; // Variable für Tastendruck   
long int pause; //länge der Pause zwische den Zahlen

void delay(long int p){//Verzögerungsfunktion
  while(p > 0) {
  p--;
  }
}
      
int genZahl(int modu){  
  x = (rand()%modu); // "Zufaellige generierung von 0 bis 9  bzw. 4 
  return x;
}

int Zahl(int z, int funz){
  if ( funz == 0){
    z = 10;
  }    
  switch (z){
      case 0: P1OUT = 0x7E; break;
       case 1: P1OUT = 0x0C; break; // Die jeweiligen Segmente der 
       case 2: P1OUT = 0xB6; break; // Anzeige werden angesprochen
       case 3: P1OUT = 0x9E; break;
       case 4: P1OUT = 0xCC; break;
       case 5: P1OUT = 0xDA; break;
       case 6: P1OUT = 0xF8; break;
       case 7: P1OUT = 0x0E; break;
       case 8: P1OUT = 0xFE; break;
       case 9: P1OUT = 0xDE; break;
       case 10: P1OUT &= 0x00; break; 
    }
  return z;
}

int main(void){          
  WDTCTL = WDTPW + WDTHOLD;  // Watchdog aus 
  P1SEL &= 0x00; //I/O funktion festgelegt
  P1DIR &= 0x00; //
  P1DIR |= 0xFE; //P1.0 Eingang rest Ausgang
  P1OUT &= 0x00; //Ausgange auf 0 
  P1IN &= 0x00; //Eingange auf 0 
  P1REN |= 0x01; //Internen Widerstand zuschalten
  
  P2SEL &= 0x00; // I/O funktion festgelegt
  P2DIR &= 0x00; //
  
  while(1){
    if (P1IN & 0x01){ 
      Z10=genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4 
      Z1=genZahl(10);// Z1 modulo 10 für Zahlen von 0 - 9
       
       if ((Z10 == 0) & (Z1 == 0)){ // um 00 zu verhindern
          Z10=genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4 
       Z1=genZahl(9);// Z1 modulo 10 für Zahlen von 0 - 9  
       }
    }
    P2DIR &= 0x00;
    if (Z10 == 0)f = 0;//Wenn Z10 = 0 Display aus 
    else f = 1; 
    Zahl(Z10, f);  // Ausgabe
    P2DIR |= 0x80;  // P2.7 Ausgang (Zehnerstelle) freischalten 
    delay(200); // zur Augenfreundlicheren Darstellung
      
    P2DIR &= 0x00;
    f = 1;
    Zahl(Z1, f);      // Ausgabe  
      P2DIR |= 0x40; // P2.6 Ausgang (Einerstelle) freischalten 
    delay(200); // zur Augenfreundlicheren Darstellung         
  }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marek S. schrieb:

> Kanst ja dann sagen was du von hältzt.

Davon erst mal gar nichts:

> void delay(long int p){//Verzögerungsfunktion
>   while(p > 0) {
>   p--;
>   }
> }

jeder bessere Compiler wird dies Funktion zu einer 0-Operation 
optimieren, da sie augenscheinlich nichts Sinnvolles macht, ausser Zeit 
zu verbrauchen. Und die nobelste Aufgabe eines Optimizers ist es, für 
den Programmierer Zeitfresser zu finden und zu eliminieren.


>   while(1){
>     if (P1IN & 0x01){
>       Z10=genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4
>       Z1=genZahl(10);// Z1 modulo 10 für Zahlen von 0 - 9
>
>        if ((Z10 == 0) & (Z1 == 0)){ // um 00 zu verhindern
>           Z10=genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4
>        Z1=genZahl(9);// Z1 modulo 10 für Zahlen von 0 - 9
>        }
>     }

Was ist, wenn danach immer noch Z10 gleich 0 und Z1 gleich 0 rauskommt?
Und warum kann beim erneuten Versuch Z1 dann nicht mehr 9 sein?

In deinem Fall ist es zwar identisch, aber im allgmeinen ist es das 
nicht: & ist nicht dasselbe wie &&
& ist eine binäre UND Verknüpfung
&& ist eine logische UND Verknüpfung

Du willst hier Logikwerte (true/false), nämlich die Ergebnisse der 
Vergleiche miteinander verknüpfen. Also ist ein logisches UND, &&, 
angebracht und kein binäres.

Wenn du verhindern willst dass da 0-0 rauskommt, dann mach das doch so
    do {
      Z10 = genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4
      Z1  = genZahl(10);// Z1 modulo 10 für Zahlen von 0 - 9
    } while( (Z10 == 0) && (Z1 == 0) );

jetzt werden so lange neue Zahlen generiert, bis eine gültige 
Kombination auftaucht.

Aber eigentlich geht das noch einfacher.
Lass dir doch nicht Zehner und Einer getrennt erzeugen. Lass dir 1 Zahl 
von 1 bis 49 (inklusive) erzeugen und zerlege die dann in Zehner und 
Einer
      Zahl = genZahl(49) + 1;    // In Zahl steht jetzt eine Zahl von 1 bis 49
      Z10 = Zahl / 10;           // davon die Zehner
      Z1  = Zahl - (10*Z10);     // und die Einer

du brauchst nichts wiederholen, denn es ist durch die Generierung sicher 
gestellt, dass Z10 und Z1 gültig sein müssen und die Kombination Z10==0 
&& Z1==0 nicht auftreten kann.


Zum Thema Multiplexing.
OK, für deinen ersten Versuch nicht schlecht. Aber schön langsam wird es 
Zeit, dass du von delay Abschied nimmst und dich mit Timern beschäftigst 
und wie man mit ihnen Funktionen machen kann, die nebenher Arbeit 
verrichten, wie zb mehrere 7_Segment Anzeigen anzusteuern.

Autor: Dennis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marek S. schrieb:
> Generirung

Der ist gut :)

Autor: m. S. (marek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Und warum kann beim erneuten Versuch Z1 dann nicht mehr 9 sein?
Weil ich das übersehen habe.

Jo ich glaube ich bin jetzt so zimlich am am ende des machbaren 
angekommen was man ohne Timer machen kann.

Aber danke das du es dir angeschaut hast.
mfg

Autor: m. S. (marek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Zahl = genZahl(49) + 1;    // In Zahl steht jetzt eine Zahl von 1 bis 49
>       Z10 = Zahl / 10;           // davon die Zehner
>       Z1  = Zahl - (10*Z10);     // und die Einer

Das ist aber auch nicht ganz optimal da als einer zehner ne 0 vorkommen 
kann da wenn 1 generiert worden ist hat der Z10 = 0. Muß man halt 
abfangen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marek S. schrieb:
> Karl heinz Buchegger schrieb:
>> Zahl = genZahl(49) + 1;    // In Zahl steht jetzt eine Zahl von 1 bis 49
>>       Z10 = Zahl / 10;           // davon die Zehner
>>       Z1  = Zahl - (10*Z10);     // und die Einer
>
> Das ist aber auch nicht ganz optimal da als einer zehner ne 0 vorkommen
> kann da wenn 1 generiert worden ist hat der Z10 = 0. Muß man halt
> abfangen.

Die Argumentation versteh ich jetzt nicht (hauptsächlich weil das kein 
vernünftiger deutscher Satz ist).
Der springende Punkt ist aber: Nicht im nachhinein da großartig Dinge 
abfangen. Generiere dir die Zahlen gleich im richtigen Bereich und zwar 
als Zahl und zerleg die erst nachher in Zehner/Einer.

Oder sprichst du von führenden 0-en und deren Unterdrückung?

Autor: m. S. (marek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Oder sprichst du von führenden 0-en und deren Unterdrückung?

Jo, davon spräche ich. Wenn die rand() funktion z.B. eine eins generiert 
macht Z10 = 1/10 = 0.1 daraus. Da es sich dabei aber um einen int wert 
handelt felt ales nach dem Komma weg. So das die Ausgabe für die 
Zähnerstelle eine 0 anzeigen würde. Das hab ich aber mit na if schleife 
abgefangen.

mfg

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marek S. schrieb:
> Karl heinz Buchegger schrieb:
>> Oder sprichst du von führenden 0-en und deren Unterdrückung?
>
> Jo, davon spräche ich. Wenn die rand() funktion z.B. eine eins generiert
> macht Z10 = 1/10 = 0.1 daraus.

Nein, das macht es nicht.
Da kommt 0 raus

> Da es sich dabei aber um einen int wert
> handelt felt ales nach dem Komma weg.

Alles nach dem Komma entsteht erst gar nicht bei einer Integer Division.

> So das die Ausgabe für die
> Zähnerstelle eine 0 anzeigen würde. Das hab ich aber mit na if schleife

If ist keine Schleife.

Das Wesen einer Schleife besteht darin, dass Anweisungen wiederholt 
werden können. Deshalb heißt das Gebilde Schleife. So wie ein Tonband, 
das ewig wiederholt wird, wenn man es zu einer Schleife zusammenklebt.

Ein if ist einfach nur eine Fallunterscheidung oder eine Abfrage.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

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

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.