ATMEGA1284P TIMER3 FAST PWM

Gast #6380903
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.
Gast #6403452
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.
Beitrag #6403481 wurde von einem Moderator gelöscht.
#6403493
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.
Gast #6403597
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.

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