Eine sehr komische "Wartefunktion"
Das hier hat keinen Sinn
Wenn Du den Timer stoppen willst muß es so heißenCode:TCCR0B |= (1<< CS00);
und vielleicht noch den Interruptflag in TIFR löschenCode:TCCR0B &= ~(1<< CS00);
Gruß Sebastian
Hallo,
ich soll für einen guten bekannten eine Geschwindigkeitsanzeige entwickeln die ihm die Geschwindigkeit seiner Modelle auf einer 4stelligen Dot-Matrix Anzeige in Wirklichkeit anzeigt. Ich hatte schoneinmal ein Programm dafür in Bascom angefangen, allerdings geht mir Bascom inzwischen ziemlich auf die Nerven weil der Compiler ein paar ziemliche Bugs bei den neueren Tinys hat, die einen immer ewig nach den Ursachen für die Fehler suchen lassen. Dies hier ist also mein erstes wirkliches Projekt in C deswegen bin ich in dieser Sprache noch nicht so bewandert. Als Display hab ich mir das SLR2016 vom Conrad ausgesucht weil es sich mit relativ wenigen Leitungen ansteuern lässt und weil es schön klein ist, zudem leuchten die Zahlen ordentlich hell.
Gesteuert wird das ganze mit einem ATtiny44, die Anzeige hat auch schon funktioniert (allerdings mit einem Programm das ich früher in Bascom geschrieben hab).
Das Problem in meinem Programm ist jetzt aber das das Programm nach beendigung meiner selbstgestrickten Wait Funktion nicht mehr ins Hauptprogramm sondern in die Interrupt Routine vom Timer0 springt (wird für die Waitfunktion verwendet).Hier Poste ich mal den Code damit ihr seht was das Programm die ganze Zeit so treibt
Code:#include <avr/io.h> #include <stdlib.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #ifndef F_CPU #define F_CPU 8000000UL /* Interner Oszillator mit 8Mhz */ #endif /* Variablen definieren */ uint8_t Statusbyte = 0; /* Statusbyte für verschiedene Operationen */ volatile uint16_t Waittime = 0; /* Countvariable für Waitfunktion */ volatile uint16_t Waitcount = 0; /* Countvariable für Waitfunktion */ /* Variablen für Geschwindigkeitsmessung */ volatile uint8_t overflowcount = 0; /* Zähler für Timer Overflows */ uint16_t timer1counts = 0; /*Zählerstand von Timer1 */ float zeit = 0.0; /* Gemessene Timer1 Zeit */ float ov_summ_zeit = 0.0; float v_float = 0.0; /* Geschwindigkeit mit Kommastelle*/ uint16_t V = 0; /* Geschwindigkeit ohne Kommastelle */ /* Variablen für Displayanzeige */ char Display[5]; /* Konstanten */ const float H0_10cm = 31.32; const float N_10cm = 115.2; const float overflowzeit = 2.097152; const uint16_t cps = 31250; const uint8_t disp_char0 = 0x00; const uint8_t disp_char1 = 0x10; const uint8_t disp_char2 = 0x20; const uint8_t disp_char3 = 0x30; /* Konstanten für Displaychars */ const uint8_t wertetabelle[] PROGMEM = {0x00 , 0x08 , 0x04 , 0x0C , 0x02 , 0x0A , 0x06 , 0x0E , 0x01 , 0x09 , 0x05 , 0x0D , 0x03 , 0x0B , 0x07 , 0x0F }; /* ++++++++++++++++++++++++++++++++++++INTERRUPTS++++++++++++++++++++++++++++++*/ ISR(TIM0_OVF_vect) { Waitcount ++; } ISR(TIM1_OVF_vect) { overflowcount ++; } /* Prototypen */ void init_io(); void timer_init(); void wait(uint16_t zeit, uint8_t faktor); /* ++++++++++++++++++++++++++++++++++++FUNKTIONEN++++++++++++++++++++++++++++++*/ /* IOs initialisieren */ void init_io() { DDRA |= 0xff; PORTA |= 0xC0; DDRB |= 0x0C; PORTB |= 0x07; #define disp_blank PA7 #define disp_write PA6 #define disp_clear PB2 return; } /* Timer initialisieren und Interrupts einrichten*/ void timer_init() /* Timer1 wird initialisiert aber nicht gestartet */ { /* Timer0 */ TCCR0A = 0; TCCR0B = 0; TIMSK0 = (1<<TOIE0); /* Timer1 */ /*TCNT1L = 0; TCNT1H = 0;*/ TCNT1 = 0; TCCR1A = 0; TCCR1B = 0; TIMSK1 = (1<<TOIE1); return; } /*+++++++++++++++++++++++++++++++++++++WARTEFUNKTION+++++++++++++++++++++++++++*/ void wait(uint16_t zeit, uint8_t faktor) { const float CPMS = 31.25; /* Counts pro Milisekunde */ Waitcount = 0; Waittime = (zeit * faktor)*CPMS; TCNT0 = 0; sei(); TCCR0B = (1 <<CS00); while (Waitcount < Waittime) { }; TCCR0B |= (1<< CS00); cli(); return; /* <<<<<<<Da Hängt er sich auf */ } /*+++++++++++++++++++++++++++++++++++++HAUPTPROGRAMM+++++++++++++++++++++++++++*/ int main(void) { init_io(); timer_init(); wait(1, 1); V = messung(); Anzeige(15,2); return 0; }
ich hoffe ihr könnt mir helfen damit mein erstes C Programm nicht gleich ein Desaster wird
Gruß und Dank im Vorraus
Wolfgang
Eine sehr komische "Wartefunktion"
Das hier hat keinen Sinn
Wenn Du den Timer stoppen willst muß es so heißenCode:TCCR0B |= (1<< CS00);
und vielleicht noch den Interruptflag in TIFR löschenCode:TCCR0B &= ~(1<< CS00);
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Hallo izaseba,
danke für deine Korrektur, das mit den Zuweisungen hab ich noch nicht so drauf, scheinbar funktionierts jetzt der Simulator vom AVR Studio springt aus der Funktion wieder einwandfrei raus .
Die Waitfunktion ist eigentlich reine Timerverschwendung, da er aber (bis jetzt!!) noch nicht gebraucht wird hab ich mir damit eine eigene Wait Funktion gestrickt weil ich bei den Funktionen von der AVR Libc noch nicht so ganz durchsteige und irgendwie noch nicht so ganz kapiert hab wie man andere Libs in AVR Studio einbindet.
P.S.: jetzt hängt der Simulator schon wieder allerdings im Interrupt vom Timer1
Hallo Wolfgang,
Es kann ja sein, daß ich mich vergucke, aber was macht das Programm im Interrupt von Timer1, wenn der Timer1 garnicht läuft
Oder hast Du das Programm von oben irgendwie abgeändert ?
Klar ist Deine Wartefunktion Timerverschwendung, sie tut aber Ihren Dienst
Das ist immernoch besser, als eine delay Funktion, wozu brauchst Du überhaupt diese wait Funktion ?
Vielleicht kann ich Die einen Tip geben, wie das eleganter zu lösen ist...
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Hallo Sebastian,
die Funktion wird nur gebraucht um die gemessenen Werte dann eine gewisse Zeit lang anzuzeigen und Delay Zeiten bei der Display initialisierung zu realisieren. Warum das Programm dann nach Beendigung der Funktion ausgerechnet in den Timer1 Interrupt springt obwohl sogar davor noch alle Interrupts deaktiviert werden versteh ich auch nicht, das werde ich dann halt irgendwie umschiffen müssen, die Frage ist nur wie? Ein sichern vom SREG hat keine änderung erbracht (warum auch) .
Gute Nacht
Wolfgang
Wo springt das return0 am Ende von main hin?
Hallo,
wieso schreibst du bei einem Normalen "void" Unterprogramm, welches überhaupt keinen Rückgabeparameter hat, am Ende "return"?
Mfg
The future is closer then you think!
Hallo
HubertG hat natürlich recht,
irgendwie fehlt bei Dir die Endlosschleife ( bin ich ein Blindfisch )
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Hallo,
danke für die Tipps gebracht hats bis jetzt leider nichts. Das mit den Return Anweisungen wusste ich nich, das man die bei void funktionen nicht braucht, jetzt weis ichs. Das main keine Endlosschleife ist war auch mein Fehler (liegt warscheinlich an den alten Bascom gewohnheiten) jetzt hab ich mir ne Endlosschleife mit do-while gebastelt, hoffentlich funktioniert das.
Leider springt das Programm immer noch in die Interruptfunktion vom Timer1 trotz eindeutig abgeschalteter Interrupts, hier nochmal der jetzige Code:
Hier mal der ganze Code damit ihr seht was bis jetzt so geschrieben steht.Code:#include <avr/io.h> #include <stdlib.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #ifndef F_CPU #define F_CPU 8000000UL /* Interner Oszillator mit 8Mhz */ #endif /* Variablen definieren */ uint8_t Statusbyte = 0; /* Statusbyte für verschiedene Operationen */ volatile uint16_t Waittime = 0; /* Countvariable für Waitfunktion */ volatile uint16_t Waitcount = 0; /* Countvariable für Waitfunktion */ /* Variablen für Geschwindigkeitsmessung */ volatile uint8_t overflowcount = 0; /* Zähler für Timer Overflows */ uint16_t timer1counts = 0; /*Zählerstand von Timer1 */ float zeit = 0.0; /* Gemessene Timer1 Zeit */ float ov_summ_zeit = 0.0; float v_float = 0.0; /* Geschwindigkeit mit Kommastelle*/ uint16_t V = 0; /* Geschwindigkeit ohne Kommastelle */ /* Variablen für Displayanzeige */ char Display[5]; /* Konstanten */ const float H0_10cm = 31.32; const float N_10cm = 115.2; const float overflowzeit = 2.097152; const uint16_t cps = 31250; const uint8_t disp_char0 = 0x00; const uint8_t disp_char1 = 0x10; const uint8_t disp_char2 = 0x20; const uint8_t disp_char3 = 0x30; /* Konstanten für Displaychars */ const uint8_t wertetabelle[] PROGMEM = {0x00 , 0x08 , 0x04 , 0x0C , 0x02 , 0x0A , 0x06 , 0x0E , 0x01 , 0x09 , 0x05 , 0x0D , 0x03 , 0x0B , 0x07 , 0x0F }; /* ++++++++++++++++++++++++++++++++++++INTERRUPTS++++++++++++++++++++++++++++++*/ ISR(TIM0_OVF_vect) { Waitcount ++; } ISR(TIM1_OVF_vect) { overflowcount ++; } /* Prototypen */ void init_io(); void timer_init(); void wait(uint16_t zeit, uint8_t faktor); uint16_t messung(); void Anzeige(uint8_t zeichen, uint8_t place); /* ++++++++++++++++++++++++++++++++++++FUNKTIONEN++++++++++++++++++++++++++++++*/ /* IOs initialisieren */ void init_io() { DDRA |= 0xff; PORTA |= 0xC0; DDRB |= 0x0C; PORTB |= 0x07; #define disp_blank PA7 #define disp_write PA6 #define disp_clear PB2 } /* Timer initialisieren und Interrupts einrichten*/ void timer_init() /* Timer1 wird initialisiert aber nicht gestartet */ { /* Timer0 */ TCCR0A = 0; TCCR0B = 0; TIMSK0 |= (1<<TOIE0); TCNT1 = 0; TCCR1A = 0; TCCR1B = 0; TIMSK1 |= (1<<TOIE1); } /*+++++++++++++++++++++++++++++++++++++WARTEFUNKTION+++++++++++++++++++++++++++*/ void wait(uint16_t zeit, uint8_t faktor) { const float CPMS = 5; /*31.25; Counts pro Milisekunde */ uint8_t temp; temp = SREG; Waitcount = 0; Waittime = (zeit * faktor)*CPMS; TCNT0 = 0; sei(); TCCR0B |= (1 <<CS00); while (Waitcount < Waittime) { }; TCCR0B &=~ (1<< CS00); cli(); SREG = temp; } /*+++++++++++++++++++++++++++++++++++++Messfunktion++++++++++++++++++++++++++++*/ uint16_t messung() { /* MESSUNG */ while (PINB0 == 1){} TCNT1 = 0; TCCR1B |= (1<<CS12); sei(); while (PINB1 == 1) {} TCCR1B &=~ (1<<CS12); cli(); timer1counts = TCNT1; /*+++++++++++++++++RECHNUNG++++++++++++*/ zeit = timer1counts / cps; ov_summ_zeit = overflowzeit * overflowcount; zeit = zeit + ov_summ_zeit; v_float = H0_10cm/zeit; V = v_float; /*itoa(V,Display,10);*/ /* Integer Wert in ASCII String umwandeln */ return(V); } /* ANZEIGE */ void Anzeige(uint8_t zeichen, uint8_t place) { /* ANZEIGE */ } /*+++++++++++++++++++++++++++++++++++++HAUPTPROGRAMM+++++++++++++++++++++++++++*/ int main(void) { init_io(); timer_init(); wait(1, 1); do { V = messung(); Anzeige(15,2); }while(1); }
Danke für eure Hilfe und noch einen schönen Bastel-Samstag
Wolfgang
Hallo ich bins wieder ,
hab heute nochmal alle möglichkeiten ausprobiert. Der Simulator hängt sich immer wieder an der selben stelle auf, immer wenn ich versuche entweder nur den Timer0 Overflow Interrupt oder alle Interrupts abzuschalten. Jetzt Frage ich mich warum, allerdings kann ich mir diese Frage mit meinen bis jetzt noch sehr bescheidenen C Kenntnissen nicht beantworten, wäre froh wenn ihr mir helfen könntet.
Schönen Sonntag noch
Gruß
Wolfgang
Lesezeichen