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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Patrick K. (Gast)


Bewertung
0 lesenswert
nicht 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


Bewertung
1 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe mich vertippt: uint8_t ist zu klein, nimm uint16_t.

von Holger L. (max5v)


Bewertung
0 lesenswert
nicht 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


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

...1200GHz?

Ui!

von spess53 (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.