Sascha712 schrieb:
> Ich hab per Dipschalter auch die möglichkeit das auf und abdimmen
> wegzulassen. Also quasi nur an und aus.
> Darum sind die Bits für den Timer dort.
Schon.
Aber was bringt dir ein
1 | while(1)
|
2 | {
|
3 | //Timer für Sekunde definieren
|
4 | TCCR1B |= 1<<WGM12 | 1<<CS11 | 1<<CS10; //Taktgeber für genau eine Sekunde
|
5 | TIMSK |= 1<<OCIE1A;
|
6 | OCR1A = 15624;
|
am ANfang der Schleife?
Die Bits verändern sich nie.
Du schaltest einzig und alleine den Vorteiler zu oder weg. Aber der Rest
bleibt immer gleich.
> Gibts irgendwo paar informationen, wie man "schön" schreibt?
Zum Beispiel das angesprochene.
Zum Beispiel, indem man sowas
> if((PINB & (1<<PINB0))&&( !(PINC & (1<<PINC1)) ))
in einem realen Programm mit Makrohilfe ein wenig aufpeppt.
1 | if( IS_CLOSED( DIMM_DIP_1 ) && IS_OPEN( DIMM_DIP_0 ) )
|
ist schon wesentlich einfacher zu lesen.
Noch einfacher ist es aber, wenn man die beiden Bits als das auffasst,
was sie sind. Beide zusammen bilden eine Zahl zwischen 0 und 3 und davon
abhängig werden dann Parameter ausgewählt. Daher ist es auch verünftig
genau das zu tun: aus den beiden Bits eine Zahl zusammenzubauen und dann
von dieser Zahl ausgehend den Brückenschlag zu den Parametern zu
schaffen, wie immer der dann auch aussieht, zb mit einem Array.
was ist leichter zu verstehen. Deine Version, oder die hier
1 | struct dimmPreset_
|
2 | {
|
3 | uint8_t dutyCycleOff;
|
4 | uint16_t dimmZeit;
|
5 | uint16_t maxDutyCycle;
|
6 | };
|
7 |
|
8 | struct dimmPreset_[] =
|
9 | {
|
10 | // PINB0 PINC1
|
11 | { 1, 0, 0 }, // 0 0 Off
|
12 | { 0, 12, 204 }, // 0 1 60%
|
13 | { 0, 12, 204 }, // 1 0 80%
|
14 | { 0, 10, 255 } // 1 1 100%
|
15 | };
|
16 |
|
17 | ....
|
18 |
|
19 | DimmLevel = 0;
|
20 | if( PINB & ( 1 << PINB0 ) )
|
21 | DimmLevel += 2;
|
22 | if( PINC & ( 1 << PINC1 ) )
|
23 | DimmLevel += 1;
|
24 |
|
25 | dutycycleoff = dimmPreset[DimmLevel].dutyCycleOff;
|
26 | dimmzeit = dimmPreset[DimmLevel].dimmZeit;
|
27 | maxdutycycle = dimmPreset[DimmLevel].maxDutyCycle;
|
28 | ....
|
welche ist kürzer? Welche ist leichter an andere Zahlenwerte anzupassen?
Welche ist leichter an andere Pinnummern anzupassen?
Anstatt PINB, PINC, PINB0, PINC1 wäre es auch vernünftig mittels #define
ein paar sprechende Namen zu definieren, so dass man die tatsächliche
Belegung nicht quer durch das ganze Programm verstreut hat, sondern am
Anfang ganz oben.
denn beispielsweise
1 | #define LED_PORT PORTD
|
2 | #define ERROR_LED PD5
|
3 |
|
4 |
|
5 | ...
|
6 |
|
7 |
|
8 | LED_PORT |= ( 1 << ERROR_LED );
|
erzählt mir im Programmtext als Leser schon wesentlich mehr als es ein
jemals könnte. Und wenn ich da noch einen Kommentar dazu mache
1 | PORTD |= ( 1 << PD5 ); // Error LED einschalten
|
dann binn ich schon fast in der besseren Variante, hab aber den Vorteil,
dass die nicht falsch sein kann ...
1 | PORTD |= ( 1 << PD6 ); // Error LED einschalten
|
weil an PD6 in Wirklichkeit gar nicht die Error LED sitzt, sondern die
Busy LED :-)
1 | #define LED_PORT PORTD
|
2 | #define ERROR_LED PD5
|
3 | #define BUSY_LED PD6
|
4 |
|
5 | ...
|
6 |
|
7 |
|
8 | LED_PORT |= ( 1 << ERROR_LED );
|
9 | LED_PORT &= ~( 1 << BUSY_LED );
|
Noch ein bischen Makro Magie darüber gestreut
1 | #define LED_PORT PORTD
|
2 | #define ERROR_LED PD5
|
3 |
|
4 | #define TURN_ON(b) LED_PORT |= ( 1 << b )
|
5 | #define TURN_OFF(b) LED_PORT &= ~( 1 << b )
|
6 |
|
7 | ...
|
8 |
|
9 |
|
10 | TURN_ON( ERROR_LED );
|
11 | TURN_OFF( BUSY_LED );
|
und dann liest sich der Programmtext schon fast wie englische Prosa,
obwohl nach all den Ersetzungen da auch nichts anderes steht als
1 | PORTD |= ( 1 << PD5 );
|
2 | PORTD &= ~( 1 << PD6 );
|
Aber die Information, die mir ein
1 | TURN_ON( ERROR_LED );
|
2 | TURN_OFF( BUSY_LED );
|
ganz automatisch beim Lesen vermittelt, ist eine ungleich höhere und
höherwertige. Hier geht es nicht mehr um Ports und Bits. Hier geht es
darum, was das Programm an dieser Stelle aus einer logischen Sicht der
Dinge macht.