Forum: Mikrocontroller und Digitale Elektronik ATmega168 Interrupts funktionieren nicht mehr.


von Johannes L. (johannes_l37)


Lesenswert?

Guten Tag,
Das programm war dazu gedacht, um zu wissen, wie lange ein 
Eingangssignal auf `high´ liegt, überall wo ich ein PC? auf 1 setze, 
wird nur ein LED zum leuchten gebracht ( zum kontrollieren ob der Punkt 
im Programm erreicht wird.)

Wenn ich das Programm mit dem AVR Simulator durchlaufen lasse, klappts 
einwandfrei.

PS: Nicht wundern das die Main so fade aussieht, hab einiges da 
rausgenommen, ist aber unwichtig.

Main:
1
/*
2
 * main_rfid.c
3
 *
4
 *  Created on: 19.08.2011
5
 *      Author: Centro
6
 */
7
//Arduino libs nur benutzbar, wenn c++ Datei.
8
//#include "arduino/WProgram.h"
9
/* Ich muss noch die IRS entsprechend Konfigurieren, dass ich mitkriege,
10
 *  was sie zählt und die Ausgabe entsprechend einrichten
11
*/
12
#include <avr/io.h>
13
#include <avr/interrupt.h>
14
#include <string.h>
15
#include "globals.h" //momentan nur Deff. von Counter1
16
#include <stdlib.h>
17
#include <util/delay.h>
18
#include <stdio.h>
19
20
//Fuer Baudrate
21
#define FOSC 8000000UL // Clock Speed
22
#define BAUD 9600L
23
#define UBRR ((FOSC / (BAUD * 16L)) - 1)
24
//Fuer Baudrate - ende
25
26
27
void setup()
28
{
29
  cli(); // Interrupts deaktiviert - sicherheitshalber
30
31
32
//Hier will ich noch die Baudrate einstellen
33
    UBRR0H = (unsigned char)(UBRR>>8);
34
    UBRR0L = (unsigned char)UBRR;
35
    /*aktiviere Sender und empfänger (uART)*/
36
    UCSR0B = (1<<TXEN0) /*| (1 << UDRIE0)*/;
37
    // frame format: 8data, 1stop bit
38
    UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
39
//Achtung, nicht vergessen bei den Fuses
40
//CKDIV8 raus zu nehmen
41
////////////////////////////////////////////
42
//für INT0
43
44
45
46
    EICRA = 0x03; //High löst aus, bei 0x02 löst Low aus
47
    //EIFR = 0x03;
48
    EIMSK |=  (1<<ISC00); // Aktiviert den Interrupt an INT0
49
50
    TCCR1A = 0x00;
51
    TCCR0A = 0x00;  // Normal Mode
52
    TCCR0B = 0x03;//0x00 // Prescaller hier Timer/counter gestoppt
53
54
    TCNT1 = 0 ;
55
    TCNT0 = 0 ;
56
57
    TCNT0 = 0x00;   // 0..255
58
    OCR0A = 0x00;   // unwichtig da Normal Mode
59
    OCR0B = 0x00;   // unwichtig da Normal Mode
60
    TIMSK0 = 0x01;  // 0x01 = 1<<TOIE0);; Aktiviert den Zähler
61
    DDRC = 0xFF ; // Für LEDs, zum überprüfen wo ich grade bin.
62
//    DDRD = 0x04;
63
//    PORTD = (0<<PD2);
64
65
}//ende von Setup (Initalisierung)
66
67
int uart_putc(unsigned char str)
68
{
69
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
70
    {
71
    }
72
73
    UDR0 = str;                      /* sende Zeichen */
74
    return 0;
75
}
76
77
78
int main(void)
79
{
80
81
setup() ; // Initialisierung
82
83
sei();
84
  PORTC |= (1<<PC2);// LED
85
    TIMSK0 = 0x01 ;
86
   PORTC |= (1<<PC3); //LED nach 'Manueller' Interrupt aktivierung
87
88
while (1)
89
{   //Unendlichkeitsschleife ... (warten auf Interrupts? Andere Befehle?)
90
if(fertig==1)
91
  {
92
cli();
93
///////////////////////////////////////
94
//Beginne zu senden, UART
95
96
char output[80];
97
int len ;
98
99
sprintf(output ,"%d",Counter1);
100
    len = strlen(output);
101
102
for (uint8_t i=0; i<len; i++)
103
      {
104
              uart_putc ( output[i] );
105
      }
106
///////////////////////////////////////
107
fertig=0;
108
_delay_ms(1000);
109
sei();
110
  }
111
}
112
return 0; // never reached
113
114
}//ende von Main

Meine ISR:
1
/*
2
 * isr.c
3
 *
4
 *  Created on: 22.08.2011
5
 *      Author: Centro
6
 */
7
#include "globals.h"
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
11
volatile int Aufoderab=0;
12
13
ISR (TIMER0_OVF_vect)
14
{PORTC |= (1<<PC5) ; //zum überprüfen ob er die ISR betritt, leuchtet ned
15
  // F_CP U in MHz  Aufruf ca. alle                          (EDIT)
16
  // 1             2 ms                 1/(1000000 / 8 / 256)  Sekunden
17
  // 8             0,256 ms             1/(8000000 / 8 / 256)  Sekunden
18
  // 16            0,128 ms             1/(16000000 / 8 / 256) Sekunden
19
  Counter1++;
20
}//ISR Ende
21
22
ISR(INT0_vect)
23
{PORTC |= (1<<PC4) ; //zum überprüfen ob er die ISR betritt,geht niemals an
24
  if(Aufoderab==0)
25
  {
26
    TIMSK0 = 0x01;  // 0x01 = 1<<TOIE0);; Aktiviert den Zähler
27
    Aufoderab=1;
28
    EICRA = 0x02;
29
  }
30
  else
31
  {//PORTC |= (1<<PC4) ; //zum überprüfen
32
    TIMSK0 = 0x00;  // 0x01 = 1<<TOIE0);; Aktiviert den Zähler
33
    Aufoderab=0;
34
    fertig=1;
35
  //  PORTC |= (1<<PC1) ;
36
  }
37
}

X-Vars:
1
volatile uint16_t Counter1;
2
volatile char fertig;
3
volatile int Durchschnitt ;
4
volatile char Durchschnittcount ;
5
volatile uint8_t tempreg;
6
volatile uint16_t tempregsumme;
mfg, Johannes

von Johannes L. (johannes_l37)


Lesenswert?

Bitte auch schreiben wenn ihr drüber geschaut habt und keinen Fehler 
findet

von Kali (Gast)


Lesenswert?

Ich empfehle Dir etwas mehr Eigenleistung einzubringen.

Vor allem fehlt da eine Beschreibung was nun genau nicht funktioniert, 
woran Du das siehst, anhand welcher Teile des Datenblatts die davon 
ausgehest, dass es funktionieren müsste und welche Gegenmaßnahmen Du 
bisher probiert hast.

Dein Code ist nicht gerade gut lesbar. Einrückung, sonst fehlerhafte 
Formatierung und sinnlose Kommentare tun den Rest, das man sich das 
garnicht anschauen will.

von spess53 (Gast)


Lesenswert?

Hi

Was hast du denn für einen Controller?

Bei einigen Typen könnte PORTC |= (1<<PC5) durch das JTAG-Interface 
blockiert sein.

MfG Spess

von Johannes L. (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
> Was hast du denn für einen Controller?
>
> Bei einigen Typen könnte PORTC |= (1<<PC5) durch das JTAG-Interface
> blockiert sein.
>
> MfG Spess

PORTC |= (1<<PC5)
funktioniert problemlos,  ein Programier adapter heißt AVRISP mkII

Was ich schon gemacht habe um es ans laufen zu kriegen?
Jede Menge, sitze da schon den ganzen tag dran, ich habe den Code aufs 
nötigste reduziert
1
include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
int main()
6
{
7
    EICRA = 0x03; //High löst aus, bei 0x02 löst Low aus
8
    EIMSK |=  (1<<ISC00); // Aktiviert den Interrupt an INT0
9
sei();
10
while(1)
11
    {
12
     PORTC |= (1<<PC2);// LED 2
13
    }
14
}
15
16
ISR(INT0_vect)
17
{
18
     PORTC |= (1<<PC3);// LED 3
19
}

Sobald ein Interrupt angeht sollte jetz das LED 3 leuchten, tut es aber 
nicht.

Zu den 'dummen' Kommentaren, dafür entschuldige ich mich, das ist mein 
erstes Programm udn die Kommentare sidn dazu da das ich mir merken kann 
wozu was da ist :/
mfg johannes

von Chris (Gast)


Lesenswert?

Johannes L. schrieb:
> EIMSK |=  (1<<ISC00); // Aktiviert den Interrupt an INT0

ISC00 ist im EICRA Register

Grüße
Chris

von spess53 (Gast)


Lesenswert?

Hi

>EIMSK |=  (1<<ISC00);

ISC00 befindet sich in EICRA

MfG Spess

von Johannes L. (johannes_l37)


Lesenswert?

Da hab ich mich wohl verschrieben

In der AVR Simulation Funktionietr das ganze Einwandfrei, wenn ich es 
auf den Chip lade, leuchtet nur LED 4 (d.h. er geht nicht in die IRS 
rein )
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
5
6
int main(void)
7
{
8
cli(); 
9
    DDRC = 0xFF;
10
    EICRA = 0x03; 
11
    EIMSK = 0x01; 
12
sei();
13
14
15
16
while(1)
17
  {
18
  PORTC |= (1<<PC4) ;//LED_4 an.
19
  }
20
21
}
22
23
24
25
26
ISR(INT0_vect)
27
{
28
  PORTC |= (1<<PC3) ;//LED_3 an.
29
}

von Johannes L. (johannes_l37)


Lesenswert?

ps: Ich habe nun auch mit nem zweiten ATmega168 ausprobiert, bei diesem 
funktioniert es ebenfalls nicht. Ich will das ganze allerdings 
nocheinmal mit dem ATmega48 ausprobieren, mit diesem lief es ja am 
Anfang auch (ATmega 168 = ATmega48 mit mehr Speicher)

von Markus O. (pipimaxi)


Lesenswert?

Wie spess53 schon in den Raum warf:
Fehler an PORTC beruhen meistens auf JTAG.
Deaktivier mal in den FuseBits die JTAG Schnittstelle und berichte.

Defaulmäßig ist die nämlich aktiv und du hast bisher nich geschrieben, 
dass du diese deaktiviert hast.

Edit:
Kanns sein, dass der 168 gar kein JTAG Interface hat?! xD

von Johannes L. (johannes_l37)


Lesenswert?

Beitrag "JTAG bei ATmega168"
Nein kann man nicht, ich programmiere peer isp ^^
Wie gesagt, es scheint mir das das am (auch wenns ungewöhnlichklingt) 
ATmega168 liegt, mit dem ATmega48 funktionierte ja alles.
btw: Ich glaub ich habe das oben schoneinmal gesagt: Eine der beiden 
LED`s läuft ja, nur halt nicht die, die ich in der ISR anknippse :)

