mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega1281 - Timer 3 (4,5) - CTC-Mode 4 oder 12 - 2 Probleme / Fehler


Autor: Joan P. (joan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich weiß nicht woran es liegt, weil sich für mich an zu vielen Stellen 
zu viele Fragen aufwerfen, aber vielleicht kann jemand mit mehr Ahnung 
ja eher etwas damit anfangen.

_Ziel:_ 16Bit Timer 3 (4 oder 5) mittels CTC Mode 4 (oder 12) als 
Interrupt mit modifizierter Auflösung nutzen.

_Idee:_ Da die Timer/Counter 4 und 5 keine Ausgangspins haben, würden 
sie sich für interne Interrupts mit selbstgemachter Auflösung eignen 
(Overflow Interrupt).

_Problem:_ Zitat Datenblatt ATmega1281, S.136: "Timer/Counter4 and 
Timer/Counter5 only have full functionality in the ATmega640/1280/2560. 
Input capture and output compare are not available in the 
ATmega1281/2561..."
Mir ist durchaus bewusst, dass ich beim 1281'er für T/C4&5 für Mode 12 
nichts erwarten darf, weils ja im Datenblat steht, aber schließt das 
Zitat den Modus 4 (CTC mit OCRnA als TOP) für T/C 4&5 auch aus?

_Die Probleme betrifft in der Form aber vor allem AUCH Timer 3, und da 
fängts für mich an._

/Ich benutzte Timer0 im Fast-PWM Modus und Pin 17 (PB7) als Ausgang für 
die Anzeige über eine 2 farbige LED (OCR0A=0 -> grün, OCR0A=255 -> rot). 
Wenn ich OCR0A mit diesen Werten beschreibe leuchtet es auch 
entsprechend. Der Ausgang wird zusätzlich mit Oszi beobachtet.. ich kann 
also sehen wie die PWM aussieht.

Die PowerReductionRegsiter-Bits für die Timer sind alle auf 0 -> Timer 
also aktiv./

Problem 1: Modus 4 (CTC mit OCR3A) läuft nur mit "OCR3A = 0xFFFF", 
sämtliche anderen Werte werden ignoriert.. das dürfte schon mal nicht 
passieren.
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

int main (void)
{
  PORTB |= (0<<PB7); // hier läuft der LED-PWM drauf
  DDRB |= (1<<DDB7);
  // Timer0 (8Bit): FastPWM-Mode(3), TOP = 0xFF, OCR0A als CompareMatch für PWM, Prescaler 1
  TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(1<<WGM00);
  TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);

  sei(); // Interrupts global ein
  PRR1 |= (0<<PRTIM3); // Timer Modul ON
  TIMSK3 |= (1<<TOIE3); // Overflow Interrupt ein
  TCCR3B |= (0<<WGM33)|(1<<WGM32)|(1<<CS31); // Mode 4, Prescaler 1/8

  OCR3A = 0xFFFF; // OutputCompareRegister Vergleichswert setzen, andere Werte zB. 0xFFFE gehen nicht!

  TCNT3 = 0x0000; // Timer/Counter4 Zählregister Reset
  OCR0A = 10; // Alive-Signal: grün
  while (1) // Loop forever
  { }
    return (0);
} 

ISR (TIMER3_OVF_vect)
{
OCR0A = 245; // Alive-Signal: rot
}

Ich hab auch schon versucht OCR3A jeweils nur 8 Bit weise zu schreiben..
Erst OCR3AH mit 0xFF und dann OCR3AL mit 0xFF -> funktioniert, der 
Interrupt kommt.
Nimmt man stattdessen andere Werte geht es nicht mehr, der Interrupt 
bleibt aus.
Das gleiche gilt für Timer 4 und 5.


Problem 2: Modus 12 (CTC mit ICR) ISR-Funktion läuft nur mit 
"_VECTOR(41)" anstatt "TIMER4_CAPT_vect".. wäre mit dem Zitat erklärbar. 
Insofern überfahre ich sicher mit meinem _VECTOR(41) irgendwelche 
Einstellungen in den Makros. Allerdings wär das nur die Notlösung, weil 
ja Overflow-Interrupt nicht geht.. nur deshab führe ichs überhaupt auf.
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

