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

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.