hallo,
Ich versuche hier einen simplen Piezo ohne Elektronik an einem Tiny13V
zu betreiben. Angeschlossen ist er an PB0:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<util/delay.h>
4
5
6
intmain(void)
7
{
8
DDRB|=(1<<0);
9
TIMSK0|=(1<<TOIE0);
10
sei();
11
TCCR0B|=(1<<CS01);
12
//TCCR0B|=(1<<CS00);
13
14
for(;;)
15
{
16
PORTB&=~(1<<0);
17
// _delay_ms(1);
18
}
19
return0;
20
}
21
22
ISR(TIM0_OVF_vect)
23
{
24
PORTB|=(1<<0);
25
}
Den genauen Resonanzbereich des Piezo kenne ich nicht, allerdings meine
ich, dass er um die 5KHz liegt, also müsste mind. eine der
Prescaler-Einstellungen ein hörbares akustisches Signal produzieren:
der Tiny13V läuft normalerweise auf 4MHz, CLKDIV8 ist gesetzt, d.h. er
müsste tatsächlich auf 500 KHz laufen.
500KHz/8 = 63 KHz
500KHz/64 = 7.8 KHz
500KHz/256 = 2 KHz
Liegt alles noch im hörbaren Bereich, trotzdem tut sich nichts. Wo liegt
der Denkfehler?
Danke
Dominik
for(;;)
{
PORTB&=~(1<<0);
// _delay_ms(1);
}
return 0;
}
ISR(TIM0_OVF_vect)
{
PORTB|=(1<<0);
}
Hier wird PB0 in der ISR 1, dann sofort wieder 0 (innerhalb ein paar
Taktzyklen).
Probier mal PB0 in der ISR zu togglen:
for(;;)
{
;
}
return 0;
}
ISR(TIM0_OVF_vect)
{
PORTB^=(1<<0);
}
Ein Oszilloskop / Multimeter mit vernünftiger Frequenzmessung hab ich
leider nicht, hab jetzt einfach mal eine LED an PB0 gesetzt, und die
blinkt bei Prescaler = 1024 gerade mal ein mal pro Sekunde, d.h. das
Ausgangssignal muss aus irgendeinem Grund viel zu langsam sein.
Hallo Dominik,
bist Du Dir sicher, dass CKSEL nicht "11" ist (=128kHz int. Oszillator)?
Bei FOSC=128kHz (ohne CKDIV8) und Timer Prescaler=1024 wäre Deine LED
0,49s an und 0,49s aus.
Dominik Hensler wrote:
> Ein Oszilloskop / Multimeter mit vernünftiger Frequenzmessung hab ich> leider nicht, hab jetzt einfach mal eine LED an PB0 gesetzt, und die> blinkt bei Prescaler = 1024 gerade mal ein mal pro Sekunde, d.h. das> Ausgangssignal muss aus irgendeinem Grund viel zu langsam sein.
Nein. Du vergisst, dass der Overflow-Interrupt ausgelöst wird, wenn der
Timer überläuft, was alle 256 Timer-Takte der Fall ist.
> 500KHz/8 = 63 KHz> 500KHz/64 = 7.8 KHz> 500KHz/256 = 2 KHz>> Liegt alles noch im hörbaren Bereich, trotzdem tut sich nichts. Wo liegt> der Denkfehler?
Was du hier ausrechnest, ist die Frequenz, mit der der Timer läuft. Die
Frequenz deines Ausgangssignals liegt nochmal um den Faktor 512
darunter.
Also:
500KHz/8 /512 = 122 Hz
500KHz/64 /512 = 15 Hz
500KHz/256 /512 = 4 Hz
Ah, verstehe. Dann bleibt mir wohl nichts übrig als die Taktfrequenz
wieder auf 4MHz raufzusetzen und den erhöhten Stromverbrauch in Kauf zu
nehmen.
Nur Interessehalber - was würde ich eigentlich machen, wenn ich eine
höhere Frequenz als 4.000.000 / 512 = 7,8 KHz bräuchte?
Zum Beispiel den Timer im CTC-Modus benutzen. Da kannst du genau
einstellen, bis wo er laufen soll. Übrigens kannst du den Timer auch so
einstellen, daß er automatisch PB0 toggelt, sodaß du dir die ISR auch
sparen kannst.
Dominik Hensler wrote:
> Ah, verstehe. Dann bleibt mir wohl nichts übrig als die Taktfrequenz> wieder auf 4MHz raufzusetzen und den erhöhten Stromverbrauch in Kauf zu> nehmen.
Nein, mit 500kHz Systemtakt kannst du problemlos ein paar kHz für den
Piezo erzeugen. Verwende am besten den CTC-Mode, den Rolf auch schon
erwähnt hat.
Die letzten beiden Anweisungen in der ISR hab ich nur testweise
reingeschrieben um zu gucken ob der Interrupt überhaupt ausgelöst wird.
Scheint aber nicht der Fall zu sein. Muss ich ausser WGM02 im TCCR0B
Register noch irgendwas anderes setzen?
Du setzt das oben gesetzte Bit wieder auf 0. Macht aber nicht wirklich
was, denn mit WGM:100 bekommst du eh keinen CTC-Mode. Schau nochmal in
das Datenblatt.
Wieso OCR0B? Im CTC-Modus stellst du den Wert über ORC0A ein. Abgesehen
davon würde bei einem Takt von 500 kHz bei einem Compare-Match-Wert von
10 der Port 50k mal pro Sekunde getoggelt, also hättest du eine Frequenz
von 25 kHz, die eher schwer zu hören ist ;-)
Nee, ich benutze doch den B-Kanal des Timers und der eingestellte Wert
wirkt sich ja auch auf die blink-Frequenz der LED aus. Welchen Compare
Match Wert würdest du vorschlagen?
Wo steht da was vom CTC-Modus? Schau im Datenblatt in Kapitel 11.9.1 (in
der aktuellen Version auf Seite 72). Da sind die Timer-Modi gelistet.
Dort gibt es nur einen CTC-Modus, nämlich Mode 2 (also WGM1 auf 1, alle
anderen auf 0). Und bei dem ist für TOP ORCA eingetragen. Für OCRB gibt
es keinen Modus.