mikrocontroller.net

Forum: Analoge Elektronik und Schaltungstechnik fettes Problem mitn Timer


Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich denke ich habe das erste Programm stehen, ist es so richtig, oder
ist da noch nen dicker Denkfehler drin ??
=====================================================================
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char CountVariable  = 0;

SIGNAL (SIG_OUTPUT_COMPARE1A)
{
  CountVariable++;
}

void main(void)
{

//DDRA     = 0x07;  //Port A0-A2 als Ausgang definieren
DDRA     |= 0x01;//Port A0 als Ausgang definieren

TCCR0  =  0x7c;  //Startet Timer/Counter 0, von 0-255
TIMSK  =  0x02;  //enable Compare-Match Interrupt
TIFR  =  0x02;  //enable Compare-Match Interrupt
OCR0  =  255;  //Vergleichswert für Wert in TCNT0

while(1)    //Einleitung der Endlos-Systemschleife
{
  if(CountVariable == 121)
  {
    PORTA |= 0x01;  //LED (PORTA0) an
    CountVariable = 0;//Variable wieder auf 0
    }
    else
    {
    PORTA &= 0xFE;  //LED (PORTA0) aus
    }
        }
}
====================================================================

Bitte um Hilfe, weiß nicht weiter,
da sind zwei doofe Fehler drin:

die LED leuchtet die ganze Zeit durch und ich muss die
falsch herum anklemmen das die leuchtet...
weil der uc den scheiss port auf masse zieht und nicht auf +5V


was muss ich da dann ändern,
also das der port auf +5v gezogen wird und die LED im sekundentakt
blinkt ??


Hilfe !!!!

Autor: volatile (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Fehler ist sicher in der Zeile unsigned char CountVariable, da muss
ein volatile davor.

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh ja stimmt :)
vielen dank, aber wofür ist das volatile eigentlich genau ??

wo liegt der unterschied zwischen unsigned char und unsigned char
volatile ??

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Volatile heißt 'flüchtig' oder 'verlierbar' und wird für Variablen
benötigt die außerhalb der Funktion main, also Interrupt-Funktionen
behandelt werden.

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahso cool, danke
also immer für "Globale" Variablen die ich für Interrupt-Routinen
benötige mit volatile kennzeichnen !!??


Und wo gibt es noch fehler?
Warum wird der port auf masse gezogen und nicht gegen +5v
und warum nur einmal ??

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist denn das ?

PORTA |= 0x01;  //LED (PORTA0) an
    CountVariable = 0;//Variable wieder auf 0
    }
    else
    {
    PORTA &= 0xFE;  //LED (PORTA0) aus

am Anfang schaltest du POTRA bit 0 ein und im else-Teil alle anderen
Bits aus? Klar dass PORTA bit 0 immer an ist.

PORTA |= (1<<PA0);  // PORTA 0 ein
PORTA &= ~(1<<PA0);  // PORTA 0 aus

so wird eher 'n Schuh draus!

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal abgesehen davon dass die LED nur für max. 1 Zähler von
'CountVariable' high ist, was whrscheinlich schlecht zu sehen ist
(kenne den eingestellten Teilerfaktor nicht auswendig).

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe das Programm jetzt so abgeändert:
=======================================================================
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char volatile CountVariable  = 0, Status = 0;

SIGNAL (SIG_OUTPUT_COMPARE1A)
{
  CountVariable++;
}

void main(void)
{
//DDRA   = 0x07;  //Port A0-A2 als Ausgang definieren
DDRA   |= 0x01;//Port A0 als Ausgang definieren
TCCR0  =  0x7c;//Startet Timer/Counter 0, von 0-255
TIMSK  =  0x02;  //enable Compare-Match Interrupt
TIFR  =  0x02;  //enable Compare-Match Interrupt
OCR0  =  255;  //Vergleichswert für Wert in TCNT0

while(1)  //Einleitung der Endlos-Systemschleife
{
  if(CountVariable == 121)
  {
    if(Status == 0)
    {
      //PORTA &= 0xFE;//LED (PORTA0) aus
      PORTA &= ~(1<<PA0);// PORTA 0 aus
      Status = 1;
      }
      else
      {
        //PORTA |= 0x01;//LED (PORTA0) an
        PORTA |= (1<<PA0);// PORTA 0 ein
        Status = 0;
      }
      CountVariable = 0;//Variable wieder auf 0
    }
  }
}
=====================================================================

Aber die Led bleibt immer noch ständig an....

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du beutzt den COMPARE1A - Interrupt, Initialisierst aber TIMER0, das
geht nicht! Außerdem musst du den globalen Interrupt
SREG |= (1<<SREG_I);  // Globalen Interrupt freigeben
freigeben.

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also muss ich noch folgendes einbauen ??

SREG = 0x80;

Wo benutze ich denn COMPARE1A ?
ich dachte OCR0 gehört zu timer0

oder was muss ich da benutzen ?

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du benutz die Output-Compare-1A Interrupt-Routine. dafür wären z.B.
diese Einstellungen nötig:

TCCR1A = 0;                       // Output pins disconnected, normal
operation
TCCR1B |= _BV(WGM12)|_BV(CS11);   // Teiler /8 => 1µs, Compare-Mode 4
(CTC)
TCCR1C = 0;
OCR1A = 1000;                     // 1000µs = 1ms (Timer)
TCNT1 = 0;                        // Startinitialisierung
TIFR |= _BV(OCF1A);               // Flag löschen
TIMSK |= _BV(OCIE1A);             // output-Compare 1A - INT enabled

SREG |= _BV(SREG_I);              // Globalen Interrupt freigeben

Das gilt für einen Takt von 8 MHz.
Ich glaube, du solltest dir die Funktion der Timer im Datenblatt
nochmal genau durchlesen!

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tut mir leid,
aber habe mir schon den ganzen tag lang immer wieder das DB
reingezogen.
Ich kenn das ja schon bald auswendig, finde aber den Fehler nicht, denn
es ist das erste mal für mich, das ich mit Timern/Countern und Interrups
arbeite. und gerade beim ersten mal fällt es jeden schwer denk ich, tut
mir leid wenn ich hier nerv, aber brauche einfach jemand der mir den
scheiss erklärt... :(

Ist TCNT1 denn nicht von Timer 1 ??

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo und an welcher Stelle genau benutze ich Output-Compare-1A
Interrupt-Routine ??
was muss ich da anstelle dessen hinschreiben ?
gibt es Output-Compare-0 Interrupt-Routine ??
also für meinen TimerCounter0  ??

brauch ich irgendwas von:
TCCR1A = 0;    // Output pins disconnected, normal operation
TCCR1B |= _BV(WGM12)|_BV(CS11);// Teiler /8 => 1µs, Compare-Mode
4(CTC)
TCCR1C = 0;
OCR1A = 1000;                     // 1000µs = 1ms (Timer)
TCNT1 = 0;                        // Startinitialisierung
TIFR |= _BV(OCF1A);               // Flag löschen
TIMSK |= _BV(OCIE1A);             // output-Compare 1A - INT enabled


SREG |= _BV(SREG_I);              // Globalen Interrupt freigeben

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
  CountVariable++;
}

Das ist deine COMPARE1A-Routine. Mit meiner Initialisierung läuft das
Teil  1x pro ms (bei 8MHz Taktfrequenz) da rein, das heißt,
'CountVariable' wird jede ms um 1 erhöht.

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahso da steht die scheisse mit Compare1A ;)
Danke Sonic, bitte nicht gestresst sein !!
kann ich da nicht irgendwas pasendes für meinen counter reinschreiben
?

