Forum: Mikrocontroller und Digitale Elektronik Interrupt funktioniert mit ATmega88 nicht


von Phil E. (mieper)


Angehängte Dateien:

Lesenswert?

Guten Abend :)


ich schaue mir derweil Interrupts an und wollte gleich schonmal ein 
Testprogramm schreiben. Mein µC ist ein ATmega88. Und mein Brett ist ein 
STK500 von Atmel. An PortB sind die LEDs. An PortD ist der Interrupt.

In der Main schleife leuchten auf meinem STK500 alle 8 LED's 
nacheinander auf.
Wenn ich Taster 2 betätige wird die Mainschleife unterbrochen und LED0 
fängt an zu blinken.

So nun das Problem. Es leuchten nur LED0, LED1 und LED5 auf. Die anderen 
blitzen kaum sichtbar ein paar Millisekunden auf.

Ich kann den Fehler nicht erkennen. Den Programmcode findet ihr im 
Dateianhang.
Als Vorlage habe ich einen Code aus der mikrocontrollerspielwiese 
verwendet. Und entsprechend meinem ATmega88 und STK500 angepasst.
Video welches das verhalten der LED's anzeigt:
https://dl.dropbox.com/u/50558492/Videos/verhalten.mp4


Freundliche Grüße
Phil E.

von Oliver J. (skriptkiddy)


Lesenswert?

bist du dir hiermit sicher?
1
#define led1on  PORTB |=_BV(PB0)
2
#define led1off  PORTB &= ~_BV(PB0)
3
4
#define led2on  PORTB |=_BV(PB1)
5
#define led2off  PORTB &= ~_BV(PB1)
6
7
#define led3on  PORTB |=_BV(PB2)
8
#define led3off  PORTB &= ~_BV(PB3)
9
10
#define led4on  PORTB |=_BV(PB3)
11
#define led4off  PORTB &= ~_BV(PB4)
12
13
#define led5on  PORTB |=_BV(PB4)
14
#define led5off  PORTB &= ~_BV(PB6)
15
16
#define led6on  PORTB |=_BV(PB5)
17
#define led6off  PORTB &= ~_BV(PB7)
18
19
#define led7on  PORTB |=_BV(PB6)
20
#define led7off  PORTB &= ~_BV(PB5)
21
22
#define led8on  PORTB |=_BV(PB7)
23
#define led8off  PORTB &= ~_BV(PB6)


Gruß Oliver

von Phil E. (mieper)


Lesenswert?

Hui!

Hab dem umschreiben der "Originaldatei" wohl nicht genug Aufmerksamkeit 
gewidmet. Danke für den Hinweis.

Edit:
Habe es jetzt korrigiert.
1
#define led1on  PORTB |=_BV(PB0)
2
#define led1off  PORTB &= ~_BV(PB0)
3
4
#define led2on  PORTB |=_BV(PB1)
5
#define led2off  PORTB &= ~_BV(PB1)
6
7
#define led3on  PORTB |=_BV(PB2)
8
#define led3off  PORTB &= ~_BV(PB2)
9
10
#define led4on  PORTB |=_BV(PB3)
11
#define led4off  PORTB &= ~_BV(PB3)
12
13
#define led5on  PORTB |=_BV(PB4)
14
#define led5off  PORTB &= ~_BV(PB4)
15
16
#define led6on  PORTB |=_BV(PB5)
17
#define led6off  PORTB &= ~_BV(PB5)
18
19
#define led7on  PORTB |=_BV(PB6)
20
#define led7off  PORTB &= ~_BV(PB6)
21
22
#define led8on  PORTB |=_BV(PB7)
23
#define led8off  PORTB &= ~_BV(PB7)

Es funktioniert jetzt größtenteils. Nur LED7 und LED8 leuchten noch 
nicht.

von g457 (Gast)


Lesenswert?

In deinem Header gehts leicht chaotisch zu was die Zuordnung von 
Bezeichner und IO-Pin angeht. Ist das beabsichtigt? Habs jetzt nicht 
nachgerechnet ob das zu dem Verhalten passt, so richtig straight-forward 
ist es jedenfalls nicht. Würd ich dringend mal aufräumen bevor woanders 
weitergesucht wird.

> #define F_CPU 8000000UL      // 8 MHz weniger kann Atmega88 ohne Quarz
> nicht (außer 125kHz)

In dieser Zeile sind mindestens 3 Fehler. Und wenn das Timing in Deinem 
Video richtig(tm) rüberkommt noch ein vierter vor dem Kommentar.

> MCUCR |=(0<<ISC01) | (0<<ISC00);

ISC* sind im EICRA. Macht hier aber nix, wird erst relevant wenn Du das 
INT0-Sense-Verhalten mal ändern willst.

von Phil E. (mieper)


Lesenswert?

g457 schrieb:
>> #define F_CPU 8000000UL      // 8 MHz weniger kann Atmega88 ohne Quarz
>> nicht (außer 125kHz)

Habe die Zeile mal testweise gelöscht. Jetzt ist die 1/10 Sekunde auch 
eine echte 1/10 Sekunde.

g457 schrieb:
>> MCUCR |=(0<<ISC01) | (0<<ISC00);

Habe ich vorsorgsweise auf EICRA geändert.

g457 schrieb:
> In deinem Header gehts leicht chaotisch zu was die Zuordnung von
> Bezeichner und IO-Pin angeht.
Gibt es denn eine ordentlichere und bequemere Variante alle Ports als 
Ausgang zu setzen?

von Uli T. (avaron)


Lesenswert?

