Hi µC.net-Community!
Ich möchte auf einem ATmega16 eine Alarmsystem-Logik in C
implementieren.
Die Anforderung ist trivial: Wenn zwei von drei Eingängen high sind, ist
ein Alarmbit zu setzen.
Dazu ist die Verknüpfung D = A ^ B v B ^ C v A ^ C in C zu realisieren.
Die Eingänge müssen per Maskierung aus dem "active low"-Eingang "PIND"
extrahiert werden.
Untenstehend sind "zwei" meiner Lösungsvorschläge präsentiert. Die
allgemeine Frage ist nun, ob das irgendwie kürzer geht? Und spezifisch
möchte ich wissen, ob "((I & B1) && (I & B2)) || ((I & B2) && (I & B3))
|| ((I & B1) && (I & B3))" vereinfacht werden kann. Die Knacknuss für
mich ist die Kombination von "bitwise"- und "boolean"-Verknüpfungen.
Ich habe auch versucht, mittels Schieben die Eingangsbits auf die
Position des Alarmbits zu bringen, womit die booleschen Operatoren
wegfallen:
1 | tmp = (((I & (1 << 3)) >> 3) & ((I & (1 << 4)) >> 4))
|
2 | | (((I & (1 << 4)) >> 4) & ((I & (1 << 5)) >> 5))
|
3 | | (((I & (1 << 3)) >> 3) & ((I & (1 << 5)) >> 5));
|
4 |
|
5 | if(tmp){
|
6 | PORTD |= ALARMRANGE;
|
7 | }else{
|
8 | PORTD &= ~ALARMRANGE;
|
9 | }
|
Da die Shifts äquivalent zu * bzw. / 2^n sind, habe ich jetzt
arithmetische und bitweise Operatoren in dem Ausdruck. Wieder weiss ich
nicht, wie ich das allgemein vereinfachen soll.
Falls es nicht kürzer geht - welche Variante würdet ihr dann bevorzugen,
und warum?
So, hier der C-Quellcode:
Die verwendeten Ports sind als initialisiert zu betrachten.
Als kürzeste Entsprechung in C habe ich Folgendes gefunden:
1 | #include <avr/io.h>
|
2 |
|
3 | #define B1 (1 << 3)
|
4 | #define B2 (1 << 4)
|
5 | #define B3 (1 << 5)
|
6 | #define ALARMRANGE (1 << 6)
|
7 |
|
8 | int main(void){
|
9 | unsigned char I = 0;
|
10 |
|
11 | for(;;){
|
12 | I = ~PIND;
|
13 |
|
14 | if (((I & B1) && (I & B2)) || ((I & B2) && (I & B3)) || ((I & B1) && (I & B3))){
|
15 | PORTD |= ALARMRANGE;
|
16 | }else{
|
17 | PORTD &= ~ALARMRANGE;
|
18 | }
|
19 | }
|
20 |
|
21 | return 0;
|
22 | }
|
Das Maskieren kann separat erfolgen:
1 | for(;;){
|
2 | I1 = ~PIND & B1;
|
3 | I2 = ~PIND & B2;
|
4 | I3 = ~PIND & B3;
|
5 |
|
6 | if ((I1 && I2) || (I2 && I3) || (I1 && I3)){
|
7 | PORTD |= ALARMRANGE;
|
8 | }else{
|
9 | PORTD &= ~ALARMRANGE;
|
10 | }
|
11 | }
|
Vielen Dank im Voraus!
Grüsse - Microwave89