Forum: Mikrocontroller und Digitale Elektronik Arduino Mega R3 PWM funktioniert nicht für Timer 5 (A), Pin 44


von Harald F. (boimler)


Angehängte Dateien:

Lesenswert?

Hallo,

ich baue gerade einen Wandler, der das Steuersignal für meine alten 
Heizungspumpen (2Hz "PWM") in ein für Hocheffizienzpumpen geeignetes 
Signal mit frei wählbarer Frequenz (hier 720Hz) aber gleichem 
Tastverhältnis umwandelt.
Benutzt wird der Arduino Mega R3 und dort die 16-bit Timer (1,3,4,5), 
vom Timer 5 nur die ersten beiden Outputs (A,B - Pin 44 und 45).
Ich nutze einen aufsteckbaren Shield, das beschriebene Verhalten zeigt 
sich aber mit und ohne Shield, auf original Arduinos und auf Clones.

1. 9 von meinen 10 Kanälen funktionieren perfekt -- Timer 1, 3, 4 und 
5B(Pin 45).
2. Der Ausgang 5A (Pin44), bei mir Kanal 9 funktioniert nicht.
3. Ausgang 5A funktioniert sobald ich zusätzlich analogWrite wie 
auskommentiert nutze. Dies ist bei keinem anderen Ausgang nötig.

Frage: Was verursacht dieses abweichende Verhalten? Habe ich etwas 
falsch/nicht verstanden, gibt es einen dummen :-) Fehler?

Ich hänge den Code und den LogicAnalyzer Screenshot an.

Vielen Dank für Eure Hilfe,
Harald

Beitrag #7455437 wurde vom Autor gelöscht.
von Chris H. (Firma: Selbständig Denkender) (keiningenieur)


Lesenswert?

Erstmal DB Seite 154 und dann musst du ma die Daten geben wie du den 5er 
konfigriert hast Dazu Seite 145

https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/ATmega640-1280-1281-2560-2561-Datasheet-DS40002211A.pdf

von Harald F. (boimler)


Lesenswert?

Der Code/die Config ist angehängt.
Die eigentliche Frage ist auch warum Timer4 Pins funktionieren, aber ein 
Pin von Timer5 nicht bzw nur via analogWrite.
Im Manual wird für beide sogar das gleiche Blockschaltbild verwendet. 
Die verwendeten Werte stammen genau von den o.a. Seiten.
Hier nochmal Timer 4 und 5:

/////////////////////////////////////////////// Timer 4 
///////////////////////////////////////////////
TCCR4A = TCCR4B = TCCR4C = 0;
for ( i=5; i<8;i++)
{
  if (Lines[i].InputType)
  {
    TCCR4A |= (1<<Lines[i].Comxy);
  }
}
  TCCR4A |=  (1<<WGM41);    // result: TCCR4A =  0b10100010, activate 
pins A/B, wave generation mode phase PWM mode 10
  TCCR4B =  0b00010001;     // timer = system clock, Divisor = 1
  ICR4 = ICR16Val;          // timer = system clock, Divisor = 1
  OCR4A = ICR4*0.6;         // set duty-cycle
  OCR4B = ICR4*0.5;         // set duty-cycle
  OCR4C = ICR4*0.4;         // set duty-cycle

/////////////////////////////////////////////// Timer 5 
///////////////////////////////////////////////
  TCCR5A = TCCR5B = TCCR5C = 0;
  for ( i=8; i<10;i++)
  {
    if (Lines[i].InputType)
    {
      TCCR5A |= (1<<Lines[i].Comxy);
    }
  }
  TCCR5A |= (1<<WGM51);     // result: TCCR5A =  0b10100010, activate 
pins A/B, wave generation mode phase PWM mode 10
  TCCR5B =  0b00010001;     // timer = system clock, Divisor = 1
  ICR5 = ICR16Val;          // timer = system clock, Divisor = 1
  OCR5A = ICR5*0.3;         // set duty-cycle
  OCR5B = ICR5*0.2;         // set duty-cycle
  OCR5C = ICR5*0.0;         // set duty-cycle

von Chris H. (Firma: Selbständig Denkender) (keiningenieur)


Lesenswert?

Harald F. schrieb:
> pins A/B, wave generation mode phase PWM mode 10

Welchen Modus willst du eigentlich nutzen ?

Gesetzt im
TCCR5A ist WGM51
TCCR5B ist WGM52 und CS50 (kein Teiler aktiviert)

mal die WGMx:y
|   TCCR5B     |    TCCR5A     |
|WGM53 | WGM52 | WGM51 | WGM50 |
   0       1       1       0

= FastPWM 9 Bit

