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


von m. S. (marek)


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;
      }
  }
  }
}

von Karl H. (kbuchegg)


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)
1
...
2
3
int main()
4
{
5
   ....
6
7
  while( 1 ) {
8
9
    ....
10
11
    if( zeige_Stelle_1 )
12
      die Pins für die eine 7_Segment einstellen
13
14
    else
15
      die Pins für die andere 7_Segment einstellen
16
    ....
17
  }
18
}

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.

von m. S. (marek)


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

von Karl H. (kbuchegg)


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.

von m. S. (marek)


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
1
#include <msp430x20x2.h>
2
#include <stdlib.h>
3
int x, f;
4
int Z1, Z10;
5
short int start = 0; // Variable für Tastendruck   
6
long int pause; //länge der Pause zwische den Zahlen
7
8
void delay(long int p){//Verzögerungsfunktion
9
  while(p > 0) {
10
  p--;
11
  }
12
}
13
      
14
int genZahl(int modu){  
15
  x = (rand()%modu); // "Zufaellige generierung von 0 bis 9  bzw. 4 
16
  return x;
17
}
18
19
int Zahl(int z, int funz){
20
  if ( funz == 0){
21
    z = 10;
22
  }    
23
  switch (z){
24
      case 0: P1OUT = 0x7E; break;
25
       case 1: P1OUT = 0x0C; break; // Die jeweiligen Segmente der 
26
       case 2: P1OUT = 0xB6; break; // Anzeige werden angesprochen
27
       case 3: P1OUT = 0x9E; break;
28
       case 4: P1OUT = 0xCC; break;
29
       case 5: P1OUT = 0xDA; break;
30
       case 6: P1OUT = 0xF8; break;
31
       case 7: P1OUT = 0x0E; break;
32
       case 8: P1OUT = 0xFE; break;
33
       case 9: P1OUT = 0xDE; break;
34
       case 10: P1OUT &= 0x00; break; 
35
    }
36
  return z;
37
}
38
39
int main(void){          
40
  WDTCTL = WDTPW + WDTHOLD;  // Watchdog aus 
41
  P1SEL &= 0x00; //I/O funktion festgelegt
42
  P1DIR &= 0x00; //
43
  P1DIR |= 0xFE; //P1.0 Eingang rest Ausgang
44
  P1OUT &= 0x00; //Ausgange auf 0 
45
  P1IN &= 0x00; //Eingange auf 0 
46
  P1REN |= 0x01; //Internen Widerstand zuschalten
47
  
48
  P2SEL &= 0x00; // I/O funktion festgelegt
49
  P2DIR &= 0x00; //
50
  
51
  while(1){
52
    if (P1IN & 0x01){ 
53
      Z10=genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4 
54
      Z1=genZahl(10);// Z1 modulo 10 für Zahlen von 0 - 9
55
       
56
       if ((Z10 == 0) & (Z1 == 0)){ // um 00 zu verhindern
57
          Z10=genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4 
58
       Z1=genZahl(9);// Z1 modulo 10 für Zahlen von 0 - 9  
59
       }
60
    }
61
    P2DIR &= 0x00;
62
    if (Z10 == 0)f = 0;//Wenn Z10 = 0 Display aus 
63
    else f = 1; 
64
    Zahl(Z10, f);  // Ausgabe
65
    P2DIR |= 0x80;  // P2.7 Ausgang (Zehnerstelle) freischalten 
66
    delay(200); // zur Augenfreundlicheren Darstellung
67
      
68
    P2DIR &= 0x00;
69
    f = 1;
70
    Zahl(Z1, f);      // Ausgabe  
71
      P2DIR |= 0x40; // P2.6 Ausgang (Einerstelle) freischalten 
72
    delay(200); // zur Augenfreundlicheren Darstellung         
73
  }
74
}

von Karl H. (kbuchegg)


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
1
    do {
2
      Z10 = genZahl(5);// Z10 moduol 5 für Zahlen von 0 - 4
3
      Z1  = genZahl(10);// Z1 modulo 10 für Zahlen von 0 - 9
4
    } 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
1
      Zahl = genZahl(49) + 1;    // In Zahl steht jetzt eine Zahl von 1 bis 49
2
      Z10 = Zahl / 10;           // davon die Zehner
3
      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.

von Dennis (Gast)


Lesenswert?

Marek S. schrieb:
> Generirung

Der ist gut :)

von m. S. (marek)


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

von m. S. (marek)


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.

von Karl H. (kbuchegg)


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?

von m. S. (marek)


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

von Karl H. (kbuchegg)


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.

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.