LED springt sporadisch (ATtiny13A; Anfänger)

Gast #4741132
Lesenswert?

Hi Leute,

vor kurzem habe ich angefangen mich mit Mikrocontroller zu beschäftigen. 
Doch jetzt komm ich einfach nicht hinter den Fehler in der Schaltung.
Benutzt wird ein ATtiny13A und mit Eclipse programmiert.

Bei der Schaltung sollte nach dem Strom anlegen ist eine Led an gehen. 
Diese soll nach einer gewissen Zeit (ca. 30s) ausgehen. Desweiteren kann 
man diese Led auch mit einem Taster seperat zu jeder Zeit Ein- und 
Ausschalten.
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
int main(void) {
5
  DDRB = 0b00000001;  // pin1 Ausgang (1<<DDB0)
6
  PORTB = 0b00000010;  // pin2 eingang (Pull-up) (1<<PB1)
7

8
  unsigned int dauer = 30;    // Automatische abschaltung in Sekunden
9
  const unsigned int milli = 1000;  // 1000milli = 1sec
10
  unsigned int zeit = dauer*milli;  // sec umrechnung
11

12
  PORTB |= (1 << PB0);  // Lampe nach start an
13

14
  while (1)
15
  {
16
    if ((PINB & (1 << PINB0))  &&  !(PINB & (1 << PINB1)))  // Lampe an && taster
17
    {
18
      PORTB &= ~(1 << PB0);  // Lampe aus
19
      _delay_ms(30);
20
      do
21
      {
22
      } while (!(PINB & (1 << PINB1)));  // erst weiter wenn kein taster mehr
23

24
    }
25
    else if ((PINB & ~(1 << PINB0))  &&  !(PINB & (1 << PINB1)))  // Lampe aus && taster
26
    {
27
      PORTB |= (1 << PB0);  // Lampe an
28
      zeit = dauer*milli;
29
      _delay_ms(30);
30
      do
31
      {
32
      } while (!(PINB & (1 << PINB1))); // erst weiter wenn kein taster mehr
33
    }
34

35
    else if (zeit == 0)    // Zeit abgelaufen
36
    {
37
      PORTB &= ~(1 << PB0);  // Lampe ausschalten nach zeitdauer
38
    }
39

40
    else  // wenn nicht gedrückt wird ausführen
41
    {
42
      if (PINB & (1 << PINB0))  // wenn die lampe an ist Zeit runterzählen
43
      {
44
        zeit--;
45
        _delay_ms(1*1.2);  // 1ms = 1,2 Korrekturwert (ohne Quarz)
46
      }
47
    }
48
  }
49
}

Das Problem bei der Schaltung ist jetzt aber das manchesmal der Taster 
nicht anspricht oder der Taster Sporadisch beim wieder loslassen auch 
schält.

Hoffentlich kann mir hier jemand sagen wo der Fehler liegt.
Gast #4741151
Lesenswert?

Die Entprell-Routinen sind fehlerhaft.
1
_delay_ms(30);
2
do
3
{
4
} 
5
while (!(PINB & (1 << PINB1))); // erst weiter wenn kein taster mehr
Nach Tastendruck wird zum Entprellen 30ms gewartet und dann wird auf das 
Loslassen der Taste gewartet. Aber beim Loslassen prellt die Taste auch, 
und das wurde hier nicht berücksichtigt. ALso wäre das die einfachste 
Lösung:
1
_delay_ms(30);
2
do
3
{
4
} 
5
while (!(PINB & (1 << PINB1))); // erst weiter wenn kein taster mehr
6
_delay_ms(30);
Etwas sauberer wäre, nicht fix 30ms zu warten, sondern zu warten, bis 
der Taster nicht mehr prellt. Das kann bei ganz billigen Tastern 
durchaus länger dauern. Vorschlag:
1
for (uint8_t i=0; i<60000; i++)
2
{
3
    // Wenn Taste noch gedrückt oder prellt, warte länger.
4
    if (!(PINB & (1 << PINB1)))
5
    {
6
        i=0;
7
    }
8
}

Der gleiche Fehler kommt an zwei Stellen vor.
#4741273
Lesenswert?

Der Tinny13 läuft mit 1200000 MHz, nicht mit 1000000 MHz. Solange an den 
Fuses nichts verändert wurde.
Also einfach mal ganz oben drüber :
#define F_CPU 1200000UL
schreiben.
Dadurch sollte auch die Fließkommaberechnung
( _delay_ms(1*1.2);  // 1ms = 1,2 Korrekturwert (ohne Quarz))
wegfallen.
Gast #4741330
Lesenswert?

Hi

>Der Tinny13 läuft mit 1200000 MHz, nicht mit 1000000 MHz. Solange an den
>Fuses nichts verändert wurde.

Lt. Datenblatt wird der ATTiny13A weder mit 12 oder 10MHz, sondern mit 
9,6MHz ausgeliefert.

MfG Spess
#4741361
Lesenswert?

Holger L. schrieb:
> Der Tinny13 läuft mit 1200000 MHz, nicht mit 1000000 MHz. Solange an den
> Fuses nichts verändert wurde.
> Also einfach mal ganz oben drüber :
> #define F_CPU 1200000UL
> schreiben.
> Dadurch sollte auch die Fließkommaberechnung
> ( _delay_ms(1*1.2);  // 1ms = 1,2 Korrekturwert (ohne Quarz))
> wegfallen.

BTW, die FP-Rechnung ist schon in der Signatur der Funktionen angelegt:
1
void _delay_ms(double __ms);
2
void _delay_us(double __us);
allerdings muß es sich bei __ms/__us um Konstanten handeln und so 
rechnet der Compiler mit FP die Anzahl zu wartenden Takte aus. Warten 
kann man natürlich nur ganze Takte, d.h. nach dem Berechnen zur 
Compile-Time braucht man keine FPs mehr.

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