Hey,
Bin neu im Form habe aber schon etwas Erfahrung mit der Programmierung
in C.
Wollte euch bitten mal meinen Code anzuschauen und mir sagen warum die
ISR nicht ausgeführt wird.
Vielen Dank für eure Hilfe
MfG.
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "ports_init_4bit.h"
volatile unsigned int millisekunde =0;
volatile unsigned int sekunde =0;
volatile unsigned int minute =0;
volatile unsigned int stunde =0;
int main(void)
{
INITIALISIERUNG_SYSTEMPORTS(); //Ports initialisieren
TCCR2=0b00001100;
OCR2=250-1;
sei(); //Global Interrupt Flag freischalten
TIMSK=(1<<OCIE2); //Timer/Counter 2 Interrupt Register
freigeschalten
while(1)
{
if (sekunde==2)
{
PORTD|=(1<<PD7);
if (sekunde==4)
{
PORTD&=~(1<<PD7);
}
}
}
}
ISR (TIMER2_COMP_vect)
{
millisekunde++;
if (millisekunde==1000)
{
millisekunde=0;
sekunde++;
}
if (sekunde==60)
{
sekunde=0;
minute++;
}
if (minute==60)
{
minute=0;
stunde++;
}
}
TCCR2=0b00001100; Ist da bei irgendeinem dieser Bits ein CS Bit dabei? Biiiiiiitteeee Schreib das nicht in Binärschreibweise. Da sieht man genau gar nichts, wenn man nicht zufällig die Bitbelegung der Konfigurationsregister komplett auswendig weiss. Schreibs doch so TCCR2 = ( 1 << CS20 ) | ( 1 << CS21 ); oder welches Bit du dann eben brauchst. Dann sieht man zumindest, dass du ein oder mehrere CS Bits setzt und weiß: Jup, da ist zumindest ein Vorteiler beteiligt. Der kann jetzt immer noch falsch sein und ist zu kontrollieren aber zumindest das Bitgefummel und auseinanderpfriemeln fällt beim Kontrollieren weg.
wenn du dier diesen Code
1 | while(1) |
2 | {
|
3 | if (sekunde==2) |
4 | {
|
5 | PORTD|=(1<<PD7); |
6 | if (sekunde==4) |
7 | {
|
8 | PORTD&=~(1<<PD7); |
9 | }
|
10 | }
|
11 | }
|
sauber einrückst, dann sieht er so aus
1 | while(1) |
2 | {
|
3 | if (sekunde==2) |
4 | {
|
5 | PORTD|=(1<<PD7); |
6 | if (sekunde==4) |
7 | {
|
8 | PORTD&=~(1<<PD7); |
9 | }
|
10 | }
|
11 | }
|
und da erhebt sich sofort eine Frage:
Das obere if führt seinen then Teil nur dann aus, wenn sekunde gleich 2
ist. Innerhalb dieses if steht das andere if, bei dem sekunde gleich 4
sein müsste. Nur: Wie kann das sein? An dieser Stelle steht schon fest,
dass sekunde gleich 2 sein muss, andernfalls wäre das Programm nie an
diese Abfrage gekommen! An dieser Stelle KANN sekunde daher niemals 4
sein was wiederrum bedeutet, dass dein Port einmal eingeschaltet aber
nie wieder ausgeschaltet wird.
Du hast überhaupt eine seltsame Art der Einrückung, wie man innerhalb
der ISR sieht.
Die Einrückung dient nicht dazu, nach Gutdünken angewendet zu werden,
sondern sie hat eine Funktion! Sie zeigt welcher Code abhängig von
welchem anderen Code ist.
Daher: Nach einem { wird eingerückt. Das zugehörige } wird wieder
ausgerückt. Und ein paar strategisch platzirete Leerzeichen dann und
wann machen den Code leichter lesbar. Schliesslich bist du von
Kindesbeinen an daran gewöhnt worden, dass zwischen Wörtern ein
Leerzeichen kommt. Oder findestduetwdiesenTextwirklichlesbarer als wie
wenn zwischen den Wörtern ein Zwischenraum steht?
1 | ISR (TIMER2_COMP_vect) |
2 | {
|
3 | millisekunde++; |
4 | if (millisekunde == 1000) |
5 | {
|
6 | millisekunde = 0; |
7 | sekunde++; |
8 | }
|
9 | |
10 | if (sekunde == 60) |
11 | {
|
12 | sekunde = 0; |
13 | minute++; |
14 | }
|
15 | |
16 | if (minute == 60) |
17 | {
|
18 | minute = 0; |
19 | stunde++; |
20 | }
|
21 | }
|
Bei solchen Sachen bin ich zwiespältig
1 | int main(void) |
2 | {
|
3 | |
4 | INITIALISIERUNG_SYSTEMPORTS(); //Ports initialisieren |
Das Problem: Die Initialisierung der Ports sind maximal ein paar Zuweisungen an die DDR Register und eventuell das Setzen von Pullups. Das ist aber eine wichtige Information, die ich nicht wirklich in eine eigene Funktion verpacken würde. Denn um in deinem Programm zu kontrollieren, ob du PD7 auch wirklich auf Ausgang gesetzt hast, muss ich jetzt in eine andere Funktion wechseln um mir das anzusehen. Fängt dein Programm so an
1 | int main(void) |
2 | {
|
3 | DDRD = ( 1 << PD7 ); |
dann ist das auch nicht länger als der Funktionsaufruf, ich sehe aber auf einen Blick, dass du PD7 auf Ausgang gesetzt hast und zwar NUR PD7. All das sehe ich nicht bei deinem Funktionsaufruf (der aus welchen Gründen auch immer in seiner SChreibweise eigentlich ein Makro ist, was in mir sowieso schon wieder die nächsten Alarmglocken zum klingeln bringt)
Hallo Danke für die schnell Antwort,
also habe den Code mal um geschrieben:
while(1)
{
if (sekunde==2)
{
PORTD|=(1<<PD7);
}
if (sekunde==4)
{
PORTD&=~(1<<PD7);
}
}
}
müsste so jetzt passen oder?
und zu karl heinz,
TCCR2=0b00001100;
//CTC Mode, Prescaler=64 (16MHz/64=250KHz -> 250KHz=4µs)
OCR2=250-1;
//TCNT 2 wird mit vorgeteilter Frequenz (250KHz bzw.alle
4µs)inkrementiert,
bis OCR2-1(-1, da das Interrupt Flag erst einen Timertakt nach der
Übereinstimmung gesetzt wird) erreicht wird (4µs*250=1ms) dann startet
ISR Timer2
Port D wird folgender Maßen initialisiert: DDRD |= (1<<PD7); PORTD &= ~(1<<PD7); //PortD //Datenrichtungsregister von PortD Pin 7 wird als Ausgang definiert. //Setze Pin 7 auf "low".
Matze schrieb: > müsste so jetzt passen oder? Versuch macht kluch > TCCR2=0b00001100; > //CTC Mode, Prescaler=64 (16MHz/64=250KHz -> 250KHz=4µs) Kann alles sein. Ich weiß ja nicht, welchen µC du benutzt daher kann ich das auch nicht kontrollieren.
Aso ja sorry, also Code funktioniert so wie ich ihn gepostet habe. Ich benutze einen AtMega 32. PS.:Habe den Fehler jetzt gefunden. in den Einstellungen des AVR Studios war der AtMega 16 mit 1Mhz eingestellt. Danke an euch und ich freue mich über Anregungen um meine Code übersichtlicher und schneller lesbar zu machen. MfG.
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.