Wenn du ausserhalb des 0x3F Adressraumes arbeiten willst musst die WGM 
eigentlich mit STS/LDS ansprechen alles darunter wird mit IN/OUT 
angesprochen
Schau mal Seite 402

Stopp soll der auf 0.0 gesetzt sein
Harald F. schrieb:
> OCR5C = ICR5*0.0;         // set duty-cycle

Harald F. schrieb:
> vom Timer 5 nur die ersten beiden Outputs (A,B - Pin 44 und 45)

Sind auch die falschen PINS.
38/39 wären das bei dem großen PINER mit 100Pins

Wenn du das kleine PINOUT verwendest 64Pins. gibs die nicht siehe seite 
94

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

du hast:
OC5A  Pin 46
OC5B  Pin 45
OC5C  Pin 44

Wenn du Duty Cycle auf 0 setzt (OCR5C = ICR5*0.0;) dann taktet an Pin 44 
natürlich nichts.  ;-)

von Chris H. (Firma: Selbständig Denkender) (keiningenieur)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> du hast:
> OC5A  Pin 46
> OC5B  Pin 45
> OC5C  Pin 44
>
> Wenn du Duty Cycle auf 0 setzt (OCR5C = ICR5*0.0;) dann taktet an Pin 44
> natürlich nichts.  ;-)

auf diesen Pins exitiert kein Timer 5 Ausgang weder im BGA noch im TQFP 
Gehäuse

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Chris H. schrieb:
> auf diesen Pins exitiert kein Timer 5 Ausgang weder im BGA noch im TQFP
> Gehäuse
Arduino Mega R3 Pin Benennungsschemata, du Tropf.

: Bearbeitet durch User
von Chris H. (Firma: Selbständig Denkender) (keiningenieur)


Lesenswert?

Arduino F. schrieb:
> Chris H. schrieb:
>> auf diesen Pins exitiert kein Timer 5 Ausgang weder im BGA noch im TQFP
>> Gehäuse
> Arduino Mega R3 Pin Benennungsschemata, du Tropf.

Selber du Tropf schau ins Datenblatt Seite 2 und 4!!! Napf

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Chris H. schrieb:
> schau ins Datenblatt
Warum sollte in einem AVR Datenblatt das Arduino Benennungsschema 
verewigt sein, du Tropf ....

Siehe: 
https://www.arduino.cc/reference/de/language/functions/analog-io/analogwrite/
Zeile mit "Mega".


Oder:
https://community.element14.com/cfs-file/__key/communityserver-wikis-components-files/00-00-00-02-65/0358.contentimage_5F00_112867.jpg
Auch hier Pin 44 bis 46

von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

Chris, du musst nicht an die Decke gehen wenn du nicht erkennst was Fakt 
ist. Arduino F. hat es dir doch schon mit dem Zaunpfahl gesagt. Es gilt 
die Arduino Pin-Nummerierung. Dafür reichen 2 Informationen. Thread 
Titel und im Programm die Existenz von setup() und loop(). Letzteres ist 
entscheidend.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Veit D. schrieb:
> du musst nicht an die Decke gehen

Das ist ein "Selbständig Denkender".
Konventionen interessieren ihn nicht.

Genau so wenig wie Threadtitel und Dokumentationen.
Beim "selbständig denken" nerven solche Fakten nur!
Aber Umschlüsselungen sind auch wirklich schwer zu verstehen....
Abstraktion, igitt!

: Bearbeitet durch User
von Chris H. (Firma: Selbständig Denkender) (keiningenieur)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> Chris, du musst nicht an die Decke gehen wenn du nicht erkennst was Fakt
> ist.
Arduino F. schrieb:
> Arduino Mega R3 Pin Benennungsschemata, du Tropf.

wer ging hier als erstes an die Decke ohne mal nachzudenken das vllt die 
HW defekt ist ??  LOL :P

von Chris H. (Firma: Selbständig Denkender) (keiningenieur)


Lesenswert?

Arduino F. schrieb:
> Genau so wenig wie Threadtitel und Dokumentationen.
> Beim "selbständig denken" nerven solche Fakten nur!
> Aber Umschlüsselungen sind auch wirklich schwer zu verstehen....
> Abstraktion, igitt!

ja dann verrate doch das Problem wo der TE dies liegen hat wenn 
Timerkanal 5 A/B nicht funzen obwohl dies zu Timer 4 identisch 
beschrieben ist!!

Kommm jetzt will ich wissen wo der Fehler liegt!! Grins

: Bearbeitet durch User
Beitrag #7455747 wurde vom Autor gelöscht.
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Chris H. schrieb:
> ohne mal nachzudenken das vllt die
> HW defekt ist ??  LOL :P

Du Tropf!
Die Hardware wurde mit analogWrite() getestet.
Damit kann es nur die fehlerhafte Registerbesetzung (Timer/Pin 
Konfiguration) sein.

Tipp:
Erst Eingangs Posting lesen und verstehen.
Dann die Denke einschalten.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

das mit der Rechnung ist leider nur ein Fehler. Hauptgrund für die 
Nichtfunktion ist der fehlende Eintrag im struct für Compare C. Die 
Timer laufen übrigens im Timer-Mode 10, der Kommentar dazu stimmt, wenn 
im Code auch nur schwer ersichtlich.

Zum testen reduziert und runtergebrochen. Alle 3 Timer 5 Pins takten.

Die Registeradressen im struct wird der TO so noch nicht verwenden 
können. Das als Warnung. Noch ein Tipp an den TO. Gewöhne dir an die 
Indexvariable der for Schleifen lokal zu belassen. Es gibt meistens 
keinen Grund für außerhalb. Du sparst dabei auch nichts, dafür kommen 
mehr Fehlerquellen hinzu.

In der welcher IDE programmierst du überhaupt?
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <arduino.h>
4
5
const uint8_t  MAX_LINES = 3;
6
const uint8_t  NO_INPUT =  0;
7
const uint8_t  DIGITAL_INPUT = 1;
8
const uint8_t  ANALOG_INPUT = 2;
9
const uint16_t PWMFreq = 720; // output PWM frequency (Hz)
10
11
uint16_t ICR16Val;
12
13
void setup()
14
{
15
  ICR16Val = 16000000 / PWMFreq / 2;    // set Phase PWM
16
17
  ////////////////////////////////////////////////////
18
  struct MyLine
19
  {
20
    uint8_t OutPort;        // pin number of pwm output port
21
    uint8_t Timer;          // assigned timer
22
    uint16_t  OCRReg;       // Adresse Output Compare Register  //
23
    uint16_t  TCCRAReg;     // Adresse Output Compare Register //
24
    uint16_t  TCCRBReg;     // Adresse Output Compare Register //
25
    uint8_t Comxy;          // bitmask
26
  };
27
28
  struct MyLine Lines[MAX_LINES]
29
  {
30
    44,   5,  0x12C, 0x120, 0x121, COM5C1,
31
    45,   5,  0x12A, 0x120, 0x121, COM5B1,
32
    46,   5,  0x128, 0x120, 0x121, COM5A1
33
  };
34
35
  // Initialize input and output ports (Arduino Pins)
36
  for (int i = 0; i < MAX_LINES; i++)
37
  {
38
    pinMode(Lines[i].OutPort, OUTPUT); // Initialize all PWM output port
39
  }
40
41
  ////////// Timer 5 ///////////
42
  TCCR5A = TCCR5B = TCCR5C = 0;
43
44
  for (int i = 0; i < MAX_LINES; i++)
45
  {
46
    TCCR5A |= _BV(Lines[i].Comxy);
47
  }
48
49
  TCCR5A |= (1 << WGM51);   // result: TCCR5A =  0b10100010, activate pins A/B, wave generation mode phase PWM mode 10
50
  TCCR5B =  0b00010001;     // timer = system clock, Divisor = 1
51
  ICR5 = ICR16Val;          // timer = system clock, Divisor = 1
52
  OCR5A = ICR5 * 0.3;       // set duty-cycle
53
  OCR5B = ICR5 * 0.2;       // set duty-cycle
54
  OCR5C = ICR5 * 0.1;       // set duty-cycle
55
}
56
void loop()
57
{
58
59
}

: Bearbeitet durch User
von Harald F. (boimler)


Lesenswert?

Danke!!

Es war natürlich ein blöder Lesefehler, aber ab einem bestimmten Punkt 
bei der Fehlersuche brauchte ich offenbar Hilfe :-).
Die "Abstraktion" im Code kommt natürlich auch von meinem Shield, der 
die verfügbaren Kanäle von 1-10 numeriert. Ich habe die struct nun so 
angepasst (s.u.) und natürlich das OCR5C verwendet.
Die anderen Spalten/Arduino Pins waren hier nicht wichtig, da sie nur 
auf der Eingangsseite zum tragen kommen - auf den Pins lese ich die 
TP-Filter der Schaltung aus bzw. zähle high und low direkt aus 
(alternativ). Beides geht sehr schön und jetzt tuts auch der Ausgang 
vollständig.

Anpassungen:
struct MyLine Lines[MAX_LINES] Zeile 9:
DIGITAL_INPUT,  A9, 48, 44,   5,  0x128, 0x120, 0x121, COM5C1, 30,

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.