Hallo Leute, ich arbeite derzeit an einem Projekt mit einem Arduino Due (Cortex M3). Es soll in ferner Zukunft mal zu einem Laborversuch o.Ä. werden. Daher hole ich kurz aus. Es geht darum, ein gesampeltes Signal via Interrupts als PWM zu modulieren. Wo das Signal herkommt ist erstmal irrelevant. Zum Testen reicht bspw. auch schon ein array mit x Werten. Ich habe mir für den Zweck eine cpp Klasse geschrieben, mit welcher ich problemlos Frequenz, Auflösung und Dutycycle beliebig einstellen kann. Die Interrupts sind soweit auch vollkommen funktionsfähig, jedoch würde ich das Ganze gerne im "Arduinostyle" verpacken. Mit der Funktion "attachInterrupt()" kann man bekanntlich einen Pin zum Interruptdetektor machen und eine ISR schreiben, welche dann aufgerufen wird. In meinem Fall sind die Interrupts jedoch von den Timern und daher intern. Wie muss ich den "echten" TCx_Handler befüllen, damit ich eine Funktion wie attachInterrupt() für die TC Handler bauen kann? In der main.cpp soll also ein beliebiger Name möglich sein, welche einfach in einer Methode/ Funktion übergeben wird. Folgender Code ist mein Wunschszenario: #include <Arduino.h> #include "pwmWrite.h" #include "mainheader.h" pwmWrite OBJECT_NAME; // creating class uint16_t signal_TC[NUM_OF_SAMPLES] = { ... }; uint32_t sampleNo = 0; // position in sample array uint32_t pwm_pin = 3; uint16_t resolution = 1024; // == TC uint32_t frequency = 41000; // PWM frequency uint16_t duty = (resolution / 2); // 50 % duty cycle, start value // (more or less irrelevant which value is chosen here) void setup() { // put your setup code here, to run once: // -------------- what I what -------------------- // OBJECT_NAME.attachInterrupt(pwm_pin, myISR); // ----------------------------------------------- // /* Calls the setup method with the following values: * - pin for pwm output * - start value of the duty cycle * - resolution of the PWM (compatibility between different attributs) * - frequency of the PWM (after which period comes the duty cycle) * - start the PWM * - enable an interrupt after each period */ OBJECT_NAME.setup(pwm_pin, duty, resolution, frequency, true, true); } void loop() { // put your main code here, to run repeatedly: } // -------------------------------------------------- // void myISR() { if(sampleNo == NUM_OF_SAMPLES) sampleNo = 0; // continous sample rotation OBJECT_NAME.duty(pwm_pin, signal_TC[sampleNo]); sampleNo++; } // ------------------------------------------------- // Derzeit läuft das Ganze noch in den normalen Handlern, in einem zweiten src file ab (alle Handler von TC0 bis TC8 sind gleich): void TC1_Handler() { TC0 -> TC_CHANNEL[1].TC_SR; // clear and read status register if(sampleNo == NUM_OF_SAMPLES) sampleNo = 0; // continous sample rotation OBJECT_NAME.duty(pwm_pin, signal_TC[sampleNo]); // write new duty cycle with value of sample sampleNo++; // go to next sample } Falls das von Interesse ist, kann ich auch die pwmWrite Klasse noch anhängen. Die müsste ich aber noch ein wenig aufarbeiten mit Kommentaren. Das NVIC_EnableIRQ() ist auch dort im setup geregelt. Wie gesagt, es funktioniert alles einwandfrei, ich habe nur Probleme mit dem Feature, dass man eine eigene ISR schreiben und vor Allem beliebig benennen kann. Für etwaige Hilfe wäre ich sehr dankbar, schon irgendwelche Denkanstöße in welchen Themen ich mich über sowas schlaulesen kann würden mir helfen. Gruß, Yuba
Yuba schrieb: > In der main.cpp soll also ein beliebiger Name möglich sein, welche > einfach in einer Methode/ Funktion übergeben wird. Das nennt sich CallBack. Das kann man entweder über Funktionszeiger/LambdaFunktionen machen oder in dem man das Subject-Observer Pattern implementiert.
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.