int main (void)
{
  PORTB |= (0<<PB7); // hier läuft der LED-PWM drauf
  DDRB |= (1<<DDB7);
  // Timer0 (8Bit): FastPWM-Mode(3), TOP = 0xFF, OCR0A als CompareMatch für PWM, Prescaler 1
  TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(1<<WGM00);
  TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);

  sei(); // Interrupts global ein
  PRR1 |= (0<<PRTIM4); // Timer Modul ON
  TIMSK4 |= (1<<ICIE4); // InputCapture Interrupt ON
  TCCR4B |= (1<<WGM43)|(1<<WGM42)|(1<<CS41); // Mode 12, Prescaler 1/8
  ICR4H = 0xAF; // InputCaptureRegister Vergleichswert setzen
  ICR4L = 0x00; 
  TCNT4 = 0x0000; // Timer/Counter4 Zählregister Reset
  OCR0A = 10; // Alive-Signal: grün
  while (1) // Loop forever
  { }
    return (0);
} 

ISR (_VECTOR(41)) // wenn da "TIMER4_CAPT_vect" drin steht, gehts nicht..
{
OCR0A = 245; // Alive-Signal: rot
}

Mit anderen Worten, schön das es mit _VECTOR(41) geht, aber darauf 
verlassen sollte ich mich nicht, oder?
Mit Timer 3 funktioniert Mode 12 (CTC mit ICR) ohne diesen Trick, also 
direkt mit "TIMER3_CAPT_vect".

Danke für eure Hilfe
Joan

[Edit, Overflow statt Output Compare solls ja sein]

Autor: Joan P. (joan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nebenbei.. wieso geht die Text-Formatierung nicht, wie hier angegeben:
http://www.mikrocontroller.net/articles/Formatieru...?

Autor: Joan P. (joan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich nochmal..

Streicht Problem 2.. das ist halt so.

Aber Problem #1 macht mich fertig..
Wenn da jemand was zu sagen könnte, wärs nett.

Danke

Autor: Joan P. (joan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mittlerweile bin ich drauf gekommen, dass man anstatt des 'Timer x 
Overflow Interrupts' den 'Timer x Output Compare A Interrupt' nehmen 
kann/muss/soll, wenn man nen Interrupt bei TCNTn == OCRnA haben will..

Laut Datenblatt sind die Timer 4&5 Compare A/B/C Vektoren für den 
1281'er auch nicht gesperrt, das betrifft nur die ICP-Vektoren (Seite 
106 im Datenblatt). Insgesamt kommts mir wegen dem ganz am Anfang 
geposteten Zitat, wegen der Output Compare Units, zwar immer noch 
"spanisch" vor aber nu läufts..
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>

int main (void)
{
  PORTB |= (0<<PB7);
  DDRB |= (1<<DDB7);
//PORTB |= (1<<PB7); // Alive-Signal: HIGH
  // Timer0 (8Bit): FastPWM-Mode(3), TOP = 0xFF, OCR0A als CompareMatch für PWM, Prescaler 1
  TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(1<<WGM00);
  TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);

  // Timer5: CTC-Mode(4), TOP = OCR5A, Prescaler 1/8 (1µs per cycle), nix externes, OCM-Interrupt (über WGM..)
  TCCR5A = (0<<COM5A1)|(0<<COM5A0)|(0<<COM5B1)|(0<<COM5B0)|(0<<COM5C1)|(0<<COM5C0)|(0<<WGM51)|(0<<WGM50);
  TCCR5B = (0<<ICNC5)|(0<<ICES5)|(0<<WGM53)|(1<<WGM52)|(0<<CS52)|(1<<CS51)|(0<<CS50);
  TCCR5C = (0<<FOC5A)|(0<<FOC5B)||(0<<FOC5C);
  PRR1 = (0<<PRTIM5);
  OCR5A = 0x07d0; // Timer 5 mit 2000µs OCM_A-Interrupt starten
  TCNT5 = 0x0000; // Timer/Counter5 Zählregister reset
  TIFR5 = (1<<OCF5A); // Timer 5 Output Compare A Flag löschen
  TIMSK5 = (1<<OCIE5A); // Timer 5 Output Compare A Interrupt aktivieren

  sei(); // Interrupts global ein

  OCR0A = 10; // Alive-Signal: grün

  while (1) // Loop forever
  { }
    return (0);
} 

ISR (TIMER5_COMPA_vect)
{
//PORTB &= ~(1<<PB7); // Alive-Signal: LOW
OCR0A = 245; // Alive-Signal: rot
}

Grüsse

PS: Falls jemand noch ne Meinung dazu hat, ich würd sie gerne lesen ;-)

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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