www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer0 Problem atmega8


Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

Ich versuche softwaremäßig eine Frequenz an einem Port pin zu erzeugen.

Das prog:
ISR(TIMER0_OVF_vect)

{
  cli();


      time1++;
      TCNT0 = 240;
  sei();

}


void init(void)

{

  

  //Konfiguration der Outputs

  output_IO_Direction_REG |= (1<<out1);

  output_IO_Direction_REG |= (1<<out2);


  //Konfiguration Timer 0
  TCNT0 = 240
     TCCR0 = (1<<CS00);      //kein vorteiler


      TIMSK = (1<<TOIE0);  //aktiviere Timer0  overflow



  sei();

}

int main(void)

{
   while(1){


  if(time1 < gl_impulsdauer){

        output_IO_Port |= (1<<out1);

        }

  else{

        output_IO_Port &=~ (1<<out1);

        }

  if(time1 >= gl_pausendauer){

        time1 = 0;

        }
        }
}

Soweit funktioniert es auch. Setze ich aber TCNT0 = 255 scheint es als 
hätte sich der kontroller aufgehangen.

Das Selbe wenn ich den Vorteiler auf 8 stelle. sobald ich  TCNT0 auf 255 
setzte funktioniert nichts mehr.

Hat jemand eine idee?


Gruß Jörn

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso ... init(); wird natürlich in main() als erstes aufgerufen

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Interrupt-Aufruf dauert normalerweise mehr als 20 CPU-Takte. Wenn Du 
aber alle 8 oder sogar in jedem CPU-Takt einen Interrupt auslösen 
willst, ist es kein Wunder, dass nichts mehr läuft. Mich wundert, dass 
es bei 240 (also 16 Takte bis zum Überlauf) noch funktioniert (wobei ich 
vermute, dass da auch schon Interrupts verloren gehen und dadurch ein 
Jitter entsteht).

cli() und sei() haben im Interrupt Handler nichts verloren. Während der 
Abarbeitung eines Interrupts ist die Verarbeitung anderer Interrupts 
sowieso durch die Hardware gesperrt. Schau mal ins AVR-GCC-Tutorial.

Und wenn Du glaubst, dass die ganzen Leerzeilen in Deinem Code die 
Lesbarkeit erhöhen: Das Gegenteil ist der Fall. Abgesehen davon ist das 
Programm unvollständig. Es fehlt z.B. die Deklaration von time.

Wenn Du einigermaßen präzise Takte erzeugen willst, dann benutze einen 
Timer, der die CTC-Betriebsart hat (beim ATMega8 Timer 1 und 2) oder 
einen neueren AVR, bei dem auch Timer 0 das kann (z.B. ATMega88, 
pinkompatibel zum ATMega8). Timer-Preload ist v.a. bei höheren 
Frequenzen Murks, eben weil das nur mit Interrupt sinnvoll geht. CTC 
hingegen braucht keinen Interrupt und kann das Signal auch direkt 
hardwaremäßig an einem Pin ausgeben.

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm "Output Compare" um dir deine Frequenz zu erzeugen, macht das 
Hardwaremäßig, ist genau und dein uC hat kein "Stress" ;)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mätte wrote:
> Nimm "Output Compare" um dir deine Frequenz zu erzeugen, macht das
> Hardwaremäßig, ist genau und dein uC hat kein "Stress" ;)
Timer 0 beim Mega8 hat keine Compare-Einheit.

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry, hab den ATM8 übersehen, dann ist klar ;)
dann nimm halt T/C 1 oder T/C 2
wie hoch soll die Frequenz denn sein ( laut Angaben ) ?

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich möchte eine frequenz mit ca 300 hz erzeugen und dabei die 
impulsdauer zwischen 50uS und 200uS verstellen können

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dann willst du ja eine PWM machen, dafür ist OC ja genau richtig.
nimm einfach den 8 Bit Timer 2, das müsste reichen, außer du willst es 
genauer einstellen können.

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso die Frequenz soll auch variabel sein von ca. 50 Hz bis 300 Hz
Das ganze benötige ich 2 x und muss unabhängig voneinander sein...

Deshalb dachte ich es wäre in Software am einfachsten zu lösen.

Ich werde mich mal am OC versuchen

Danke schonmal für die Hilfe

Gruß Jörn

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok dann musst du halt Timer 1 und Timer 2 verwendet, gibt dann halt 2 
Unterschiedliche Routinen ab, da der eine 8 und der andere 16 Bit.
Mit dem OCR Register änderst du die Pulsdauer und mit 2^8-TCNT bzw. 
2^16-TCNT die Frequenz.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mätte wrote:
> [...] und mit 2^8-TCNT bzw. 2^16-TCNT die Frequenz.
Wie bitte? Das TCNT hat man bei PWM in Ruhe zu lassen! Bitte lies Dir 
mal im Datenblatt und/oder im Tutorial durch, wie es geht.

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das hört sich gut an
mir ist nur noch nicht ganz klar wie der timer eingestellt werden muss.
  TCCR1B = (1<<CS11);     //Vorteiler 8
  TCCR1A = (1<<COM1A1)|(1<<COM1A0)|(1<<WGM12)|(1<<WGM10);  
  TCNT1 = 10000;
  OCR1A = 1000;    //Output Compare vergleichsregister


