Hallo
Ich habs mal etwas geputzt:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t y, p;
ISR(TIM0_COMPA_vect) // Servoansteuerung
{
static uint16_t count=0;
if (count>y) PORTB &= ~(1<<PB4); else PORTB |= (1<<PB4);
if (count < 2000) count++; else { count=0; if(p) p--; }
}
int main(void)
{
DDRB = (1<<PB4)|(1<<PB1); // Servoausgang
PORTB |= (1<<PB1); // und Spannungsversorgung der Schaltung?
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 = 12; // 100kHz 1200000/12
sei();
y=150;
while(1)
{
p=50; while(p); // eine Sekunde warten
if(y == 150) y=100; else y=150; // neue Position festlegen
}
return(0);
}
Das ist jetzt für 1,2MHz. Das sollte nicht funktionieren, weil die ISR nur 12 Takte Zeit hat und deshalb vermutlich überläuft (=während der Ausführung der ISR tritt schon der nächste Interrupt auf). Sollte dein Tiny wirklich mit 9,6MHz takten, sollte das OCR0A so geladen werden:
OCR0A = 96; // 100kHz 9600000/96
Die ISR hätte dann 96 Takte Zeit zur Ausführung.
Gruß
mic
[Edit]
Code:
TCCR0B = (0 << CS02) | (0 << CS01) | (1 << CS00); // kein prescaler!
OCR0A = 12; // 100kHz 9600000/(8*12)
sei();
// y=150; //wieso kann ich y nur hier setzen?
while(1){
y=150; // und nicht hier?
Vermutlich passiert genau hier der Überlauf. Nach while(1) sind die zwölf Takte vorbei (egal welcher Kontrollertakt verwendet wird) und der Kontroller stürzt ins Interruptüberlaufsniwana. Es wird zwar noch irgendwas als Impuls ausgegeben, aber das ist völlig unkontrolliert. Bei der Zuordnung direkt nach sei() erfolgt der Absturz wenigstens mit richtig geladenem y. Ist nur so ein Nachtgedanke.
Lesezeichen