ich bekomme einfach keinen klaren neuen Anfang. Kanal C scheint auch noch was besonderes zu sein.
Ich lade die Compare Match Register von A/B/C unterschiedlich.
Bekomme die zeitlichen Unterschiede durch einmaliges Toogle an den OC1x Pins zu sehen.
Siehe Screenshot oben.
Aber egal was ich versuche, ich bekomme den Zähler nicht definiert vorzeitig zurückgesetzt.
Nullen kann ich den, aber dann haut gar nichts mehr hin.
Auch den TCNT1 Zähler auf 65535 (oder 65000 damit man eine Änderung sieht) hilft nicht.
Eigentlich müßte man nur im ISR Aufruf vom langsamsten Kanal den Zähler oder ein Flag zurücksetzen.
Ideen?
so langsam verliere ich die Lust.
Der OCIE1x (Timer Compare Interrupt) von A/B sind ausgeschalten. Normalerweise dürfte A/B gar nicht takten.
Tun sie aber laut Screenshot mit genau dem Code hier.
Nehme ich den ISR COMPC Vector dazu, takten alle 3 Kanäle gleich, leicht verschoben mit irgendeiner Frequenz ohne mein Einfluss.
/*
01.07.2015
Doc Arduino - german arduino.cc Forum
Arduino Mega2560
*/
// globale Variablen
boolean _toggle_T1 = LOW;
const byte _LED = 8;
long _CounterA;
long _CounterB;
long _CounterC;
// Funktionen deklarieren
void set_Timer1_CMR();
void setup() {
Serial.begin(38400);
pinMode(_LED, OUTPUT); // max. 36 bzw. 170kHz
pinMode(11, OUTPUT); // Pin von OC1A > Pin 11 Mega2560 (max. 8MHz)
pinMode(12, OUTPUT); // Pin vom OC1B > Pin 12 Mega2560 (max. 8MHz)
// beim Uno sind das Pin 9 und 10
pinMode(13, OUTPUT); // Pin vom OC1C > Pin 13 Mega2560 (max. 8MHz)
set_Timer1_CMR(); // gewünschte Taktfrequenz in Hz - bei Bedarf mit einer Kommastelle
// 0.2 bis 36kHz bzw. 170kHz bzw. 8MHz)
} // Ende Setup
void loop() {
// do other things here
}
// *** Funktionen *** ----------------------------------------------
void set_Timer1_CMR() // Normal Mode, kein CTC
{
cli(); //stop interrupts
// set Timer-1 Register
TCCR1A = 0; // Reset TCCR1A Register
TCCR1B = 0; // Reset TCCR1B Register
TIMSK1 = 0; // Reset TIMSK1 Register (disable Timer Compare Interrupts)
TCNT1 = 0; // initialize counter value to 0
TCCR1A |= (1 << COM1A0); // set Toggle OCnA Pin on compare match > Pin 11 Mega2560
TCCR1A |= (1 << COM1B0); // set Toggle OCnB Pin on compare match > Pin 12 Mega2560
TCCR1A |= (1 << COM1C0); // set Toggle OCnC Pin on compare match > Pin 13 Mega2560
OCR1A = 10000; // Compare Match Register A
OCR1B = 15000; // Compare Match Register B
OCR1C = 20000; // Compare Match Register C
//TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // set Prescaler 8
//TIMSK1 |= (1 << OCIE1A); // enable Timer Compare Interrupt A
//TIMSK1 |= (1 << OCIE1B); // enable Timer Compare Interrupt B
TIMSK1 |= (1 << OCIE1C); // enable Timer Compare Interrupt C
sei(); //allow interrupts
} // end Funktion
/*
ISR(TIMER1_COMPC_vect) { // Timer 1.C Interrupt
TCNT1 = 65500;
}
*/
Weil du "PORTH =" machst und damit den ganzen Port überschreibst. Egal was vorher drin stand. Dass eine 0 schieben nichts bringt war vor allem in Zusammenhang mit |= oder gemeint. Das kam wohl nicht so richtig rüber.
Ob das Unsinn ist oder nicht: in PORTB werden auf jeden Fall immer 7 Bit auf 0 gesetzt und das oberste wechselt zwischen 0 und 1
7 Bits unververändert lassen, geht anders 8)
Ich würde das Ganze auch nach setup packen, damit erst gar keiner auf die Idee kommt, loop() würde hier verwendet
vegiß das einfach, in dem einen Fall klappt es, allgemein ist es nur Müll Code. Da habt ihr beide schon recht. Wie gesagt, einfach vergessen. Hier soll es weiterhin um den Timer gehen.
so, hab's endlich geschafft, ging aber nur mit fremder Hilfe, bin fremd gegangen bei unseren Kumpel's, sorry , und habe dabei viel gelernt. Zum Bsp. das man einen Interrupt Handler auch schreiben muß wenn man einen Interrupt aktiviert. Ansonsten resetet sich der µC, weil er ins leere springt. Das war die Haupthürde die es zu nehmen galt. Der Rest war Programmierkunst der helfenden Leute.
Das sieht dann zum Bsp. so aus. Mit fest vorgegebenen Compare Match Werten gehts noch etwas schneller, aber damit eben ohne automatische Berechnung, was keinen Sinn macht. Vielleicht gehts doch, wenn man nach der Berechnung der Compare Werte dem Compiler sagen kann das diese ab dem Zeitpunkt konstant sind. Dazu müßte man wissen wie man aus einer lokalen Variable eine Konstante macht. Mehrfach (um)definieren geht ja nicht.
Doc_Arduino:
Zum Bsp. das man einen Interrupt Handler auch schreiben muß wenn man einen Interrupt aktiviert. Ansonsten resetet sich der µC, weil er ins leere springt.
Ja, jetzt wo du das sagst ist das eigentlich selbstverständlich. Gewusst habe ich das schon. Darauf gekommen das dann auch hier anzuwenden bin nicht
Das hat sich auch von Version zu Version geändert. Mal hattest du eine ISR definiert. Mal nicht.
Das TIMSK1 |= (1 << OCIE1A); im switch/case kannst du dir übrigens sparen. Da machst du schon einmal außerhalb
als ich das mit den Interrupts dann wußte, dachte ich auch im ersten Moment, na Mensch, dass hätte doch mal jemand sagen können. Aber durch das rumprobieren immer mal Interrupts auskommentiert und wieder reingenommen, konnte ein fremder schlecht alles im Überblick behalten. Mach Dir keine Sorgen.
Das mit dem constexpr brauche ich wohl nicht mehr. Aber gut zu wissen das es möglich ist. Danke dafür.
Denn unsere Kumpels haben mir nochwas gezeigt. Man toggelt das Port Register einfach durch. Damit sind alle bis zum max. möglichen Takt auf die Flanke synchron und man beschäftigt nur einen Interrupt. Außerdem ist man nicht mehr auf die 3 Timer Toggle Pins beschränkt. Man kann irgendein freien Port nehmen und bis zu 8 Pins schalten lassen. Sieht dann am Ende wie ein Binärzähler aus.
Allerdings muß ich Euch nochmal fragen, denn es gibt bei näherer Betrachtung der Takte unschöne Anomalien im Takt. Immer fast genau auf eine ms genau, egal welcher Wert das Compare Match Register bekommen hat. Das Problem besteht nur wenn ich den Code Arduino gerecht schreibe. Schreibe ich das in reinen C gibt es keine erkennbaren Störungen. Nur die loop ist ja leer, wo ich nun dachte das die reinfunkt.
ich werde das testen, nur schreibe und uploade ich den Code von beiden in der IDE aus. Sollte da nicht Timer 0 immer mitlaufen .... wir werden gleich sehen ...
Tatsache, wenn Timer 0 ausgeschalten wird, klappt das. Nun verrate mir mal einer woher weis die IDE ob Timer 0 laufen soll oder nicht. Guckt die nach ob setup und loop vorkommt?
so Leute, hab das jetzt mit der automatischen Berechnung kombiniert. Funktioniert.
Mußte dabei aber leider feststellen, dass mein Logikanalyser auf Kanal 3 und 7 einen Treffer weg hat.
Selbst durch Kabel umstecken zeigen immer diese beiden Müll an. China eben.
Ansonsten funktioniert der Code. Kann ja mal jemand testen mit Logik-Analyzer.