Das sind meine einstellungen... also eine PWM
doch wie muss ich das ganze einstellen um auch die frequenz verändern zu 
können

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wie bitte? Das TCNT hat man bei PWM in Ruhe zu lassen! Bitte lies Dir
>mal im Datenblatt und/oder im Tutorial durch, wie es geht.

Du kannst die gewünschte Frequenz ja nicht mit dem Vorteiler einstellen 
bzw. nicht genau genug, also musst du den Timer vorladen um dann die 
jeweilige Frequenz zu bekommen ...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt im Datenblatt eine Tabelle, in der alle Betriebsarten des Timers 
dargestellt sind. In der Tabelle steht auch, welcher Wert die 
Periodendauer des Signals (und damit die PWM-Frequenz) definiert. Im 
Datenblatt ist das der TOP-Wert (TOP Value). Damit kannst Du die 
PWM-Frequenz (in Zusammenarbeit mit dem Prescaler) praktisch beliebig 
einstellen.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mätte wrote:
>>Wie bitte? Das TCNT hat man bei PWM in Ruhe zu lassen! Bitte lies Dir
>>mal im Datenblatt und/oder im Tutorial durch, wie es geht.
>
> Du kannst die gewünschte Frequenz ja nicht mit dem Vorteiler einstellen
> bzw. nicht genau genug, also musst du den Timer vorladen um dann die
> jeweilige Frequenz zu bekommen ...
Nö, das ist absoluter Quatsch! Gerade den Vorlade-Mist kann man sich mit 
der Hardware-PWM nämlich sparen. Noch mal: Lies es Dir im Datenblatt und 
im AVR-GCC-Tutorial durch und erzähl hier keinen Unsinn!

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> erzähl hier keinen Unsinn!
hab ja nicht behauptet, dass es die beste Variante ist, (mit Top macht 
halt alles die HW) aber funktionieren tuts.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mätte wrote:
>> erzähl hier keinen Unsinn!
> hab ja nicht behauptet, dass es die beste Variante ist, (mit Top macht
> halt alles die HW) aber funktionieren tuts.
Warum erzählst Du es überhaupt? Oben wurde schon mal auf die Probleme, 
die das Nachladen (per Interrupt) mit sich bringt, hingewiesen, und es 
ist nicht nur "nicht die beste" Variante, sondern die unsinnigste!

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
macht dem uC bei 300Hz ja nichts ...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mätte wrote:
> macht dem uC bei 300Hz ja nichts ...
Je nachdem, was das Programm sonst noch machen soll, schon. 300 unnötige 
Interrupts pro Sekunde sind u.U. zu viel. Also lass es einfach. Der µC 
hat das alles eingebaut, also sollte man das auch nutzen.

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit welchem register lege ich denn nun die Top Value fest?

Laut datenblatt ICP1  doch damit funktinoniert es nicht

Autor: Mätte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der µC hat das alles eingebaut, also sollte man das auch nutzen.
Dem stimme ich zu ;)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörn wrote:
> Mit welchem register lege ich denn nun die Top Value fest?
>
> Laut datenblatt ICP1  doch damit funktinoniert es nicht
Wenn überhaupt, dann ICR1.

Du solltest Dir auch beim Posten vielleicht ein wenig mehr Mühe geben. 
Dein Geschreibsel ist echt anstrengend zu lesen! Auch Groß- und 
Kleinschreibung sollten etwas weniger willkürlich eingesetzt werden. Und 
die Sache mit "ICP1" anstatt "ICR1" hätte sich durch etwas 
sorgfältigeres Arbeiten auch vermeiden lassen.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mätte wrote:
>>Der µC hat das alles eingebaut, also sollte man das auch nutzen.
> Dem stimme ich zu ;)
Aha. Ich dachte schon, Du wärst einer von der Sorte, die ihr Auto nur im 
ersten Gang fahren, auch wenn es fünf Gänge hat...

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja so ist das wenn man von so einem Timer in den Wahnsinn getrieben 
wird.
ICR1 hatte ich auch verwendet war nur ein Tippfehler hier im forum.

Hier nochmal meine neuen Einstellungen:
  TCCR1B = (1<<CS11)|(1<<CS10);
  TCCR1A = (1<<COM1A1)|(1<<WGM11)|(1<<WGM13);M

  OCR1A = 50;
  ICR1 = 500;

Laut Datenblatt:

PWM, Phase and Frequency Correct

TOP  =  ICR1
Update of OCR1X TOP

Mit OCR1A kann ich nun die Impulsdauer verändern.
Nur mit ICR1 kann ich immer noch nicht die Frequenz verändern.

Danke für eure mühe ;-)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörn wrote:
>
>   TCCR1A = (1<<COM1A1)|(1<<WGM11)|(1<<WGM13);M
> 
Schau bitte nochmal genau ins Datenblatt und überprüfe, in welchem 
Register WGM13 steht! ((Kleiner Tipp: Es ist nicht im TCCR1A!)) Und 
das "M" hinter dem Semikolon steht da im Original hoffentlich auch 
nicht...

Autor: Jörn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;-) Nein das M ist im Orginal nicht vorhanden.

Meine güte was ein blöder Fehler, aber nach 4 Stunden sieht man auch den 
Wald vor lauter Bäumen nicht mehr.

Bin davon ausgegangen das die Bits in der Tabelle alle zu dem einen 
Register gehören.

Jetzt funktioniert es.

Vielen Dank

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.