ATTINY 13 Weihnachtskarte LED - Fehler im Code?

OP #3403467
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
}
Angehängte Dateien:
Gast #3403500
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 !
OP #3403564
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren