Forum: Mikrocontroller und Digitale Elektronik ATMEGA1284P TIMER3 FAST PWM


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Elektroboon (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Du solltest auch DDRB beschrieben, wenn du du PB6 und PB7 verwenden 
willst.

von Elektroboon (Gast)


Bewertung
0 lesenswert
nicht lesenswert
OMG wie doof. Logisch. Danke.

von Elektroboon (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert
Fehler in Zeile 42 (die du nicht zeigst).

Oliver

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


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.