ich habe es aber auch mal mit deiner initialisierung probiert...
TCCR1C = 0;
kannte er nicht habs auskommentiert....
und mir gedacht, wenn countervarialbe jede ms hochgezählt wird ist 1s
um wenn countervariable bei 1000 ist und habe das in der schleife
gändert, LED leuchtet aber immer noch durch ?!?

hier programm:
=======================================================================
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char volatile CountVariable  = 0, Status = 0;
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
  CountVariable++;
}

void main(void)
{
DDRA   |= 0x01;//Port A0 als Ausgang definieren

TCCR1A = 0;    // Output pins disconnected, normal operation
TCCR1B |= _BV(WGM12)|_BV(CS11);//Teiler/8 =>1µs,Compare-Mode 4(CTC)
OCR1A = 1000;           // 1000µs = 1ms (Timer)
TCNT1 = 0;              // Startinitialisierung
TIFR |= _BV(OCF1A);     // Flag löschen
TIMSK |= _BV(OCIE1A);   // output-Compare 1A - INT enabled
SREG |= _BV(SREG_I);    // Globalen Interrupt freigeben

while(1)
{
  if(CountVariable == 999)
  {
    if(Status == 0)
    {
      PORTA &= ~(1<<PA0);// PORTA 0 aus
      Status = 1;
    }
    else
    {
      PORTA |= (1<<PA0);// PORTA 0 ein
      Status = 0;
    }
    CountVariable = 0;//Variable wieder auf 0
    }
  }
}
=======================================================================

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Sonic :) :) :) :) :) :) :) :) :) :) :) :)

Ich habs hinbekommen, ich habs ich habs JUHUUUUUUUUUUUUUUUUUUUU



DAAAAAAAAAAANNNNKE    ALTER  DANKE DANKE DANKE !!!!!!!!!!!!


ich habe einfach die scheisse von
SIGNAL (SIG_OUTPUT_COMPARE1A)

in
SIGNAL (SIG_OUTPUT_COMPARE0)


geändert,


bor voll geil ne LED die im Sekundentakt blinkt, lol


ABER EINFACH GEIL,


Du bist superspitze



DANKE DANKE DANKE !!!

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke das Du mich nicht hängen lassen hast, echt super,

jeder andere wäre schon kotzen gegangen :P

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, war grad' kotzen, aber prima dass es läuft!

Autor: dicke möpse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:P
ja genau, das musste ja jetzt sein lol !!

So ich geh nu aber pennen,
muss ja morgen früh fit für die PWM sein :)

N8 @all

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.