Forum: Mikrocontroller und Digitale Elektronik Timer0 beim 1200er in ICCtiny


von Hilel (Gast)


Lesenswert?

Hallo zusammen.
was stimmt an dem folgenden Code nicht? Syntaxfehler sind keine
vorhanden. Das Programm wurde schon kompiliert. Ich sehe bloß keine
Änderungen an PORTD.0 und PORTD.1. Es liegt an der Interrupt-Routine.
Die Interrupt-Routine wird jede Millisekunde aufgerufen. Sie wird erst
freigegeben, wenn delay1ms() aufgerufen wird.

#include <io1200.h>
#include <macros.h>

#pragma interrupt_handler tim0Ovf:2

#define CLOCK 4000000L      // Taktfrequenz

# define SETBIT(ADRESS,BIT) (ADRESS|=(1<<BIT))
# define CLRBIT(ADRESS,BIT) (ADRESS&=~(1<<BIT))
# define CHKBIT(ADRESS,BIT) (ADRESS & (1<<BIT))

static volatile unsigned int timeout_1ms;
static void delay1ms (unsigned int n);
void initT0Int();

static void delay1ms (unsigned int n)
{
  timeout_1ms = n;
  SETBIT(TIMSK,TOIE0);        // Interrupt Timer 0 frei
  while(timeout_1ms);
  CLRBIT(TIMSK,TOIE0);        // Interrupt gesperrt
}

void tim0Ovf()
{
   TCNT0 = 240;
   if(timeout_1ms) timeout_1ms--;
}

void initT0Int()
{
  TCNT0 = 240;
  TCCR0 = 0x04;    // Vorteiler =256,  Timer 0 starten
}

void main()
{
 DDRD=0x3F;
 PORTD=0x00;

 CLRBIT(PORTD,0);
 CLRBIT(PORTD,1);

 initT0Int();       // Timer0 initilisieren
 asm("sei");      // allg. Interrupt Freigabe

 SETBIT(PORTD,0);
 delay1ms(1000);
 CLRBIT(PORTD,0);
 delay1ms(1000);

 SETBIT(PORTD,1);
 delay1ms(1000);
 CLRBIT(PORTD,1);

}

von Peter D. (peda)


Lesenswert?

Du hast die main-loop vergessen.


Peter

von Hilel (Gast)


Lesenswert?

Hallo Peter.
ICCAVR fügt while(1) automatisch am Programmende ein. Ich habe das
Programm schon mit main-loop kompiliert und es lief trotzdem nicht.
Meine Vermutung liegt beim Timer0-Interrupt. Ich habe in die ISR
tim0Ovf() den Befehl CLRBIT(PORTD,4); eingefügt. Es passiert nichts. Es
wird überhaupt nicht in die ISR gesprungen. Mit dem IAR-Compiler und
dem 8515 hat alles gut geklappt. Interrupt-Vector kann es auch nicht
sein. Würde IAR den 1200er unterstützen, würde ich es gar nicht
probieren mit dem ICCAVR.

Gruß
Hilel

von Hilel (Gast)


Lesenswert?

Hallo.
Gibt es wirklich keinen ICCtiny-Anwender hier im Forum?
Es wäre schön, wenn sich jemand melden würde.
ich danke euch.

von Ralf (Gast)


Lesenswert?

Hi,

habe zwar keine Ahnung vom ICCtiny, aber ich denke der Fehler liegt in
deiner Delay-Funktion. Du setzt am Anfang timeout_1ms gleich n und
gehst dann in eine while-Schleife. Hier solltest Du timeout_1ms aber
auch dekrementieren, sonst ist die Bedingung immer erfüllt (es sei
denn, du übergibst eine 0 an die Funktion).

static void delay1ms (unsigned int n)
{
  timeout_1ms = n;
  SETBIT(TIMSK,TOIE0);        // Interrupt Timer 0 frei
  while(timeout_1ms)
  {
     timeout_1ms--;       //z.B. so
  }



  CLRBIT(TIMSK,TOIE0);        // Interrupt gesperrt
}


Hoffe, das wars,

viele Grüße,

Ralf

von crazy horse (Gast)


Lesenswert?

