Forum: Mikrocontroller und Digitale Elektronik ATTINY 13 Weihnachtskarte LED - Fehler im Code?


von Dan. R. (dan_r)


Angehängte Dateien:

Lesenswert?

Servus zusammen,

bei der Idee eine simple Weihnachtskarte mit einer fixen LED und 6 
weiteren LED´s (jeweils 2 in einem Schaltkreis) wollte ich einen Attiny 
13 als Steuerung benutzen. Die Idee war die Karte durch einen kleinen 
Schalter zu aktivieren und durch erneutes drücken wieder auszuschalten 
um den Attiny in den Sleepmode zu versetzen. Nach dem Test bekomme ich 
jetzt allerdings starr leuchtende LED´s ohne je etwas gedrückt zu haben, 
vielleicht kann mir ja jemand helfen den Fehler zu finden oder hat einen 
alternativen Vorschlag. Betrieben soll das ganze mit einer 3V Batterie 
ohne Vorwiderstände werden.

Danke euch schonmal.

1
#include <avr/io.h>
2
#include <avr/sleep.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
6
#define F_CPU 1200000L  //1,2MHz
7
8
#define LED_DDR      DDRB
9
#define LED_PORT      PORTB
10
11
#define LED_PIN      PB4 //LED: Leuchtet immer
12
#define LED_GRP1_PIN      PB2 //LED-Gruppe 1: blinkt
13
#define LED_GRP2_PIN      PB1 //LED-Gruppe 2: blinkt
14
#define LED_GRP3_PIN      PB0 //LED-Gruppe 3: blinkt
15
#define BUTTON_INPUT_PIN    PB3 //Taster
16
17
void init_io() {
18
    //Set all pins of LED port as output
19
    LED_DDR |= (1 << LED_PIN);
20
    LED_DDR |= (1 << LED_GRP1_PIN );
21
    LED_DDR |= (1 << LED_GRP2_PIN );
22
    LED_DDR |= (1 << LED_GRP3_PIN );
23
    LED_DDR &= ~(1 << BUTTON_INPUT_PIN);
24
}
25
26
void init_interrupt() {
27
    MCUCR &= ~0x3;
28
    sei();
29
}
30
31
void free_external_interrupt() {
32
    //GICR |= (1 << INT0);
33
}
34
35
void lock_external_interrupt() {
36
    //GICR &= ~(1 << INT0);
37
}
38
39
void power_down() {
40
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
41
    sleep_mode();
42
}
43
44
// Empty interrupt routine
45
ISR(INT0_vect) {
46
}
47
48
int main(void) {
49
    init_io();
50
    init_interrupt();
51
52
    //Turn on the single LED
53
    LED_PORT |= (1 << LED_PIN);
54
55
    //Turn on LED group and wait for one second
56
    while (1) {
57
      free_external_interrupt();
58
      power_down();
59
      lock_external_interrupt();
60
61
62
      LED_PORT |= (1 << LED_GRP1_PIN);
63
      _delay_ms(1000);
64
      LED_PORT &= ~(1 << LED_GRP1_PIN);
65
66
      LED_PORT |= (1 << LED_GRP2_PIN);
67
      _delay_ms(1000);
68
      LED_PORT &= ~(1 << LED_GRP2_PIN);
69
70
      LED_PORT |= (1 << LED_GRP3_PIN);
71
      _delay_ms(1000);
72
      LED_PORT &= ~(1 << LED_GRP3_PIN);
73
    }
74
75
    return 1;
76
}

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Dan. R. schrieb:
> ohne Vorwiderstände

Das ist schon mal eine extrem schlechte Voraussetzung. Irgendwer muss 
den Strom begrenzen, die Batterie, die LED oder der arme ATTiny (wenn 
dem die Ausgänge durchlegiert sind, bleibt aber wenigstens das Licht 
an).

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Neben den Widerlingen solltest Du einen Timer statt delay nehmen und wie 
wird der Taster denn erkannt ?
Ein Taster prellt, d.h. wenn Du den nur am externen IRQ ohne 
Softwareentprellung hast gibt's viele IRQs hintereinander.
Und eine sinnvolle ISR sehe ich auch nicht ?
Du solltest in der ISR ein Flag setzen, IRQs deaktivieren, den Flag in 
einer Entprellroutine abfragen und wenn dann der Taster nochmal gedrückt 
wurde den Flag zurücksetzen und den Käfer schlafen legen.
Alles andere ist Murks !

von Dan. R. (dan_r)


Lesenswert?

Ok habe jetzt das Blinken mit nem neuen Ansatz geschafft, jetzt müsste 
ich das ganze nur so hinbekommen dass es auf Knopfdruck an bzw. ausgeht. 
Hmm das mit der Entprellung klingt logisch, hat jmd ein Beispiel 
hierfür? Wegen den Widerständen sollte es ja mit den richtigen Led´s auf 
lange Zeit klappen.
1
#include <avr/io.h>
2
3
#define F_CPU 1200000L  //1,2MHz
4
5
void init_io() {
6
    DDRB |= (1 << PB0);
7
    DDRB |= (1 << PB1);
8
    DDRB |= (1 << PB2);
9
    DDRB |= (1 << PB4);
10
    DDRB &= ~(1 << PB3);
11
}
12
13
void switch_on(int port) {
14
  PORTB &= ~(1 << port);
15
}
16
17
void switch_off(int port) {
18
    PORTB |= (1 << port);
19
}
20
21
int main(void)
22
{
23
    int n;
24
  int Leuchtzeit = 20000;
25
26
    init_io();
27
28
    switch_on(PB4);
29
30
  while(1)
31
  {
32
      switch_on(PB0);
33
      for(n=0;n<Leuchtzeit+2000;n++);
34
      switch_off(PB0);
35
36
      switch_on(PB1);
37
      for(n=0;n<Leuchtzeit+2000;n++);
38
      switch_off(PB1);
39
40
      switch_on(PB2);
41
      for(n=0;n<Leuchtzeit+2000;n++);
42
      switch_off(PB2);
43
  }
44
}

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.