Guck mal nach ob die Pins für PortB überhaupt verbunden sind mit den 
PortB Pins des Atmegas... Einige sind auf dem STK nicht wirklich 
rausgeführt da sie für andere Sachen gebraucht werden... Kann mich nur 
gerade leider nicht mehr daran erinnern welche das waren, war aber in 
meinen Anfangstagen auch eine Quelle der Verirrung....

von Max (Gast)


Lesenswert?

was bedeutet eigentlich _BV??

Ist das ne Abkürzung von

(1<< )

?

von µC-Bastler (Gast)


Lesenswert?

>   DDRB = 255; DDRD = 251;            //Aus- und Eingänge festlegen
>   PORTB |= 255;                      //Alle LED's aus

Deine Portinitialisierung ist nicht gerade besonders gut lesbar.
Warum gibst du die Werte nicht in Hex- oder Binärdarstellung an. So kann 
das doch keiner auf einen Blick zuordnen.

von Oliver J. (skriptkiddy)


Lesenswert?

/usr/lib/avr/include/avr/sfr_defs.h:
1
#define _BV(bit) (1 << (bit))

Gruß Oliver

von Phil E. (mieper)


Lesenswert?

Uli Trautenberg schrieb:
> Guck mal nach ob die Pins für PortB überhaupt verbunden sind mit den
> PortB Pins des Atmegas... Einige sind auf dem STK nicht wirklich
> rausgeführt da sie für andere Sachen gebraucht werden... Kann mich nur
> gerade leider nicht mehr daran erinnern welche das waren, war aber in
> meinen Anfangstagen auch eine Quelle der Verirrung....

Ja es funktionieren alle. Habe schon ein Programm geschrieben auf 
welchem ich alle 8 angesteuert habe.


µC-Bastler schrieb:
>>   DDRB = 255; DDRD = 251;            //Aus- und Eingänge festlegen
>>   PORTB |= 255;                      //Alle LED's aus
>
> Deine Portinitialisierung ist nicht gerade besonders gut lesbar.
> Warum gibst du die Werte nicht in Hex- oder Binärdarstellung an. So kann
> das doch keiner auf einen Blick zuordnen.

Das habe ich hierher:
http://www.sachsendreier.com/msw/projekte/ext_interrupt/ext_interrupt.html

Außerdem:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen

von Phil E. (mieper)


Lesenswert?

Phil E. schrieb:
> Uli Trautenberg schrieb:
>> Guck mal nach ob die Pins für PortB überhaupt verbunden sind mit den
>> PortB Pins des Atmegas... Einige sind auf dem STK nicht wirklich
>> rausgeführt da sie für andere Sachen gebraucht werden... Kann mich nur
>> gerade leider nicht mehr daran erinnern welche das waren, war aber in
>> meinen Anfangstagen auch eine Quelle der Verirrung....
>
> Ja es funktionieren alle. Habe schon ein Programm geschrieben auf
> welchem ich alle 8 angesteuert habe.


Gerade nochmal nachgeschaut. Das andere Programm welches alle 8 LED's 
ansteuert verwendet PortD statt PortB als Ausgang.

Edit:

Es funktionier jetzt alles. Doch eine Frage habe ich jetzt noch.
Wenn ich den Eingang für den Interrupt festlege verliert der Taster 
seine Wirkung.
Ich ersetze
1
DDRD = 251;
 durch
1
DDRD |= _BV(PD2);
aber der Taster hat dann keine Wirkung mehr.

von Phil E. (mieper)


Lesenswert?

Habe noch eine Frage.
Wenn ich
1
# define F_CPU 8000000UL
 wieder einfüge blinken die LED's im 1 Sekunden Takt. Statt im 1/10sec. 
Takt. Warum?

von g457 (Gast)


Lesenswert?

> Wenn ich
> # define F_CPU 8000000UL
> wieder einfüge blinken die LED's im 1 Sekunden Takt. Statt im 1/10sec.
> Takt. Warum?

Weil Dein Takt nicht tatsächlich 8MHz ist. Vermutlich hast Du CKDIV8 [0] 
gesetzt -> Datenplatt Kapitel 8 'System Clock and Clock Options'.

HTH

[0] ich tippe auf 0.8 Sekunden vs. 1 Sekunde

von Phil E. (mieper)


Lesenswert?

g457 schrieb:
>> Wenn ich
>> # define F_CPU 8000000UL
>> wieder einfüge blinken die LED's im 1 Sekunden Takt. Statt im 1/10sec.
>> Takt. Warum?
>
> Weil Dein Takt nicht tatsächlich 8MHz ist. Vermutlich hast Du CKDIV8 [0]
> gesetzt -> Datenplatt Kapitel 8 'System Clock and Clock Options'.
>
> HTH
>
> [0] ich tippe auf 0.8 Sekunden vs. 1 Sekunde

Daran lag es. Danke :)

von Route_66 H. (route_66)


Lesenswert?

Phil E. schrieb:
> Ich ersetzeDDRD = 251;
>
>
>
>  durchDDRD |= _BV(PD2);
>
>
>
> aber der Taster hat dann keine Wirkung mehr.

Hallo!
Damit setzt Du ja PD2 auf Ausgang(!) zur Ansteuerung eines Tasters?

von Phil E. (mieper)


Lesenswert?

Route 66 schrieb:
> Phil E. schrieb:
>> Ich ersetzeDDRD = 251;
>>
>>
>>
>>  durchDDRD |= _BV(PD2);
>>
>>
>>
>> aber der Taster hat dann keine Wirkung mehr.
>
> Hallo!
> Damit setzt Du ja PD2 auf Ausgang(!) zur Ansteuerung eines Tasters?

Ach ja.. haha :D

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.