nö, das wirds nicht sein, timeout wird ja in der Timer-ISR
decrementiert, irgendwann wirds 0, und dann wird die while-Schleife
auch wieder verlassen.
Warum es nicht funktioniert, sehe ich aber auch nicht, sieht korrekt
aus.
Stell doch mal das erzeugte Assemblerlisting hier rein.

von Hilel (Gast)


Lesenswert?

Hallo Ralf.
>>Du setzt am Anfang timeout_1ms gleich n und
gehst dann in eine while-Schleife. Hier solltest Du timeout_1ms aber
auch dekrementieren, sonst ist die Bedingung immer erfüllt (es sei
denn, du übergibst eine 0 an die Funktion).
>>

timeout_1ms soll eben nicht von der Routine static void delay1ms
(unsigned int n) verändert werden. Das Dekrementieren von timeout_1ms
übernimmt die ISR-Routine tim0Ovf().
void tim0Ovf()
{
   TCNT0 = 240;
   if(timeout_1ms) timeout_1ms--;
}
Immer wenn ein Interrupt von Timer0 ausgelöst wird, wird timeout_1ms
dekrementiert. Irgendwann erreicht timeout_1ms in der While-Schleife
den Wert 0 und die Routine static void delay1ms (unsigned int n)wird
bendet.
Dasselbe Programm hat ja schon mit dem AT90S8515 beim IAR-Compiler
funktioniert.
Viele Grüße
Hilel

von Hilel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen.
Ich stelle mal das erzeugte Assemblerlisting hier rein.
Gruß
Hilel

von Dirk Schnitzler (Gast)


Lesenswert?

Hi!

Ich habe zwar keine direkte Erfahrug mit AVR, aber es
sieht so aus, als ob bei dir die Compileroptimierung zuschlägt:)
Ist z.B. PortD als VOLATILE definiert?
Füge doch mal zum Testen etwas mehr Code zwischen deine Makros
ein, damit du die Optimierung überlistest...

Gruß, Dirk.

von Hilel (Gast)


Lesenswert?

Ich habe es:
1) void delay1ms(void) statt static void delay1ms(void)
2) Interruptvektor ist 3 statt 2 (2 ist eigentlich die Sprungadresse
0x0002). Im Datenblatt steht sogar eine 4, aber ich denke, das ist ein
Tippfehler von ATMEL.Es gibt beim 1200er nur 4 Interruptvektoren:
    1: RESET
    2: INT0
    3: TIMER0, OVF0
    4: ANA_COMP

#include <io1200.h>
#include <macros.h>

#define CLOCK 4000000L      // Taktfrequenz

# define SETBIT(ADRESS,BIT) (ADRESS|=(1<<BIT))
# define CLRBIT(ADRESS,BIT) (ADRESS&=~(1<<BIT))
# define CHKBIT(ADRESS,BIT) (ADRESS & (1<<BIT))

static volatile unsigned int timeout_1ms;

#pragma interrupt_handler tim0Ovf:3
void tim0Ovf()
{
   TCNT0 = 240;
   if(timeout_1ms) timeout_1ms--;
}

void delay1ms (unsigned int n)
{
  timeout_1ms = n;
  SETBIT(TIMSK,TOIE0);        // Interrupt Timer 0 frei
  while(timeout_1ms);
  CLRBIT(TIMSK,TOIE0);        // Interrupt gesperrt
}

void tim0Ovf()
{
   TCNT0 = 240;
   if(timeout_1ms) timeout_1ms--;
}

void initT0Int()
{
  TCNT0 = 240;
  TCCR0 = 0x04;    // Vorteiler =256,  Timer 0 starten
}

void main()
{
 DDRD=0x3F;
 PORTD=0x00;

 CLRBIT(PORTD,0);
 CLRBIT(PORTD,1);

 initT0Int();       // Timer0 initilisieren
 asm("sei");      // allg. Interrupt Freigabe

 SETBIT(PORTD,0);
 delay1ms(1000);
 CLRBIT(PORTD,0);
 delay1ms(1000);

 SETBIT(PORTD,1);
 delay1ms(1000);
 CLRBIT(PORTD,1);

}

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.