Hallo, ich versuche mit einem AtTiny85 einen Frequenzumsetzer zu bauen. F1 * Faktor --> F2 Die Frequenz ist maximal 2khz. Bisher habe ich versucht mit dem Timer0 die Frequenz 1 zu messen. Ich speichere mir in der ISR vom PIN den Timer wert, die Overflows werden gezählt. Den Takt erzeuge ich mit Timer1, damit lasse ich mit dem gezählten Wert/2 einen Pin toggeln. Das Problem ist nun das die Messroutine die Erzeugungsroutine beeinflusst so das der Erzeugte Takt am Oszi mit zunehmender Frequenz scheußlicher wird (schwankt). Vielleicht habe ich auch einen ganz falschen Ansatz gewählt. Wie wäre es sinnvoller? Mario
Hier noch der (scheußliche) Code ;)
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | #define F_CPU 8000000L
|
5 | |
6 | |
7 | |
8 | volatile long count1_ovf=1; |
9 | volatile int count1_ovf_tmp=1; |
10 | volatile long count1_counts=1; |
11 | volatile int count1_rest=1; |
12 | volatile long count_mess_ovf=0; |
13 | volatile int countok=0; |
14 | volatile int flanke2=0; |
15 | volatile int count1_a=0; |
16 | volatile int count1_b=0; |
17 | |
18 | |
19 | void setup() |
20 | {
|
21 | GIMSK = 0b00100000; // turns on pin change interrupts |
22 | PCMSK = 0b00000001; // turn on interrupts on pins PB0, PB1, &amp; PB4 |
23 | DDRB = 0b00010000; |
24 | // TCCR1 |= (1<<CS10); /* CPU/16384 als Takt */
|
25 | TIMSK |= (1<<TOIE0 | 1<<TOIE1); /* Overflow Interrupt an */ |
26 | // TCCR0B |= (1<<CS00); /* CPU/16384 als Takt */
|
27 | sei(); // enables interrupts |
28 | // cli();
|
29 | }
|
30 | |
31 | |
32 | int main(void) |
33 | {
|
34 | setup(); |
35 | |
36 | while (1) |
37 | {
|
38 | if (count_mess_ovf >=30000){ |
39 | TCCR0B &= ~(1<<CS00); /* CPU/16384 als Takt */ |
40 | TCCR1 &= ~(1<<CS10); /* CPU/16384 als Takt */ |
41 | count_mess_ovf=0; |
42 | count1_ovf=1; |
43 | count1_counts=1; |
44 | count1_rest=1; |
45 | countok=0; |
46 | count1_ovf_tmp=1; |
47 | flanke2=0; |
48 | count1_a=0; |
49 | count1_b=0; |
50 | TCNT0 = 0; |
51 | TCNT1 = 0; |
52 | //DDRB = 0b00000000;
|
53 | }
|
54 | |
55 | }
|
56 | }
|
57 | |
58 | ISR(PCINT0_vect) |
59 | {
|
60 | |
61 | if (PINB & ( 1 << PIN0 ) ) { |
62 | |
63 | TCCR1 |= (1<<CS10); /* CPU/16384 als Takt */ |
64 | TCCR0B |= (1<<CS00); /* CPU/16384 als Takt */ |
65 | //DDRB = 0b00010000;
|
66 | |
67 | count1_b = TCNT1 - count1_a; |
68 | |
69 | count1_counts = (count1_b + ( 255 * count_mess_ovf )) / 2; |
70 | count_mess_ovf = 0; |
71 | |
72 | count1_counts = count1_counts * 1.07; |
73 | count1_ovf = count1_counts / 255; |
74 | count1_rest = count1_counts - ( 255 * count1_ovf ); |
75 | |
76 | count1_a = TCNT1; |
77 | }
|
78 | |
79 | }
|
80 | |
81 | ISR(TIMER0_OVF_vect) |
82 | {
|
83 | count_mess_ovf++; |
84 | }
|
85 | |
86 | |
87 | ISR(TIMER1_OVF_vect) |
88 | {
|
89 | |
90 | if (countok == 1 && count1_ovf >= 1){ |
91 | |
92 | PINB = _BV(PB4); |
93 | count1_ovf_tmp = count1_ovf; |
94 | countok=0; |
95 | |
96 | }
|
97 | |
98 | if (count1_ovf_tmp == 0) { |
99 | TCNT1 = 255 - count1_rest; |
100 | countok=1; |
101 | |
102 | }
|
103 | else { count1_ovf_tmp--; } |
104 | }
|
Mario schrieb: > ich versuche mit einem AtTiny85 einen Frequenzumsetzer zu bauen. > > F1 * Faktor --> F2 > > Die Frequenz ist maximal 2khz. OMG Schon wieder eine Reinkarnation E-Bike-Tuning o.ä.
Hallo, Du solltest den Timer direkt den Pin toggeln lassen und das nicht extra im IRQ machen. Somit vermeidest Du den von Dir beobachteten Jitter. Dafür ist diese Hardwarefunktionalität extra eingebaut. MfG
Ich denke du meinst Counter statt timer? Wie schaffe ich es bei einem gemessenen wert von z.B. 12345 Der Counter muss dann ja trotzdem vorher 48x überlaufen, oder?
Oberflächlich betrachtet würde ich sagen, Timer1 im CTC-Modus mit 'Comparator A Output Mode'; mit seinem in Zweierstufen einstellbaren Vorteiler sollte man eine brauchbare Auflösung hinbekommen. Aber da stellt sich mir die Frage nach den Rahmenbedingungen: Eingangsfrequenzbereich, Bereich des Faktors, verlangte Genauigkeit.
S. Landolt schrieb: > Aber da stellt sich mir die Frage nach den Rahmenbedingungen: > Eingangsfrequenzbereich, Bereich des Faktors, verlangte Genauigkeit. Wie immer bei solchen Postings: -Frequenzbereich 0..unendlich -Faktor 0..unendlich -Genauigkeit: natürlich 100% exakt Dazu natürlich noch (das hast du vergessen zu fragen): -instantane Reaktion -dabei aber natürlich absolut kein Jitter der Ausgabefrequenz Hab' ich noch was vergessen?
Ok, das werde ich mir noch anschauen. Die Eingangsfrequenz soll um 8% verlangsamt werden. Genauigkeit keine kommastellen also 1Hz.
Das hatte ich durchaus gelesen, dass die obere Grenzfrequenz 2 kHz beträgt - und die untere? Wäre diese z.B. 100 Hz, dann entspräche die Angabe 1 Hz 1 %, bei den 2 kHz jedoch ein halbes Promille, das beißt sich mit den 8 bit des Timers. Sie sehen, die Vorgaben sind etwas diffus. Konstanter Faktor von 0.92? Mit c-haters Vermutung "E-Bike" kann ich leider wenig anfangen. Aber schauen Sie sich mal die Möglichkeiten des Timer1 an, ich stelle mir das nicht allzu schwer vor.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.