AT Tiny44 bei PWM-Modus reagiert zu langsam

Gast #2362778
Lesenswert?

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.
#2362783
Lesenswert?

* 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.
Gast #2362796
Lesenswert?

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).
#2364015
Lesenswert?

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.
Gast #2368653
Lesenswert?

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
}
Gast #2368886
Lesenswert?

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
}
#2368893
Lesenswert?

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
#2368897
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren