Pins Schieberegister zeitlich schalten

Gast #3416517
Lesenswert?
• ▲
▼
Hallo,
ich stehe gerade ein wenig auf dem Schlauch was meinen Quellcode angeht.

Ich versuche zwei kaskadierte Schieberegister zu schalten.
In jedem Schieberegister darf jeweils nur ein Pin für eine vorher fest 
definierte Zeit eingeschaltet werden, anschließend soll eine variable 
Zeit mit ausgeschaltetem Pin gewartet werden bis das Spiel wider von 
vorne beginnt. Die beiden Register laufen "asynchron", da die Zeiten bei 
ausgeschaltetem Pin nicht gleich sein müssen.

Mein Programm läuft zwar, allerdings sieht es nach ziemlichem Murks 
aus..
Denke das es einfacher\ übersichtlicher zu gestalten wäre ?
(Den Teil der die Schieberegister behandelt habe ich für die 
Übersichtlichkeit weggelassen)
Angehängte Dateien:
#3417715
Lesenswert?
• ▲
▼
Murks schrieb:

> Mein Programm läuft zwar, allerdings sieht es nach ziemlichem Murks
> aus..

So schlimm find ich das gar nicht.

Man könnte da noch etwas mehr  Struktur reinbringen, indem man genau das 
macht: eine struct erfinden, in der alle relevanten Daten für 1 SR 
gesammelt sind.

Den Teil mit der Neuausgabe auf die SR würde ich aus der Funktion 
rausziehen, der Update Funktion einen Returnwert verpassen, so dass in 
main dann steht
1
...
2

3
  while( 1 )
4
  {
5
    needUpdate = UpdateCounter( &R1 );
6
    needUpdate |= UpdateCounter( &R2 );
7

8
    if( needUpdate )
9
    {
10
       Ausgaberegister( &R1 );
11
       Ausgaberegister( &R2 );
12
    }
13
  }


> Denke das es einfacher\ übersichtlicher zu gestalten wäre ?

Ich denke, der wesentliche Punkt ist erst mal das Zusammenfassen der für 
1 SR relevanten Informationen in eine Struktur.
Das vereinfacht dir schon mal die Haufenweise duplizierten Variablen und 
es vereinfacht dir die ganzen Funktionsschnttstellen.
1
struct SRInfo
2
{
3
  uint16_t pauseZeiten[8];
4
  uint32_t warteZeit;
5
  uint8_t  ausgaberegister;
6
  volatile bool zeitAbgelaufen;
7
  int8_t   runde;
8
  bool     pinIstAn;
9
};
10

11
struct SRInfo R1 =
12
{
13
  {1000,500,3000,500,7000,100,200,800},
14
  0, 0x00, true, 0, false
15
};
16

17
struct SRInfo R2 =
18
{
19
  {500,10,2000,500,8000,500,200,500},
20
  0, 0x00, true, 0, false
21
};

Ab dieser Stelle hast du dann alle Informationen für ein spezifisches 
Schieberegister in jeweils einer Struktur beisammen. Du kannst zb einen 
Pointer darauf an eine Funktion übergeben und die Funktion kann über 
diesen Pointer auf alle relevanten Informationen für ein spezifisches 
Schieberegister zugreifen.
1
bool updateCounter( struct SRInfo* Reg )
2
{
3
  if( Reg->zeitAbgelaufen )
4
  {
5
    Reg->zeitAbgelaufen = false;
6
    
7
    Reg->ausgaberegister = 0x00;
8
    if( !Reg->pinIstAn )
9
    {
10
      Reg->wartezeit = Millisekunde + Reg->pauseZeiten[Reg->runde];
11
    }
12
    
13
    else
14
    {
15
      Reg->ausgaberegister |= ( 1 << Reg->runde);
16
      if ( Reg->runde != 8)
17
        Reg->runde += 1;
18
      
19
      Reg->wartezeit = Millisekunde + Einschaltzeit_MS;
20
    }
21

22
    Reg->pinIstAn = !Reg->pinIstAn;
23

24
    return true;
25
  }
26

27
  return false;
28
}

Der Rest sind dann nur noch relativ naheliegende Transformationen, in 
dem du gleiche Teile aus den einzelnen if-Zweigen rausziehst, entweder 
davor oder danach. Die Sache mit der runde und dem Pin-Setzen solltest 
du nochmal überdenken, das ist unnötig kompliziert. Du musst nicht da 1 
Bit reinodern. Sobald erst mal 1 Bit gesetzt ist, genügt es dieses 1 Bit 
um 1 stelle weiter zu schieben.




Und bitte: gewöhn dir solche Dinge ab
1
  if( isIrgendwas == true )
oder
1
  if( isIregendwas == false )

mit solchen expliziten Vergleichen auf true oder false schiesst du dir 
über kurz oder lang ins eigene Knie. Du kannst das ganz einfach so 
schreiben
1
  if( isIrgendwas )
bzw
1
  if( !isIrgendwas )

wenn dein 'isIrgendwas' vernünftig benannt ist, dann liest sich das 
wunderbar. Du sagst ja im täglichen Leben auch nicht: "wenn es wahr ist, 
dass in Auto rot ist", sondern einfach nur "Wenn ein Auto rot ist"
1
  if( isRed( Auto ) == true )
versus
1
  if( isRed( Auto ) )
Der Vergleich auf true steckt schon implizit in "IsRed" drinnen. C 
verlangt an dieser Stelle keinen expliziten Vergleich. "IsRed" genügt 
völlig als Aussage, was da eigentlich abgefragt wird.
genauso die Umkehrung. '!' ist das logische nicht. D.h. in
1
  if( !isRed( Auto ) )
steht da in fast wunderbarem Englisch da. "wenn das Auto nicht rot ist". 
Passt perfekt. Es braucht kein: "Wenn es falsch ist, dass das Auto rot 
ist
1
   if( isRed( Auto ) == false )
Das ist nur von hinten durch die Brust ins Auge.
Gast #3418798
Lesenswert?
• ▲
▼
Schönen Dank Karl Heinz,
das hat mir sehr weitergeholfen.

Auf die Struck hätte ich ehrlich gesagt auch selber kommen müßen.

Auf den ersten Teil mit der neuen bool needUpdate Variable ( wenn es so 
gemeint war) habe ich erstmal verzichtet, da ich darin keinen Sinn sehe.
Verzichte nun aber auf den Reg->runde Zähler.
Was nur funktioniert wenn die Schieberegister in der updateCounter 
Methode sind weil Reg->ausgaberegister = 0x00 sonnst verhindert das daß 
Bit ( Reg->ausgaberegister <<= 1 ) weitergeschoben werden kann. Solange 
dort kein Denkfehler ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren