Forum: Mikrocontroller und Digitale Elektronik Attiny45 bug


von Daniel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich stehe noch ganz am Anfang mit der AVR-Programmierung in C; 
vielleicht könnt ihr mir bei einem Problem helfen...

Ich habe dieses Programm für einen Attiny45 geschrieben, um erstmals 
Interrupts auszuprobieren.

Falls mithilfe eines Tasters Pin 5 auf 0V gezogen wird, soll die an Pin 
6 anliegende Led für 1/2 Sek aussetzen. Den Reset Pin habe ich übrigens 
mit Vcc verbunden.
Leider tut sich - nichts. Also gar nichts, die Led leuchtet nicht, 
Drücken des Tasters ändert auch nichts.

Dass ein Programm nicht gleich funktioniert, ist ja normal, aber ich 
weiß nicht, wo ich beim Debuggen ansetzen soll, da mir keine Fehler beim 
Kompilieren angezeigt werden.

Wäre super, wenn mir jmd. meine Fehler nennen könnte :D

von Einer K. (Gast)


Lesenswert?

PCINT0 != INT0

von Daniel (Gast)


Lesenswert?

Hm, kurz und knackig, aber etwas mehr Info wäre nett. Das Bit heißt doch 
"INT0"?

von Daniel (Gast)


Lesenswert?

Oder anders: könnte ich die Zeile auch so schreiben?

GIMSK |= (1 << 6);

von Einer K. (Gast)


Lesenswert?

Daniel schrieb:
> Hm, kurz und knackig, aber etwas mehr Info wäre nett. Das Bit
> heißt doch
> "INT0"?

Wenn das Bit "INT0" heißen soll, dann möchte die ISR bestimmt 
"INT0_vect" genannt werden.

von Daniel (Gast)


Lesenswert?

Ah, da fällt der Groschen bei mir. Doch warum leuchtet die Led erst gar 
nicht? eigentlich ist doch Pin 6 als Ausgang und High geschaltet?

von Peter II (Gast)


Lesenswert?

Daniel schrieb:
> Ah, da fällt der Groschen bei mir. Doch warum leuchtet die Led erst gar
> nicht? eigentlich ist doch Pin 6 als Ausgang und High geschaltet?

wie ist die LED angeschossen? gegen GND oder VCC?

von holger (Gast)


Lesenswert?

>wie ist die LED angeschossen? gegen GND oder VCC?

Oder verkehrt herum:)

von Einer K. (Gast)


Lesenswert?

Daniel schrieb:
> Doch warum leuchtet die Led erst gar
> nicht? eigentlich ist doch Pin 6 als Ausgang und High geschaltet?

Meine telepathischen Fähigkeiten sind leider noch nicht so weit 
entwickelt, dass ich diese Frage beantworten könnte.

Bis dahin würde ich dir empfehlen:
1. Den für dieses Problem unrelevanten Code löschen
2. Schaltplan prüfen
3. Messen

von Daniel (Gast)


Lesenswert?

holger schrieb:
> Oder verkehrt herum:)

Nenene, soweit war ich schon XD

Gut, wenn ihr meint, der Code hat soweit keine bösen Fehler, probier ich 
halt noch ein bisschen rum...

was könnte ich denn noch löschen, so groß ist das Programm doch nun 
nicht?

von Einer K. (Gast)


Lesenswert?

Daniel schrieb:
> was könnte ich denn noch löschen, so groß ist das Programm doch nun
> nicht?

Sach mal.....

OK, ich machs mal für dich:
1
 
2
#define F_CPU 1000000
3
4
#include <avr/io.h>
5
 
6
7
8
9
int main(void)
10
{
11
  
12
  DDRB |= (1 << 1);
13
  PORTB = 0xFF;
14
   
15
    while (1) ;
16
    return 0;
17
}

Das dürfte der optimale Testcode, für dein "LED leuchtet nicht Problem" 
sein.

von (prx) A. K. (prx)


Lesenswert?

Daniel schrieb:
> Gut, wenn ihr meint, der Code hat soweit keine bösen Fehler,

Wenn es der oben gepostete Code ist: der hat. Wenn es ein mittlerweile 
geänderter Code ist: den kennt niemand.

von Einer K. (Gast)


Lesenswert?

Arduino F. schrieb:
> #define F_CPU 1000000
Mein Fehler!

Besser:
#define F_CPU 1000000L
(tut der LED aber nicht weh!)

von Daniel (Gast)


Lesenswert?

@ Arduino Fanboy:

Das Problem ist ja nicht, das ich die Led nicht generell an oder 
ausschalten kann, und auch mit _delay_ms habe ich schon experimentiert, 
hat alles geklappt.
Bolß möchte ich, bevor ich z.b. mit timern rumprobiere, erstmal 
Interrupts verstehen, deshalb diese "Übung".

von (prx) A. K. (prx)


Lesenswert?

