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
bzw
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
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
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.