Hallo, ich baue einen Frequenzgenerator bei dem über ein Poti das Puls-Pausen-Verhältnis und mit Hilfe von drei Jumpern die Frequenz eingestellt wird. Ich benutze dafür ein AT Tiny 44. Leider reagiert der µC beim Umschalten der Frequenzen unregelmäßig schnell und grundsätzlich sehr langsam.Auch das ausschalten dauert sehr lange. Woran kann das liegen? Danke fur Antworten im Voraus.
* definiere 'unregelmäßig schnell' * definiere 'grundsätzlich sehr langsam' Über welche Zeiten sprechen wir? Das der aktuell laufende PWM Zyklus zu Ende gefahren werden muss, dürfte klar sein. Abgesehen davon liegt der Fehler, wie immer wenn es nicht ein systembedingter Fehler ist, in deinem Programm.
Also wenn ich von den hohen zu den niedrigen Frequenzen wechsel dauert es bis zu 7 Sekunden bis sich die neue Frequenz einstellt. Vorher läuft die alte weiter. Andersherum geht es oft etwas schneller. Will ich den PWM-Modus beenden dauert es sogar bis zu 11 Sekunden. Das Programm ist recht einfach gestaltet und läuft an sich mit 1,3kHz(Port togglen in der while-Schleife).
JvH schrieb: > Also wenn ich von den hohen zu den niedrigen Frequenzen wechsel dauert > es bis zu 7 Sekunden bis sich die neue Frequenz einstellt. Dann bräuchten wir wohl auch mal einen Schaltplan ... und das Programm auch, wenn's nicht gerade geheim ist. Klingt, als hättest du einen floatenden Eingang.
Wenn Du den Comparewert runter setzt, mußt Du auch den Timer auf 0 setzen. Ansonsten muß der erstmal über 65535 laufen, ehe der nächste Compare auftritt. Peter
Das mit dem Timer hat die Verzögerung zwar nciht behoben aber immerhin soweit eingegrenzt dass ich mit arbeiten kann. Danke für die Hilfe.
JvH schrieb: > Das mit dem Timer hat die Verzögerung zwar nciht behoben aber immerhin > soweit eingegrenzt dass ich mit arbeiten kann. Bei 7 Sekunden hast du einen gröberen Bock im Programm. Warum zeigst du es nicht? So schlimm? Spätestens nach 1/f[s], wobei f die alte Frequenz ist, muss die Einstellung stehen und die PWM umgeschaltet sein. Und ich glaube nicht dass du Frequenzen im Bereich 0.14Hz erzeugst.
Okay, dann hier das Programm. Ich hoffe der "Bock" ist nur für mich versteckt und jemand findet ihn schnell.
1 | int main(void) |
2 | {
|
3 | |
4 | /*****Variablen*****/
|
5 | |
6 | uint8_t adc_temp = 0; // Variable für den gemessene Analogspannung |
7 | uint8_t ocr0a_temp = 0; // Hilfsvariable fürs rechnen |
8 | uint8_t Jumper_Status = 0; // Variable für Status der Frequnezen |
9 | uint8_t Jumper_Status_alt = 0; |
10 | |
11 | /******Initialisierungen*****/
|
12 | clock_prescale_set(7); //CPU-Freuqeunz = 8Mhz/128 |
13 | init_ports(); |
14 | init_ADC(); |
15 | |
16 | |
17 | |
18 | |
19 | while(1) |
20 | {
|
21 | |
22 | adc_temp = ReadAdc(); |
23 | |
24 | Jumper_Status = 0; |
25 | |
26 | if(JUMPER1_SET) |
27 | {
|
28 | Jumper_Status = J1_AKTIV; |
29 | }
|
30 | |
31 | if(JUMPER2_SET) |
32 | {
|
33 | Jumper_Status = J2_AKTIV; |
34 | }
|
35 | |
36 | if(JUMPER3_SET) |
37 | {
|
38 | Jumper_Status = J3_AKTIV; |
39 | }
|
40 | |
41 | |
42 | if (Jumper_Status != Jumper_Status_alt) |
43 | {
|
44 | switch (Jumper_Status) |
45 | {
|
46 | case (J1_AKTIV): |
47 | TCCR0B |= ((1<<CS00)|(1<<CS01)); //Teilungsfaktor 64 |
48 | ocr0a_temp = 96; |
49 | OCR0A = ocr0a_temp; |
50 | TCNT0 = 0; //Timer-Reset |
51 | OCR0B = ((ocr0a_temp<<4)/adc_temp); |
52 | init_TCCR(); |
53 | break; |
54 | |
55 | case (J2_AKTIV): |
56 | TCCR0B &= ~(1<<CS00); |
57 | TCCR0B |= (1<<CS01); //Teilungsfaktor 8 |
58 | ocr0a_temp = 156; |
59 | OCR0A = ocr0a_temp; |
60 | TCNT0 = 0; //Timer-Reset |
61 | OCR0B = ((ocr0a_temp<<4)/adc_temp); |
62 | init_TCCR(); |
63 | break; |
64 | |
65 | case (J3_AKTIV): |
66 | TCCR0B &= ~(1<<CS00); |
67 | TCCR0B |= (1<<CS01); //Teilungsfaktor 8 |
68 | ocr0a_temp = 76; |
69 | OCR0A = ocr0a_temp; |
70 | TCNT0 = 0; //Timer-Reset |
71 | OCR0B = ((ocr0a_temp<<4)/adc_temp); |
72 | init_TCCR(); |
73 | break; |
74 | |
75 | default:
|
76 | TCCR0A = 0; |
77 | TCCR0B = 0; |
78 | OCR0A = 0; |
79 | TCNT0 = 0; //Timer-Reset |
80 | OCR0B = 0; |
81 | break; |
82 | }
|
83 | Jumper_Status_alt = Jumper_Status; |
84 | }
|
85 | else
|
86 | {
|
87 | if (Jumper_Status != 0) |
88 | {
|
89 | adc_temp = ((255<<4)/adc_temp); |
90 | OCR0B = ((ocr0a_temp<<4)/adc_temp); |
91 | }
|
92 | }
|
93 | |
94 | |
95 | |
96 | }
|
97 | }
|
Was genau macht denn init_ports()? Ich hatte oben schon mal die Vermutung geäußert, dass du floatende Pins hast, an denen deine Taster hängen, darauf bist du nicht eingegangen. Vielleicht postest du ja doch einmal den Schaltplan und den kompletten Sourcecode.
Den Schaltplan habe ich leider nicht digital. Aber an den Eingängen für den Jumper-Status hängen jeweils nur ein 1k Vorwiderstand, ein Kondensator zum Entstören und dass ganze wird dann per Jumper mit 5V verbunden. Nichts aufwendiges also. Meine zweite Source FIle ist von einem anderen Projekt übernommen. Sie enthält den Ablauf der AD-Messung und dürfte nach Copy-Paste-Methode keine Fehler enthalten. Die dritte Source FIle mit den Inits sieht wie folgt aus:
1 | //#include <stdio.h>
|
2 | #include<avr/io.h> |
3 | #include "ports.h" |
4 | #include "init.h" |
5 | |
6 | |
7 | void init_ports() |
8 | {
|
9 | /****PortA****/
|
10 | DDRA |= (1<< PA7); //alle Ports als Eingang(0), Port A7 als Ausgang(1) |
11 | PORTA =0x00; //alle Pull-Ups deaktiviert(0), keiner aktiviert(1) |
12 | |
13 | /***PortB***/
|
14 | DDRB = 0x00; //PortB2(OC0A) als Ausgang(1) |
15 | //PORTB =0x04; //PortB2 als HIGH-Output(1)
|
16 | |
17 | }
|
18 | |
19 | void init_ADC() |
20 | {
|
21 | ADMUX =0x00; //Vcc als Referenz(00), PortA0 als Eingang für ADC(0) |
22 | ADCSRB |= (1<<ADLAR); //Bits werden zuerst in ADCH geschrieben |
23 | |
24 | |
25 | }
|
26 | |
27 | void init_TCCR() |
28 | {
|
29 | TCCR0A |=(1<<COM0B1)|(1<<WGM01)|(1<<WGM00); //Impulsreihenfolge High/Low|Modus ist Fast PWM |
30 | TCCR0B |=(1<<WGM02); //Fast PWM mit OCRA als Referenz |
31 | //TCCR0B |= ((1<<CS00)|(1<<CS01)); //Teilungsfaktor 1/64 zu CPU-Clock
|
32 | DDRB |= (1<<OCR0A); |
33 | }
|
JvH schrieb: > Den Schaltplan habe ich leider nicht digital. Aber an den Eingängen für > den Jumper-Status hängen jeweils nur ein 1k Vorwiderstand, ein > Kondensator zum Entstören wie groß? > und dass ganze wird dann per Jumper mit 5V > verbunden. Das klingt nicht gut. Wenn der Jumper nicht gesetzt ist, wer zieht den Eingang auf 0? > Nichts aufwendiges also. Noch unaufwendiger wäre es gewesen, den ganzen Klimbim zu lassen, eine vernünftige softwaremässige Entprellung zu machen und die Jumper wie üblich gegen Masse schalten zu lassen. Dazu die internen Pullup Widerstände und deine Aussenbeschaltung ist bis auf die Jumper: 0 - njente - nada - nothing
Karl Heinz Buchegger schrieb: > JvH schrieb: >> Den Schaltplan habe ich leider nicht digital. Aber an den Eingängen für >> den Jumper-Status hängen jeweils nur ein 1k Vorwiderstand, ein >> Kondensator zum Entstören > > wie groß? > >> und dass ganze wird dann per Jumper mit 5V >> verbunden. > > Das klingt nicht gut. > Wenn der Jumper nicht gesetzt ist, wer zieht den Eingang auf 0? Schalte mal direkt von den entsprechenden Pins einen 10k Widerstand nach Masse, wenn du nicht schon einen hast.
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.