Timer Rechenfehler?

Gast #1525135
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?
Gast #1525161
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
Gast #1525184
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.
Gast #1525225
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 :)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren