Arduino Mega R3 PWM funktioniert nicht für Timer 5 (A), Pin 44

#7455430
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

Angehängte Dateien:
Beitrag #7455437 wurde von einem Moderator gelöscht.
#7455471
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 = ICR40.6; // set duty-cycle OCR4B = ICR40.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 = ICR50.3; // set duty-cycle OCR5B = ICR50.2; // set duty-cycle OCR5C = ICR5*0.0; // set duty-cycle

(Firma: hier&da) #7455487
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 im Beitrag #7455471:

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

(Firma: Gast) #7455729
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

#7455730
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.

Angehängte Dateien:
(Firma: hier&da) #7455741
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

Beitrag #7455747 wurde von einem Moderator gelöscht.
#7455820
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
}
#7456117
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,

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