Forum: Mikrocontroller und Digitale Elektronik Frequenz Umsetzer mit AtTiny85


von Mario (Gast)


Lesenswert?

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

von Mario (Gast)


Lesenswert?

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;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
}

von Bernd (Gast)


Lesenswert?

> Wie wäre es sinnvoller?

Quelltext?

von c-hater (Gast)


Lesenswert?

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.ä.

von Christian S. (roehrenvorheizer)


Lesenswert?

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

von Mario (Gast)


Lesenswert?

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?

von S. Landolt (Gast)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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?

von Mario (Gast)


Lesenswert?

Ok, das werde ich mir noch anschauen.

Die Eingangsfrequenz soll um 8% verlangsamt werden. Genauigkeit keine 
kommastellen also 1Hz.

von Mario (Gast)


Lesenswert?

Frequenz wie oben max. 2khz.

von S. Landolt (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.