Forum: Mikrocontroller und Digitale Elektronik LED springt sporadisch (ATtiny13A; Anfänger)


von Patrick K. (Gast)


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.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Patrick K. schrieb:
1
} while (!(PINB & (1 << PINB1)));  // erst weiter wenn kein taster mehr

Mach danach noch ein Delay von 50ms rein, und zwar an beiden Stellen im 
Code.

> oder der Taster Sporadisch beim wieder loslassen auch schält.

Ein Taster schält nicht, er schaltet!

von Stefan F. (Gast)


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.

von Patrick K. (Gast)


Lesenswert?

Hi,

vielen Dank euch zwei. Mit der delay hat es funktioniert, und mit der 
for schleife werd ichs noch Testen.

P.S. im Schwäbischen schält der Taster ;)


nochmals Danke

von Stefan F. (Gast)


Lesenswert?

Ich habe mich vertippt: uint8_t ist zu klein, nimm uint16_t.

von Holger L. (max5v)


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.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Holger L. schrieb:
> Der Tinny13 läuft mit 1200000 MHz, nicht mit 1000000 MHz.

...1200GHz?

Ui!

von spess53 (Gast)


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

von Holger L. (max5v)


Lesenswert?

Magnus M. schrieb:
> ...1200GHz?
>
> Ui!

Ups.
Ist ne Sonderanfertigung, hat nicht jeder.

1.2 MHz und 1 MHz natürlich.

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

Ja, läuft aber trotzdem mit 1.2 MHz, da CKDIV8 gesetzt ist.

: Bearbeitet durch User
von Carl D. (jcw2)


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.

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.