Hallo zusammen, habe mal eine Anfängerfrage: In einem ersten Testprogramm möchte ich eine LED an PORTB1 einschalten. Kann ich über eine define-Anweisung erreichen das ich nur schreiben brauche Z.B. #define LED1 PB1 ... DDRB = 0x0F; ... LED1 = 1; ??? Ich möchte einen anderen weg ausprobieren als PORTB |= (1<<PB1) zum Beipsiel. Ist das möglich bzw. macht das in euren Augen einen sinn?
Ingo schrieb: > Ich möchte einen anderen weg ausprobieren als PORTB |= (1<<PB1) zum > Beipsiel. Effektiv wird es immer darauf hinauslaufen müssen (und der Compiler wird daraus den passenden SBI-Befehl basteln, wenn man ihn optimieren lässt). Wenn du nun Wert auf Portierbarkeit legst, kannst du sowas schreiben:
1 | #define GLUE(a, b) a##b
|
2 | #define SET_(what, p, m) GLUE(what, p) |= (1 << (m))
|
3 | #define CLR_(what, p, m) GLUE(what, p) &= ~(1 << (m))
|
4 | #define SET(what, x) SET_(what, x)
|
5 | #define CLR(what, x) CLR_(what, x)
|
6 | |
7 | #define LED1 B, 1
|
8 | |
9 | #include <avr/io.h> |
10 | #define F_CPU 1000000UL
|
11 | #include <util/delay.h> |
12 | |
13 | void port_init(void) |
14 | {
|
15 | SET(DDR, LED1); /* enable output for LED1 */ |
16 | }
|
17 | |
18 | void flash_led1(void) |
19 | {
|
20 | SET(PORT, LED1); |
21 | _delay_ms(100); |
22 | CLR(PORT, LED1); |
23 | }
|
p.s.: Hier der daraus generierte Assemblercode für einen ATmega88:
1 | .global port_init |
2 | .type port_init, @function |
3 | port_init: |
4 | /* prologue: frame size=0 */ |
5 | /* prologue end (size=0) */ |
6 | sbi 36-0x20,1 |
7 | /* epilogue: frame size=0 */ |
8 | ret |
9 | /* epilogue end (size=1) */ |
10 | /* function port_init size 2 (1) */ |
11 | .size port_init, .-port_init |
12 | .global flash_led1 |
13 | .type flash_led1, @function |
14 | flash_led1: |
15 | /* prologue: frame size=0 */ |
16 | /* prologue end (size=0) */ |
17 | sbi 37-0x20,1 |
18 | ldi r24,lo8(25000) |
19 | ldi r25,hi8(25000) |
20 | /* #APP */ |
21 | 1: sbiw r24,1 |
22 | brne 1b |
23 | /* #NOAPP */ |
24 | cbi 37-0x20,1 |
25 | /* epilogue: frame size=0 */ |
26 | ret |
27 | /* epilogue end (size=1) */ |
28 | /* function flash_led1 size 9 (8) */ |
29 | .size flash_led1, .-flash_led1 |
Hallo, warum nicht so ?
1 | //Makros zur Bitverarbeitung
|
2 | #define SET(x,y) (x)|=(1<<(y)) //Bit set
|
3 | #define CLR(x,y) (x)&=~(1<<(y)) //Bit clear
|
4 | #define TOGGLE(x,y) (x)^=(1<<(y)) //Bit toggle
|
5 | |
6 | #define READ(x,y) (x)&(1<<(y)) //Bit read
|
7 | |
8 | //Bit setzen
|
9 | SET(DDRB,PB1); |
sondern mit glue (noch nie gehört) ??? Daniel
technikus schrieb: > warum nicht so ? Weil du dann an mehr als einer Stelle ändern musst, wenn deine LED demnächst nicht mehr an Port B sondern E klemmt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.