Timer0 beim 1200er in ICCtiny

Gast #51543
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);

}
Gast #51545
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
Gast #51547
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
Gast #51548
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.
Gast #51549
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
Gast #51551
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.
Gast #51552
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);

}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 23 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.