von Markus O. (pipimaxi)


Lesenswert?

Das lässt vermuten, dass du nicht in der ISR landest ;-)
Prüf mal in der While-Schleife ob das INTF-Bit gesetzt wird, während du 
eine rising edge an PIN PD2 machst. Lass dir das ggf. mit einer 
einschaltenden LED quittieren.

von Einhart P. (einhart)


Lesenswert?

Int0 wird über PIN B0 ausgelöst.

von Johannes L. (johannes_l37)


Lesenswert?

Einhart Pape schrieb:
> Int0 wird über PIN B0 ausgelöst.

nein, Int0 wird beim ATmega168 über PD2 ausgelöst,
Ich habe das Problem inzwischen gefunden kopf auf Tisch hau
Nachdem ich noch ein wenig mit bad_vector rumexperimentiert habe kam ich 
dann drauf ..., besser gesagt durch einen Freund, ich hatte in Eclipse 
das Projekt noch nicht auf den ATmega168 umgestellt (es stand noch auf 
ATmega48) und da der 168`ger mehr Speicher hat, sind die ISR nicht an 
der selben Speicherstellen, ergo konnte keine ISR auslösen.
Trotzdem vielen dank für eure Hilfe, ich glaube sowas passiert mir nicht 
nocheinmal

von Einhart P. (einhart)


Lesenswert?

Stimmt, ich war beim PinChange0 Interrupt :-(

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.