mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik hilfe für neueinsteiger - timerprogramierung


Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Gemeinde,

bin nun auch dem avr´s verfallen :) (..mache grad nen e-techniker), tue 
mich aber noch ein bissel schwer mit der programierung. c/c++ 
grundkennisse sind vorhanden.

ich versuch mich am stk500 mit nem atmega 8 (4mhz ext. quartz), atmega16 
&8815 wären auch vorhanden.

ich versuche mich gerade am timer. hab dazu ein testprogramm geschrieben 
(ja ich weis sollte besser über interupts geschehen, aber ich muss 
erstmal den timer verstehen bevor ich mit interrupts beschäftige, von 
daher verzeiht mir)

nun mein problem: der counter läuft nicht so wie ich gern möchte. er 
sollte im sekundentakt auf einem lcd hochzählen. läuft aber viel zu 
schnell (so mit gefühlen 1000hz - brauch also eine sekunde für nen 
durchlauf) am lcd.


hier mein prog:
#include <avr/io.h>
#include <stdlib.h>
#include "lcd-routines.h"
 
unsigned char  z;
int s = 0;
short a = 0;


int main()
{

lcd_init(); // LCD init

TCCR0 = (1<<CS01) | (1<<CS00);  // Prescaler Timer0 auf 1024 setzn

DDRB  = 0x00;  // Port B als Ausgang setzen


do{
  do{
    
    do{
    z = TIFR;  // Timer Counter Register auslesen
    z = z & 0x01; // Timer Interupt Flag (TOV0) mit Logisch 1 vergleichen 
    }

    while (z == 0); // Schleife solange wie TOV0 nicht gesetzt (Logisch 0)

  s=s+1; // "s" um 1 erhöhen 
  TIFR = (0<<TOV0); // Timer Interupt Flag (TOV0) zurücksetzen
  }
  while (s<15); // Schleife solange wie "s" < 15 (4Mhz/256/1024/15 sollte rund 1 Hz sein)

s=0;  // Schleifenzähler "s" zurücksetzen
a=a+1; // Zähler für LCD Ausgabe um 1 erhöhen

  {
  char b[5]; // b definieren
    itoa( a, b, 10 ); // übergabe int a >> char b
  set_cursor (0,1); // cursor pos setzen
  lcd_string( b ); // Anzeige b
   }
}   
while (a<1000); // bei LCD Anzeige 1000 beenden

return 0;
}



ich hab alles schön mit "remarks" meiner gedankengänge gefüllt. helft 
mir bitte meine "irrungen" zu finden.

grüsse swen

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

> TIFR = (0<<TOV0); // Timer Interupt Flag (TOV0) zurücksetzen

...Alternatively,TOV0 is cleared by writing a logic one to the flag.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Interrupt Flags werden anders zurückgesetzt

Nicht
  TIFR = (0<<TOV0); // Timer Interupt Flag (TOV0) zurücksetzen

sondern
  TIFR = (1<<TOV0); // Timer Interupt Flag (TOV0) zurücksetzen

(Ja das stimmt. Man schreibt eine 1 an die Position, an der man das Flag 
zurückgesetzt haben will)

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke!,

das hätt ich wissen müssen, habs beim hier angebotenen tutorial 
gelesen..

-> achja wobei natürlich das "TOV0" nen overflow flag ist und kein 
interupt flag (tut aber programmtechnisch nix zu sache..) mein fehler :(

jetzt läuft wesentlich langsamer aber immer noch so mit 15hz zählrate.

hab ich da ne falsche vorstellung von der teilung des zählers?

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>jetzt läuft wesentlich langsamer aber immer noch so mit 15hz zählrate.


Ein 8-Bit-Timer hat bei 4MHz und Vorteiler 1024 eine Overflowtime von 
ca.65ms. Und 1/65ms macht ca. 15Hz.

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> Ein 8-Bit-Timer hat bei 4MHz und Vorteiler 1024 eine Overflowtime von
> ca.65ms. Und 1/65ms macht ca. 15Hz.


genau deswegen mache ich ja ne schleife mit 15 counts bevor am lcd 
höchgezählt wird.

[c]
while (s<15); // Schleife solange wie "s" < 15 (4Mhz/256/1024/15 sollte 
rund 1 Hz sein)
/[c]

hab trozdem keine 1Hz.

hab mal probehalber die schleife auf 250 gesetzt. ha sind ungefähr 1hz 
zählrate. mir ist das so wichtig weil ich einen frequenzzähler basteln 
möchte

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachmal ins Datenblatt:

Das hier
TCCR0 = (1<<CS01) | (1<<CS00);  // Prescaler Timer0 auf 1024 setzn

ist kein Vorteiler von 1024

(Und tu dir selbst einen Gefallen und sorg für ein sauberes 
Erscheinungsbild deines Codes. Du schiesst dich nur ins eigene Knie, 
wenn du es nicht tust. Einrückungen sollen konsistent sein. AUs 2 Meter 
Entfernnung soll erkennbar sein, welche Codeteile zusammen gehören und 
welche nicht. Viele Leerzeilen hintereinander ziehen den Code nur in die 
Länge, erhöhen aber nicht die Übersicht)

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke Karl heinz,

ich hatte wirklich vorher ins datenblatt geschaut (seite 72). hab mich 
wohl in der zeile vertan, selbst beim kontrollieren. nun läufts prima!

mfg swen

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> (Und tu dir selbst einen Gefallen und sorg für ein sauberes
> Erscheinungsbild deines Codes. Du schiesst dich nur ins eigene Knie,
> wenn du es nicht tust. Einrückungen sollen konsistent sein. AUs 2 Meter
> Entfernnung soll erkennbar sein, welche Codeteile zusammen gehören und
> welche nicht. Viele Leerzeilen hintereinander ziehen den Code nur in die
> Länge, erhöhen aber nicht die Übersicht)


jo werd ich ab jetzt machen. asche auf mein haupt

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du sollst auch den 'natürlichen' Schleifentyp für eine Aufgabe benutzen. 
Wenn du Dinge abzählen willst, dann benutze eine for-Schleife. Dort hast 
du
  * Startwert
  * Endwert (und damit implizit die Anzahl der Wiederholungen)
  * den Wert um den erhöht wird
an einer Stelle beisammen und nicht quer über den ganzen Code verstreut

So könnte das zb aussehen
#include <avr/io.h>
#include <stdlib.h>
#include "lcd-routines.h"
 
uint8_t  NrTimerLoops;
uint16_t Counter = 0;

int main()
{
  DDRB  = 0x00;  // Port B als Ausgang setzen
  lcd_init();    // LCD init

  TCCR0 = (1<<CS01) | (1<<CS00);  // Prescaler Timer0 auf 64 setzn

  for( Counter = 0; Counter < 1000; Counter++ ) {

    // 15 Wiederholungen
    // 4Mhz/256/1024/15 -> 1Hz
    for( NrTimerLoops = 0; NrTimerLoops < 15; NrTimerLoops++ ) {

      while( TIFR & (1<<TOV0) )     // auf eine 1 im TOV0 Bit warten
        ;                           // -> der Timer ist übergelaufen
      TIFR = (1<<TOV0);             // Timer Interupt Flag (TOV0) zurücksetzen
    }

    {
      char b[5];                 // b definieren
      utoa( Counter, b, 10 );    // übergabe int a >> char b
      set_cursor (0,1);          // cursor pos setzen
      lcd_string( b );           // Anzeige b
    }
  }

  return 0;
}

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für die mühe karl heinz,

mit der for- schleife ist natürlich viel besser!

wobei wir natürlich

TCCR0 = (1<<CS02) | (1<<CS00);

setzen müssen sonst wird es nichts mit prescaler 1024 ;-).

ich habs gerade mal reingespielt. es hängt bei "178". werd mich dann mal 
dransetzen, muss wersmal ausser haus was erledigen gehen...

bis später

grüsse
swen

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.