Hallo Leute, ich spiele mich gerade ein wenig mit dem CTC-Modus des ATMega16. Dieser Chip hat 3 Timer: T0-8bit, T1-16bit & T2-8bit. Dabei ist mir nach einigen Programmabstürzen und Fehlersuche erst aufgefallen, dass die jeweiligen Overflow-Zählregister TCNT0-2 als unsigned 8bit/16bit definiert sind, jedoch die CTC Register OCR0-2 als signed 8bit/16bit. Auszug aus dem Datenblatt: TCNT2 – Timer/Counter Register The Timer/Counter Register gives direct access, both for read and write operations, to the Timer/Counter unit 8-bit counter. OCR2 – Output Compare Register The Output Compare Register contains an 8-bit value that is continuously compared with the counter value (TCNT2). Dazu meine 1.Frage: Gibt es einen Weg diese Overflow Zähler auch als unsigned Variablen zu verwenden? Irgendwie finde ich es ansonsten ein wenig verwirrend, wenn ich für ein Interrupt aus einem 8bit Timer einen kleineren Wert als 255(Overflow - TCNT) bräuchte, den Werte bereich zwischen 127 und 255 aber mit dem OCR-Zähler aber nicht abdecken kann. Oder habe ich da einen Denkfehler? Meine 2.Frage betrifft den Timer1(16bit) CTC-Modus: Laut Datenblatt gibt es 2 Zählregister für den CTC-Modus, nämlich OCR1A und OCR1B. Also war meine 1. Vermutung, dass es mit Timer1 möglich ist 2 unterschieldiche CTC-Aufrufe zu generieren. Auch in den Interface-Files werden die entsprechenden Vektoren definiert (TIMER1_COMPA_vect/TIMER1_COMPB_vect) um ein Interrupt aufzurufen, wenn die entsprechnende Flag gesetzt wird. Jedoch findet sich im Datenblatt keine Einstellungsmöglichkeit in den Registern TCCR1A und TCCR1B, den TCNT1 Wert mit dem OCR1B Wert zu vergleichen und somit einen CTC-Modus mit OCR1B zu realisieren (im Datenblatt Table 16-5). Und auch von der Überlegung her wäre es komisch 2 CTC-Events über nur einen Hauptzählwert (TCNT1) zu generieren, da dieser, wenn ich es richtig verstanden habe, nach einem erfolgreichen CTC-Match wieder auf 0 gesetzt wird. Kann mir jemand erklären was es mit diesem OCR1B Wert auf sich hat und für was dieser verwendet werden könnte bzw. ob es vielleicht doch möglich ist aus einem Timer gleichzeitig 2 CTC-Events zu erzeugen? Danke und LG
Max P. schrieb: > Dazu meine 1.Frage: > ... > Denkfehler? Ja. Im gesamte Timer-Kapitel im Datenblatt kommt der Begriff „signed“ nicht ein einziges Mal vor. > Meine 2.Frage betrifft den Timer1(16bit) CTC-Modus: > Laut Datenblatt gibt es 2 Zählregister für den CTC-Modus, nämlich OCR1A > und OCR1B. > ... > ob es vielleicht doch möglich ist > aus einem Timer gleichzeitig 2 CTC-Events zu erzeugen? Datenblatt (oder das passende Tutorial deiner Wahl) nochmal lesen, was genau der CTC-Modus ist, und wie er funktioniert, und die dazu Tabelle mit den Betriebsarten (alle 16). Dann beantwortet sich die Frage von alleine. Oliver
Max P. schrieb: > Laut Datenblatt gibt es 2 Zählregister für den CTC-Modus, nämlich OCR1A > und OCR1B. Ich vermute, bei dir liegt ein grundlegendes Missverständnis der Register-Funktionen vor. Dies sind keine Zählregister, sondern (siehe Datenblatt): Output Compare Registers Das Zählregister (ein einziges) ist TCNT1. Vorschlag: versuche, mit Atmel Start die Register für die von dir gewünschte Funktion zu initialisieren. Da hast du ein (mehr oder weniger sinnvoll angeordnetes) Formular, das (hoffentlich) die Funktion der Register etwas klarer macht. Das liefert dir auch Dummy-Interruptroutinen, die du selbst weiter füllen kannst.
Max P. schrieb: > Jedoch findet sich im Datenblatt > keine Einstellungsmöglichkeit in den Registern TCCR1A und TCCR1B, den > TCNT1 Wert mit dem OCR1B Wert zu vergleichen und somit einen CTC-Modus > mit OCR1B zu realisieren (im Datenblatt Table 16-5). Braucht es nicht, die beiden Vergleiche und Flags setzen finden immer statt. Ein Clear ist natürlich nur mit einem Compareregister sinnvoll, sonst würde ja das größere nie erreicht.
Oliver S. schrieb: > Max P. schrieb: >> Dazu meine 1.Frage: >> ... >> Denkfehler? > > Ja. Im gesamte Timer-Kapitel im Datenblatt kommt der Begriff „signed“ > nicht ein einziges Mal vor. In der Software verhält sich der OCRx-Wert allerdings wie ein signed 8bit Wert, d.h. wenn ich versuche 127 zuzuweisen funktioniert alles, mit z.B. 128 steht im OCRx auf einmal ein negativer Wert. Hatte gestern keine Zeit mehr das nocheinmal zu testen. >> Meine 2.Frage betrifft den Timer1(16bit) CTC-Modus: >> Laut Datenblatt gibt es 2 Zählregister für den CTC-Modus, nämlich OCR1A >> und OCR1B. >> ... >> ob es vielleicht doch möglich ist >> aus einem Timer gleichzeitig 2 CTC-Events zu erzeugen? > > Datenblatt (oder das passende Tutorial deiner Wahl) nochmal lesen, was > genau der CTC-Modus ist, und wie er funktioniert, und die dazu Tabelle > mit den Betriebsarten (alle 16). > Dann beantwortet sich die Frage von alleine. Ok, werde ich mir nochmal durchlesen. > Oliver
Dieter R. schrieb: > Max P. schrieb: > >> Laut Datenblatt gibt es 2 Zählregister für den CTC-Modus, nämlich OCR1A >> und OCR1B. > > Ich vermute, bei dir liegt ein grundlegendes Missverständnis der > Register-Funktionen vor. Dies sind keine Zählregister, sondern (siehe > Datenblatt): > > Output Compare Registers > > Das Zählregister (ein einziges) ist TCNT1. > > Vorschlag: versuche, mit Atmel Start die Register für die von dir > gewünschte Funktion zu initialisieren. Da hast du ein (mehr oder weniger > sinnvoll angeordnetes) Formular, das (hoffentlich) die Funktion der > Register etwas klarer macht. Das liefert dir auch > Dummy-Interruptroutinen, die du selbst weiter füllen kannst. Ah, sorry. Das hab ich komplett falsch beschrieben. Da bin ich mit den, für mich neuen, Bezeichnungen durcheinander gekommen. Danke für den Tipp mit Atmel Start, das kannte ich noch gar nicht. Werde ich mir ansehen. LG
Max P. schrieb: > In der Software verhält sich der OCRx-Wert allerdings wie ein signed > 8bit Wert, d.h. wenn ich versuche 127 zuzuweisen funktioniert alles, mit > z.B. 128 steht im OCRx auf einmal ein negativer Wert. Hatte gestern > keine Zeit mehr das nocheinmal zu testen. Da stimmt irgendetwas nicht. In was programmierst Du? Zeig mal Deinen Quellcode. Die Register beim ATMega16 werden definitiv nicht als signed angesprochen. Ehrlich gesagt kenne ich überhaupt keinen Mikrocontroller, bei dem Signed-Werte für Register verwendet werden (außer vielleicht Fliesskomma-Einheiten).
Peter D. schrieb: > Max P. schrieb: >> Jedoch findet sich im Datenblatt >> keine Einstellungsmöglichkeit in den Registern TCCR1A und TCCR1B, den >> TCNT1 Wert mit dem OCR1B Wert zu vergleichen und somit einen CTC-Modus >> mit OCR1B zu realisieren (im Datenblatt Table 16-5). > > Braucht es nicht, die beiden Vergleiche und Flags setzen finden immer > statt. > Ein Clear ist natürlich nur mit einem Compareregister sinnvoll, sonst > würde ja das größere nie erreicht. Dieser Timer fuchst mich noch ein wenig, aber danke für die Erklärung! Langsam wirds^^
Chris D. schrieb: > Die Register beim ATMega16 werden definitiv nicht als signed > angesprochen. Er wird sich halt eine signed Variable anzeigen lassen die den Register-Wert beinhaltet.
Chris D. schrieb: > Max P. schrieb: >> In der Software verhält sich der OCRx-Wert allerdings wie ein signed >> 8bit Wert, d.h. wenn ich versuche 127 zuzuweisen funktioniert alles, mit >> z.B. 128 steht im OCRx auf einmal ein negativer Wert. Hatte gestern >> keine Zeit mehr das nocheinmal zu testen. > > Da stimmt irgendetwas nicht. > > In was programmierst Du? Zeig mal Deinen Quellcode. > > Die Register beim ATMega16 werden definitiv nicht als signed > angesprochen. > > Ehrlich gesagt kenne ich überhaupt keinen Mikrocontroller, bei dem > Signed-Werte für Register verwendet werden (außer vielleicht > Fliesskomma-Einheiten). Aktuell verwende ich Atmel Studio/C++. Werde ich machen, komme aber vor heute Nacht nicht zu meinem PC. LG
Max P. schrieb: > In der Software verhält sich der OCRx-Wert allerdings wie ein signed > 8bit Wert, d.h. wenn ich versuche 127 zuzuweisen funktioniert alles, mit > z.B. 128 steht im OCRx auf einmal ein negativer Wert. Hatte gestern > keine Zeit mehr das nocheinmal zu testen. In welcher Software? Oliver
Max P. schrieb: > jedoch die CTC Register OCR0-2 als signed 8bit/16bit. Nö. Alle IO-Register sind unsigned, siehe sfr_defs.h:
1 | #define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
|
2 | #define _MMIO_WORD(mem_addr) (*(volatile uint16_t *)(mem_addr))
|
3 | #define _MMIO_DWORD(mem_addr) (*(volatile uint32_t *)(mem_addr))
|
Chris D. schrieb: > In was programmierst Du? Zeig mal Deinen Quellcode. Oliver S. schrieb: > In welcher Software? Atmel Studio/C++ main.c [c] #include "Interface/Globals.h" #define DEBUG_Mode #ifdef DEBUG_Mode #pragma message("!!!Debug-Modus aktiviert!!! Fuer Mikrocontroller-Built deaktivieren!") #endif uint16_t ADC_Messergebnis = 0; bool flag_ADC_Messung_gestartet = false; bool flag_Taster_Abfrage_Aktiv = false; byte tmp_Buffer_Taster_val = 0; double x_double = 0; uint8_t x_uint = 0; int8_t x_int = 0; int main(void) { x_double = OCR2_VALUE; x_uint = OCR2_VALUE; x_int = OCR2_VALUE; OCR2 = OCR2_VALUE; tmp_Buffer_Taster_val = 1; return 0; } [c] globals.h [c] #include <avr/io.h> #include <stdint.h> #include <stdbool.h> #include <avr/interrupt.h> #include "../Interface/timing.h" #define F_CPU 14000000UL //6553600UL #define T_LED_TICK 10L //Zeit in "us" pro ISR-Aufruf #define USEC_IN_1SEC 1000000L //"us" in einer Sekunde #define CPU_Prescaler_T0 1L #define OCR2_VALUE ((F_CPU * T_LED_TICK) / (USEC_IN_1SEC * CPU_Prescaler_T0) - 1) #if OCR2_VALUE < 0 #warning "OCR2_value" kleiner als 0 #endif #if OCR2_VALUE > 255 #warning "OCR2_value" groesser als 255 #endif #include <util/delay.h> typedef uint8_t byte; [c] Habe den Fehler gefunden. Auf der Watchliste wird der OCRx-Wert als "int" ausgegeben, und statt z.B. 139 steht dann -117 da drinnen. Mit der Hex-Ausgabe stimmt der Wert. facepalm Siehe Bilder im Anhang. Peter D. schrieb: > Nö. > Alle IO-Register sind unsigned, siehe sfr_defs.h: Mega256Helper schrieb: > Er wird sich halt eine signed Variable anzeigen lassen die > den Register-Wert beinhaltet. Fast, habe die Typen-Definition im Ausgabefenster übersehen, aber danke für den Hinweis!
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.