mikrocontroller.net

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


Autor: Hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);

}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast die main-loop vergessen.


Peter

Autor: Hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hilel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen.
Ich stelle mal das erzeugte Assemblerlisting hier rein.
Gruß
Hilel

Autor: Dirk Schnitzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hilel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.