Forum: Mikrocontroller und Digitale Elektronik ATMEGA1284P TIMER3 FAST PWM


von Elektroboon (Gast)


Lesenswert?

Hi,

ich versuche vergeblich den Timer3 zu verwenden.

Timer1 klappt ganz super mit:

TCCR1A = (1<<COM1A1) + (1<<COM1B1) + (1<<WGM11);
TCCR1B = (1<<WGM13) + (1<<WGM12) + (1<<CS10); // prescaler = 1 (none)
ICR1 = 15999;
OCR1A = 3999;
OCR1B = 11999;
DDRD |= (1 << DDD4) | (1 << DDD5);


Timer3 hingegen mit:

TCCR3A = (1<<COM3A1) + (1<<COM3B1) + (1<<WGM31);
TCCR3B = (1<<WGM33) + (1<<WGM32) + (1<<CS30); // prescaler = 1 (none)
ICR3 = 15999;
OCR3A = 3999;
OCR3B = 11999;
DDRD |= (1 << DDB6) | (1 << DDB7); //PB6 und 7 als AUSGANG

scheint nicht zu funktionieren.

Hat jemand ne Idee?

Danke schonmal.

von Chris K. (Gast)


Lesenswert?

Du solltest auch DDRB beschrieben, wenn du du PB6 und PB7 verwenden 
willst.

von Elektroboon (Gast)


Lesenswert?

OMG wie doof. Logisch. Danke.

von Elektroboon (Gast)


Lesenswert?

Ich habe nun leider ein Problem bei der ISR. Mein uC läuft mit 20MHz.

Bei 1000ms soll hochgezählt werden. Ohne die PWM-Timer1/3 Inits 
funktioniert es mit "==". Mit PWM geht es nur sporadisch mit "==" und 
mit ">=" wird es sehr ungenau.

Kann mir jemand erklären warum die Variable über 1000 läuft und wie ich 
das beheben kann?

Beim PWM würde mir eine geringere Auflösung reichen falls dies helfen 
würde... jedoch benötige ich die 4 Kanäle.
1
void encode_init( void )
2
{
3
  int8_t new;
4
5
  //set pins as input
6
  ROTDDR &= ~((1<<ROTPA)|(1<<ROTPB)|(1<<ROTPBUTTON));
7
  //enable interrnal pullups;
8
  ROTPORT |= (1<<ROTPA)|(1<<ROTPB)|(1<<ROTPBUTTON);
9
10
11
  new = 0;
12
  if( PHASE_A ) new = 3;
13
  if( PHASE_B ) new ^= 1;       // convert gray to binary
14
  last = new;                   // power on state
15
  enc_delta = 0;
16
  TCCR0B = (1<<CS02);   //  prescaler 256
17
  TCCR0A = (1<<WGM01); //   CTC Modus
18
  OCR0A = 78; //78=1ms
19
  TIMSK0 |= 1<<OCIE0A;
20
}
21
22
TCCR1A = (1<<COM1A1) + (1<<COM1B1) + (1<<WGM11);
23
TCCR1B = (1<<WGM13) + (1<<WGM12) + (1<<CS10); // prescaler = 1 (none)
24
ICR1 = 16000;
25
OCR1A = 0; //R 
26
OCR1B = 0; //G
27
DDRD |= (1 << DDD4) | (1 << DDD5); //PD4 und 5 als AUSGANG
28
29
30
TCCR3A = (1<<COM3A1) + (1<<COM3B1) + (1<<WGM31);
31
TCCR3B = (1<<WGM33) + (1<<WGM32) + (1<<CS30); // prescaler = 1 (none)
32
ICR3 = 16000;
33
OCR3A = 0; //B
34
OCR3B = 4000; //0-10V Output
35
DDRB |= (1 << DDB6) | (1 << DDB7); //PB6 und 7 als AUSGANG
36
37
ISR( TIMER0_COMPA_vect )            // 1ms for manual movement
38
{
39
  int8_t new, diff;
40
41
  new = 0;
42
  if( PHASE_A ) new = 3;
43
  if( PHASE_B ) new ^= 1;          // convert gray to binary
44
  diff = last - new;               // difference last - new
45
  if( diff & 1 ) 
46
  {                 // bit 0 = value (1)
47
      last = new;                    // store new as next last
48
      enc_delta += (diff & 2) - 1;   // bit 1 = direction (+/-)
49
  }
50
  ms++;//Addiere +1 zu MilliSekunden
51
  if (ms == 1000)    //-------------------------------HIER!!!!!!! Bei == überläuft die Variable bei >= wird's ungenau!!!!
52
  {
53
    ms = 0;
54
    ss++;//Addiere +1 zu Sekunden
55
    lcd_burned_ss++;
56
    if (ss >= 60)
57
    {
58
      ss = 0;
59
      mm++;//Addiere +1 zu Minuten
60
      if (mm >= 60)
61
      {
62
        mm = 0;
63
        hh++;//Addiere +1 zu Stunden
64
        if (hh >= 24)
65
        {
66
          day++;
67
          if (day >= 8)
68
          {
69
            day=1;
70
          }
71
          hh = 0;
72
        }
73
      }
74
    }
75
  }
76
}

Danke vorab.

von Oliver S. (oliverso)


Lesenswert?

Fehler in Zeile 42 (die du nicht zeigst).

Oliver

Beitrag #6403481 wurde von einem Moderator gelöscht.
von Falk B. (falk)


Lesenswert?

Elektroboon schrieb:
> Ich habe nun leider ein Problem bei der ISR. Mein uC läuft mit 20MHz.
>
> Bei 1000ms soll hochgezählt werden. Ohne die PWM-Timer1/3 Inits
> funktioniert es mit "==". Mit PWM geht es nur sporadisch mit "==" und
> mit ">=" wird es sehr ungenau.

Wie stellst du das fest?

> Kann mir jemand erklären warum die Variable über 1000 läuft

Das kann sie mit DEM Programm nicht.

> Beim PWM würde mir eine geringere Auflösung reichen falls dies helfen
> würde... jedoch benötige ich die 4 Kanäle.

Hilft nicht.

Zeige VOLLSTÄNDIGEN, ORIGINALEN Quelltext, keine losen Schnipsel!
Siehe Netiquette.

von Elektroboon (Gast)


Lesenswert?

Das stelle ich fest indem ich die Sekunden im Display mit einer Uhr 
vergleiche und nach ca. 30s sehe wie sie langsam voneinander abweichen.

Den kompletten Code mit allen includes zu Posten würde den Rahmen 
sprengen.

von Peter D. (peda)


Lesenswert?

Elektroboon schrieb:
> Den kompletten Code mit allen includes zu Posten würde den Rahmen
> sprengen.

Wow, Dein Code ist also über 10MB groß?
Ist aber auch kein Problem, dann zippe das komplette Projekt, plain Text 
läßt sich gut komprimieren.

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.