Forum: Mikrocontroller und Digitale Elektronik Timer Rechenfehler?


von Philipp Karbach (Gast)


Lesenswert?

Folgende Situation:

#define F_CPU 18432000UL


void realtimeclock_setup() {
  TCCR0 |= (1<<WGM01);
  TCCR0 |= (1<<CS01) | (1<<CS00);
  OCR0 = 127;
  TIMSK |= (1<<OCIE0);
}

Es handelt sich um einen Atmega16, eigentlich sollte der 
SIG_OUTPUT_COMPARE0 Interrupt meiner Meinung nach alle 1,7µS auslösen. 
Wo liegt mein Rechen-/Denkfehler?

von Simon K. (simon) Benutzerseite


Lesenswert?

Paar mehr Informationen? Wie schnell isser denn?

von Philipp Karbach (Gast)


Lesenswert?

der Timer? CPU takt steht oben? ich versuche einen ausgang per timer 
nach einer bestimmt zeit zu toggeln um so einen ton zu erzeugen. die 
töne sind allerdings viel zu tief.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ja wie hast du denn festgestellt, dass er die 1,7µs nicht ausgibt? Und 
welchen Ton möchtest du hören? 1000/(1,7s*2) sind 294 kHz.

von Simon K. (simon) Benutzerseite


Lesenswert?

Und gib mal bitte den ganzen Code, mit dem Fragment kann man nichts 
anfangen.

von Philipp Karbach (Gast)


Lesenswert?

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#define F_CPU 18432000UL


void realtimeclock_setup() {
  TCCR0 |= (1<<WGM01);
  TCCR0 |= (1<<CS01) | (1<<CS00);
  OCR0 = 127;
  TIMSK |= (1<<OCIE0);
}


volatile float usec=0.0;

SIGNAL(SIG_OUTPUT_COMPARE0)
{
  if(usec<668.5) {
    PORTA &= ~(1<<PA0);
  }

  if(usec>668.5) {
    PORTA |= (1<<PA0);
    if(usec>1136.0)
      usec=0.0;
  }

  usec += 1.7;
}


int main() {
  DDRA |= (1<<PA0);

  realtimeclock_setup();
  sei();

  while(1) {}


  return 0;
}


Wie kommen die 668.5 zustande?

668.5*1.7uS = 1136uS,1/(1136uS*2)=440Hz

von Mmmh (Gast)


Lesenswert?

Die float-Berechnungen werden Dir Dein Timing völlig verhauen.
Wenn, dann macht man sowas nicht im Interrupt. Der soll immer so kurz 
wie möglich sein.

Einerseits schreibst Du, das Du alle 1,7us einen Int willst, dann aber 
sollen 440Hz rauskommen.
Ganz abgesehen davon, das 18.432MHz eine ungünstige Frequenz dafür ist, 
weil die nicht glatt teilbar ist.
Vermutlich machst Du darum die float-Kopfstände? Kann das sein?

Probier mal avrcalc.

von Simon K. (simon) Benutzerseite


Lesenswert?

Warum benutzt du nicht direkt den Output Compare Mode um die Frequenz 
auszugeben? Einfach die passenden Werte in das OCR Register laden und 
ggf. den Timervorteiler umstellen.

von Philipp Karbach (Gast)


Lesenswert?

okay ich sehe mein konzept ist unsinn, habe schonmal auf nen 4mhz quarz 
umgewechselt und mit avrcalc den timer berechnet. jetzt hab ich schonmal 
einen ton super exakt ausgegeben. das tool ist klasse :)

von Sven P. (Gast)


Lesenswert?

Philipp Karbach schrieb:
> das tool ist klasse :)

Die Formel im Datenblatt aber auch :->

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.