Ich würde dir empfehlen, für die Bits in Registern die Namen zu 
verwenden, statt numerischer Positionen. Bei den GPIO-Bits ist das egal, 
die sind selbsterklärend, aber die Bits in MCUCR, GIMSK etc sind es 
nicht. Was zu Folge hat, dass man erst einmal ins Datasheet schauen 
muss, bevor man mit deinem Code überhaupt was anfangen kann. Vielen ist 
das zu blöd und ignorieren deinen Beitrag deswegen.

von (prx) A. K. (prx)


Lesenswert?

Arduino F. schrieb:
> Besser:
> #define F_CPU 1000000L

Weshalb sollte das besser sein?

von (prx) A. K. (prx)


Lesenswert?

Daniel schrieb:
> Nenene, soweit war ich schon XD

Nur weiss immer noch niemand, wie die LED dranhängt.

von Daniel (Gast)


Lesenswert?

Danke für den Hinweis, kann ich verstehen.

Ich fürchte, es wird einfach auf trial and error hinauslaufen; am besten 
beginne ich wohl mit funktionierenden Codebeispielen Anderer und 
variiere die dann. Im Moment steh ich hier nunmal auf dem Schlauch, und 
auch der verbesserte Code bringt keine Resultate. Ist wohl noch ein 
langer weg bis zur ersten ADC kontrollierten PWM.

von Daniel (Gast)


Lesenswert?

A. K. schrieb:
> Nur weiss immer noch niemand, wie die LED dranhängt.

Naja, die Anode an Pin 6, über die Kathode ist über einen Widerstand mit 
GND verbunden. Und die Led leuchtet, wenn ich an ihr manuell 5v anlege.

von Draco (Gast)


Lesenswert?

A. K. schrieb:
> Arduino F. schrieb:
>> Besser:
>> #define F_CPU 1000000L
>
> Weshalb sollte das besser sein?

In diesem Fall ist es nicht zwingend nötig, oder besser. Aber sobald mal 
irgendwann eine UART Berechnung hinzukommt, oder überhaupt eine 
Berechnung. Dann macht das L bzw UL schon einen großen Sinn.

von (prx) A. K. (prx)


Lesenswert?

Draco schrieb:
> In diesem Fall ist es nicht zwingend nötig, oder besser. Aber sobald mal
> irgendwann eine UART Berechnung hinzukommt, oder überhaupt eine
> Berechnung. Dann macht das L bzw UL schon einen großen Sinn.

Bei einem Compiler mit Integer-Grüsse 16-Bit besteht zwischen 1000000L 
und 1000000 kein Unterschied. Beides hat den gleichen Datentyp "long". 
Folglich besteht auch in einer Rechnung, die diesen Wert nutzt, kein 
Unterschied.

Anders wäre es beim Suffix UL.

: Bearbeitet durch User
von Draco (Gast)


Lesenswert?

Attiny45 != 16Bit

von (prx) A. K. (prx)


Lesenswert?

Draco schrieb:
> Attiny45 != 16Bit

Mehr als das ist es aber auch nicht und nur da wärs ein Unterschied.

Hab die Formulierung aber schon korrigiert, weil ich sicher war, dass da 
jemand rückwärts drüber stolpert ;-). Es geht um die Sicht des 
Compilers, und für den ist das ein 16-Bitter. Weniger geht per C 
Standard nicht, da die Datentypen fürs Maschinenwort int/unsigned sind 
und die sind auf mindestens 16 Bits festgelegt.

Dezimale Konstanten, die nicht in "int" passen, sind automatisch "long". 
Auch ohne Suffix.

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

Was bezweckst Du damit?

PCMSK |= (1 << 0);

(Ich frage, weil Du damit nichts erreichst ... :-) )


Dann solltest Du auch deswegen nochmal ins Datenblatt schauen:

GIMSK |= (1 << INT0);    //Pin Change Interrupt enable

Willst Du den Pin Change Interrupt aktivieren - oder wie codiert INT0?

von (prx) A. K. (prx)


Lesenswert?

Dieter F. schrieb:
> Was bezweckst Du damit?
> PCMSK |= (1 << 0);
> (Ich frage, weil Du damit nichts erreichst ... :-) )

Ist sinnvoller als
  PCMSK |= 1;
denn wenn du mal den Pin wechselst, dann ist
  PCMSK |= 1<<3;
deutlich richtiger als
  PCMSK |= 3;

Noch besser ist allerdings
  #define TASTER 0
  PCMSK |= 1<<TASTER;

: Bearbeitet durch User
von Dieter F. (Gast)


Lesenswert?

A. K. schrieb:
> Ist sinnvoller als

Nö, wenn dann schreibt man sinnvoller Weise
1
PCMSK |= (1 << PCINT0);

von (prx) A. K. (prx)


Lesenswert?

Dieter F. schrieb:
> Nö, wenn dann schreibt man sinnvoller Weise

Yep.

von Christian M. (Gast)


