Hallo

Danke für die Erklärungen. Aber was brauchst du nun wirklich? 36kHz, 72kHz oder gar 144kHz?

Beim oben gezeigten Grundgerüst wird der Interrupt 72000 mal in der Sekunde ausgelöst und die ISR angeprungen. 72000 mal, weil eine Periode des 36kHz-Signals aus zwei Halbwellen besteht und der erzeugende Ausgang deshalb doppelt so schnell angesteuert werden muss. Hier die passende Erweiterung die den Pin5 oder PB0 ansteuert:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIM0_COMPA_vect)
{
	// PB0 einlesen und invertiert wieder ausgeben
	if(PINB & (1<<PB0)) PORTB &= ~(1<<PB0); else PORTB |= (1<<PB0);
}

int main(void)
{
	TCCR0A = (0 << WGM00) | (1 << WGM01); // CTC-Mode
	TCCR0A |= (0 << COM0A0) | (0 << COM0A1); // ohne OCR-Pin
	TCCR0B = (0 << CS02) | (0 << CS01) | (1 << CS00); // kein prescaler!
	TIMSK0 = (1 << OCIE0A); // Interrupt ein
	OCR0A = 9600/72; // 9,6MHz/72kHz = 133,3
	sei();

	DDRB |= (1<<PB0); // PB0/Pin5 als Ausgang betreiben
	while(1)
	{
	}
	return(0);
}
(ungetestet)

Bei der PWM-Betriebsart, wie beim asuro, läuft der Timer von 0 bis 255 und startet dann wieder bei 0. Die Periodendauer wird über das OCRx-Register erzeugt. Immer wenn der Zählerwert dem Inhalt dieses Registers entspricht wird der OCx-Ausgang des Timers geschaltet. Details werden über die Parametrierung des Timers eingestellt. Beim asuro wird der Ausgang immer gesetzt wenn der Timer nach dem Überlauf bei 0 neu startet, wenn OCRx erreicht wird, wird der Ausgang wieder ausgeschaltet. Dadurch werden pro Timerdurchlauf beide Periodenhäflten erzeugt. Ein Durchlauf dauert 8MHz/36kHz=222 Takte, jede Halbwelle also ca. 111 Takte. Für ein symetrisches Signal muss der Ausschaltpunkt deshalb 111 Takte vor dem Überlauf sein, deshalb wird das OCRx-Register mit 256-111=145 oder 0x91 geladen.

Nun muss man noch die Takte pro Periode von 256 auf 222 kürzen. Da der Timer beim Überlauf nach 0 springt und erst dann die Überlauf-ISR aufgerufen wird, kann man hier den Zählerstand manipulieren. Das Zählregister des Timers muss um die zuvielen Takte erhöht werden. Dazu wird der aktuelle Zählerstand eingelesen, die Korrektur dazugerechnet und alles zusammen wieder in das Zählregister zurückgeschrieben. Der Korrekturwert errechnet sich aus der Differenz von 222 zu 256 und zusätzlichen(!) 3 Takten fürs Laden, Rechnen und Zurückschreiben: 256-222+3=37 oder 0x25. Deshalb findet man in der asuro-Lib in der ISR folgende Zeile:

TNCT2 += 0x25;

Beim Tiny mit 9,6MHz klappt das nicht so einfach: 9600000/36000=266. Leider zuviel für den 8-Bit-Timer.

Gruß

mic