Forum: Compiler & IDEs LED einschalten - Code Variante


von Ingo (Gast)


Lesenswert?

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?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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

von technikus (Gast)


Lesenswert?

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

von Gast (Gast)


Lesenswert?

GLUE ist nur der Makroname, könntest auch KLEBEFIX nennen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.