Lesenswert?

Hallo Daniel,

jeder Code über 10 Zeilen funktioniert NIE auf Anhieb. Bestenfalls 
gibt er falsche Resultate, mit denen Du auf den Fehler schliessen 
kannst. Sonst musst Du IMMER irgendwelche Zwischenresultate irgendwie 
ausgeben können zum Debugging.

Gruss Chregu

von Paul B. (paul_baumann)


Lesenswert?

Christian M. schrieb:
> jeder Code über 10 Zeilen funktioniert NIE auf Anhieb.

In C nicht -das ist wohl wahr.

MfG Paul

von Christian M. (Gast)


Lesenswert?

Paul B. schrieb:
> In C nicht

Hallo Paul!

Ja, aber wer programmiert schon C...

Gruss Chregu

von Paul B. (paul_baumann)


Lesenswert?

Christian M. schrieb:
> Ja, aber wer programmiert schon C...

Masochisten?
:)
MfG Paul

von *.* (Gast)


Lesenswert?

Dabei ist C kaum mehr als vereinheitlichter Assembler...

von Dieter F. (Gast)


Lesenswert?

Christian M. schrieb:
> jeder Code über 10 Zeilen funktioniert NIE auf Anhieb. Bestenfalls
> gibt er falsche Resultate, mit denen Du auf den Fehler schliessen
> kannst. Sonst musst Du IMMER irgendwelche Zwischenresultate irgendwie
> ausgeben können zum Debugging.

Na, Du musst aber echt deprimiert sein. Ich hoffe, Du programmierst 
nicht beruflich :-)

von Draco (Gast)


Lesenswert?

*.* schrieb:
> Dabei ist C kaum mehr als vereinheitlichter Assembler...

Quark, C ist bloß eine Vereinfachung für die Leute denen Basic zu schwer 
ist!

Christian M. schrieb:
> Hallo Daniel,
>
> jeder Code über 10 Zeilen funktioniert NIE auf Anhieb. Bestenfalls gibt
> er falsche Resultate, mit denen Du auf den Fehler schliessen kannst.
> Sonst musst Du IMMER irgendwelche Zwischenresultate irgendwie ausgeben
> können zum Debugging.
>
> Gruss Chregu

Ach Mensch, D weiß man nun nicht ob man Mitleid haben sollte oder ihm 
eine Umschulung zum Zeitungsboten ans Herz legt.

Wenn ich das mal so Rechne... In zehn Zeilen Code, eine Zeile für die 
Debugausgabe... Das sind dann 10% des Codes. Krass! :'D Da wären hier im 
Forum aber so einige Arbeitslos wenn das deren Chefs mitbekommen!

von Christian M. (Gast)


Lesenswert?

Draco schrieb:
> Ach Mensch

Freut mich, dass Du so gut programmieren kannst. Ich hoffe, das gibt Dir 
einen Ausgleich zu Deinen sozialen Kompetenzen!

Gruss Chregu

von Stefan F. (Gast)


Lesenswert?

>     while (1) ;
>    return 0;

Diese beiden Zeilen darfst du weglassen. Der avr-gcc fügt entsprechenden 
Maschinencode ggf. automatisch ein.

> jeder Code über 10 Zeilen funktioniert NIE auf Anhieb

Du ärmster. Ich programme jede Woche hunderte Zeilen am Stück (manchmal 
sogar über 1000, Kommetare und Leerzeichen nicht mitgezählt) und häufig 
funktionieren sie auch auf Anhieb. Bin ich jetzt bein Superheld? Sicher 
nicht, sondern einfach nur fortgeschritten, wie jeder andere es auch 
kann.

von AVR-Bastler (Gast)


Lesenswert?

@Daniel

1. Benutze in Deinem Code die Bit-Namen wie sie im Datenblatt stehen und 
nicht ... (1<<1). Dann hast Du eine größere Chancem dass jemand helfen 
will.

2. Wenn Du Deinen Code korrigiert hast, poste in erneut. Wie soll sonst 
jemand wissen, welche Fehler Du neu eingebaut hast?

3. Wenn Du einen Programmfehler suchst, teste die Programmroutine, die 
den Fehler zeigt, isoliert. D.h. wenn die LED nicht leuchtet, dann wirf 
alles raus, was nichts mit genau diesem Pin und dieser LED zu tun hat.

4. Bei einem µC gibt es neben Software-Fehlern auch die Möglichkeit von 
Hardware-Fehlern - je nachdem, was Du mit dem Ding vorher gemacht hast.
Also nimm z.B. mal einen anderen Pin. Oder einen anderen µC.

5. Es soll auch Leute gegeben haben, die hatten zwar keinen Fehler beim 
Kompilieren, haben aber die dicke Fehlermeldung beim Flashen übersehen 
und wunderten sich dann, warum ihr neuer kleiner Freund den Code nicht 
ausführt, von dem er nie gehört hat.

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.