Hallo! Ich weiß, das Thema ist hier schon etwa 999 mal durchgekaut worden, allerdings stehe ich vor einem "neuen" unlösbaren Problem. Ich habe 2 8Bit Counter. Diese werden gleichzeitig gestartet und enden gleichzeitig (ist ein Ausnahmefall, normalerweise laufen sie versetzt). Ich verwende einen Atmega8. Nun habe ich gelesen dass Interrupts, sollte einer ausgelöst werden während ein anderer gerade abgearbeitet wird, einfach beim nächsten ausgelösten Interrupt weitermachen. Also: Interrupt1 --> Wird Abgearbeitet --> 2ter Interrupt wird ausgelöst --> 1erste ISR ist fertig --> 2ter Interrupt wird abgearbeitet. Bei mir ist es aber so dass nur alle 5 Interrupts der 2te Timer angesprochen wird (Obwohl beim Softwaredebuggen ein Overflow angezeigt wird). Meine Frage: Sollte das normalerweise gehen? Eigentlich schon, oder? Ich muss zu meiner Schande zugeben dass ich eine Funktion in beiden ISR aufrufe die beim Portsetzen ein _delay_us(1) verwende, kann das für Verwirrung sorgen? Vielen Dank im Voraus und Verzeihung für das Wiederkauen eines schon viel zu oft besprochenen Themas.
Constantin Schieber schrieb: > Meine Frage: Sollte das normalerweise gehen? Eigentlich schon, oder? Kein Code, keine Antwort. :-)
> Sollte das normalerweise gehen?
Kommt drauf an. Wenn mans richtig(tm) implementiert schon.
Ein delay ist nur dann kritisch wenn die Ausführung der ISR (bzw. aller
ISR mit höherer Priorität als der 'Verlierer) länger dauert als bis zum
nächsten Interrupt, weil dann gewinnt jener gemäß Speckifikation (bzw.
jeder mit höherer Priorität als wie der 'Verlierer'). Sowas nennt man
'Verhungern' und zeugt von schlechtem (Software)Design (sofern es nicht
beabsichtigt ist ∗hust∗ :-)
HTH
1 | ISR (SIG_OVERFLOW0) |
2 | {
|
3 | generate_clk(CLK_R); //Gernerate Click for faster motor |
4 | d_tacts_r++; |
5 | if(d_tacts_r == r_tacts_r) |
6 | {
|
7 | TCCR0 = (0<<CS00) | (0<<CS01) | (0<<CS02); |
8 | }
|
9 | else
|
10 | TCNT0 = f_interrupt_r; |
11 | }
|
12 | |
13 | ISR (SIG_OVERFLOW2) |
14 | {
|
15 | generate_clk(CLK_L); //Gernerate Click for faster motor |
16 | d_tacts_l++; |
17 | if(d_tacts_l == r_tacts_l) |
18 | {
|
19 | TCCR2 = (0<<CS20) | (0<<CS21) | (0<<CS22); |
20 | }
|
21 | else
|
22 | TCNT2 = f_interrupt_l; |
23 | }
|
24 | /****************************************************************************
|
25 | Toggle Ports to generate clock for stepper
|
26 | ****************************************************************************/
|
27 | void generate_clk(char dir) |
28 | {
|
29 | cb(PORT_M, dir); |
30 | _delay_us(1); |
31 | sb(PORT_M, dir); |
32 | _delay_us(1); |
33 | }
|
Dass ist der Code. Also in diesen 3 Programmteilen manifestiert sich der Fehler (der Rest ist Berechnung von Drehzahlen, Winkeln etc). Ich denke nicht dass man das allzu falsch machen kann, die Initialisierung der Timer und die Berechnung des Overflows ist vielleicht auch noch interessant:
1 | unsigned short set_timer(short hz) |
2 | {
|
3 | return (unsigned short)(0xFF - (F_CPU / 1024 / hz)); //Set Timeroverflow, the higher hz is the faster an interrupt will be created |
4 | }
|
5 | |
6 | void init_Timer() |
7 | {
|
8 | //Ersten 8 Bit Timer initialisieren
|
9 | TCCR0 = (1<<CS00) | (1<<CS02); |
10 | TIMSK |= (1<<TOIE0); |
11 | //Zweiten 8 Bit Timer initialisieren
|
12 | TCCR2 = (1<<CS20) | (1<<CS22); |
13 | TIMSK |= (1<<TOIE2); |
14 | }
|
Ich bin mir jetzt eigentlich keiner höheren Schuld bewusst. Die Timer werden beim Programmaufruf initialisiert (Prescaler einstellen und Interrupts zulassen). Danach berechne ich wie oft ein Interrupt ausgelöst werden soll und das war's. Fühle mich also keiner (gröberen) Schuld bewusst, mal abgesehen davon dass es schrecklich programmiert ist und das ganze eigentlich über Multitasking (http://www.mikrocontroller.net/articles/Multitasking) gelöst gehört. Aber erstmal soll sich was tun, danach kann man das ganze schön machen! Danke für die schnelle Antwort übrigens!
Nur der Vollständigkeit halber: > TCCR0 = (1<<CS00) | (1<<CS02); und > TCCR2 = (1<<CS20) | (1<<CS22); liefern nicht die selben Presacler (1024 für Timer0 und 128 für Timer2). Falls das noch nicht des Problems Lösung ist: Was ist F_CPU. Wie hoch ist die Taktrate tatsächlich? HTH
Oh nein, ich bin ja so dumm!!! Vor lauter Suche nach einem extrem gefinkelten Fehler hab ich das vollkommen übersehen :( Danke Danke Danke, da starr ich minutenlang aufs Datenblatt und in die Doku und übersehe das einfach! :/ Also Danke nochmals und ein schönes Wochenende, Sie haben meinen Tag gerettet!!! :)
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.