Nachdem dein Code nicht komplett ist, der Timer aber OK scheint, würde ich sagen das du ein Probelm mit dem UART hast. Du kannst z.B. nicht senden bevor du initialisiert hast.
Hey,
Ich hab schon den ganzen mittag ziemliche Probleme mit Timer0 eines Atmega32. Ich möchte eigentlich nur das bei jedem overflow ein Interrupt ausgelöst wird. Sobald ich aber Interrupts aktiviere resetet sich der Controller. Um diese Stelle geht es:
wenn ich "sei()" oder "TIMSK |= (1<<TOIE0);" rausnehme funktioniert das Programm wie es soll, aber sobald beide da sind resetet sich der Controller. Ich habe bestimmt wieder was total einfaches übersehen und such nun schon ewig danach. Also wär gut wenn mal kurz jemand drüber sehen könnte, hier mein gesamter Testcode:Code:TCCR0 |= (1 << CS00) | (1 << CS01 ) ; // Timer0 initialisierung TCCR0 &= ~(1 <<CS02 ); // Vorteiler ist 64 TIMSK |= (1<<TOIE0); // Interrupt aktivieren init_USART(); sei();
Mit dem Code bekomm ich im Hyperterminal immer nur "test1" und "test2" inner Endlosschleife angezeigt. Ich weis im moment nichtmehr weiter...Code:int main( void ) { sendUSART(" test1 \r \n"); _delay_ms(1000); TCCR0 |= (1 << CS00) | (1 << CS01 ) ; // Timer0 initialisierung TCCR0 &= ~(1 <<CS02 ); // Vorteiler ist 64 TIMSK |= (1<<TOIE0); // Interrupt aktivieren init_USART(); sendUSART("test2 \r\n"); _delay_ms(1000); sei(); sendUSART("test3 \r \n"); _delay_ms(1000); while( 1 ) { // Endlosschleife sendUSART("test4 \r \n"); _delay_ms(1000); } return 0; //wird nie erreicht } ISR(TIMER0_OVF_vect) { sendUSART("interrupt"); }
Gruß
elayne
Nachdem dein Code nicht komplett ist, der Timer aber OK scheint, würde ich sagen das du ein Probelm mit dem UART hast. Du kannst z.B. nicht senden bevor du initialisiert hast.
Okey, stimmt. Habe ich übersehen. Aber wenn ich den ersten Sendebefehl rausnehme geht es auch nicht.
Hier ist nochmal die main.c
und die usart.cCode:#include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include <avr/delay.h> #include "usart.c" #ifndef F_CPU #define F_CPU 16000000L // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! #endif volatile int32_t t,zahl; int main( void ) { TCCR0 |= (1 << CS00) | (1 << CS01 ) ; // Timer0 initialisierung TCCR0 &= ~(1 <<CS02 ); // Vorteiler ist 64 TIMSK |= (1<<TOIE0); // Interrupt aktivieren init_USART(); sendUSART("test2 \r\n"); _delay_ms(1000); sei(); sendUSART("test3 \r \n"); _delay_ms(1000); while( 1 ) { // Endlosschleife sendUSART("test4 \r \n"); _delay_ms(1000); } return 0; //wird nie erreicht } ISR(TIMER0_OVF_vect) { sendUSART("interrupt"); }
Die UART routinen habe ich aus dem Wiki, und ohne Interrupt ging es bisher immer. Deswegen dachte ich da gibt es kein Problem. Aber mit dem jetzigen code bekomm ich im HyperTerminal nur "test2" fortlaufend angezeigt.Code:/*### Senden per USART - RS232-Kommunikation ###*/ /*Zum senden von Zeichen im Hauptprogramm entweder char irgendwas[] = "meintext"; sendUSART(irgendwas); oder direkt sendUSART("meinText"); verwenden.*/ void init_USART(void) { UCSRB |= (1<<TXEN); //UART TX (Transmit - senden) einschalten UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Modus Asynchron 8N1 (8 Datenbits, No Parity, 1 Stopbit) UBRRH = 0; //Highbyte ist 0 UBRRL = 103; //Lowbyte ist 103 (dezimal) -> (Frequenz_in_Hz / (Baudrate * 16)) - 1 <- Quarfrequenz = 16*1000*1000 Hz!!!! } void sendchar(unsigned char c) { while(!(UCSRA & (1<<UDRE))) //Warten, bis Senden möglich ist { } UDR = c; //schreibt das Zeichen aus 'c' auf die Schnittstelle return 0; } void sendUSART(char *s) //*s funktiniert wie eine Art Array - auch bei einem String werden die Zeichen (char) einzeln ausgelesen - und hier dann auf die Sendeschnittstelle übertragen { while(*s) { sendchar(*s); s++; } }
Gruß
elayne
[/code]
du musst ERST TIMSK setzen DANN TCCR, bei mri gabs zwar kein reset aber der timer verhielt sich merkwürdig
TCCR0 &= ~(1 <<CS02 ); kannste weglassen alles was nicht mit |= gesetzt wird ist sowieso 0!
Die UART-Ausgabe dauert länger als der Timer0 OVL, setze einmal den Prescaler auf 1024.
Hey,
Denke für eure Hilfe erstmal.
Ich habe jetzt beides versucht, ich hab aber immer noch den blöden Fehler mit dem Reset. Vielleicht sollte ich mal erwähnen das ich ein RN Controll 1.4 verwende. Vor ein paar wochen hatte ich die selbe Schaltung auf einem Steckbrett aufgebaut und damals viel komplizierteres problemlos programmiert. Damals hatte ich noch einen Quarzoszillator, jetzt benuze ich den Quarz. Aber das können doch alles keine Gründe für so ein Phänomän sein.
Hier nochmal mein aktueller Code:
Im UART gibt das wieder nur Test2 in einer EndlosschleifeCode:#include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> #include <avr/delay.h> #include "usart.c" #ifndef F_CPU #define F_CPU 16000000L // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! #endif int main( void ) { TIMSK |= (1<<TOIE0); // Interrupt aktivieren TCCR0 |= (1 << CS00 ) | (1 << CS02) ; // Timer0 initialisierung TCCR0 &= ~(1 <<CS01 ); // Vorteiler ist 1024 init_USART(); sendUSART("test2 \r \n"); _delay_ms(1000); PORTA = 0x00; sei(); sendUSART("test3 \r \n"); _delay_ms(1000); while( 1 ) { // Endlosschleife sendUSART("test4 \r \n"); _delay_ms(1000); } return 0; //wird nie erreicht } ISR(TIMER0_OVF_vect) { sendUSART("interrupt"); }
Gruß
elayne
Hallo,
falls du eine Optimierung eingeschaltest hast, nimm die bitte erst einmal raus.
Edit: Dann musst du die delays auskommentieren.
Dann probier mal
sendUSART((char*)"interrupt");
hth
Jens
Ich würde einmal sagen du hast da ein anderes Problem. Auf meinem STK funktioniert das einwandfrei.
Allerdings würde mich interessieren mit was du schreibst und kompilierst oder ist das noch immer nicht der komplette Code. Mein AVR-Studio lässt mir diesen Code ohne usart.h nicht zu.
Das _delay_ms(1000); funktioniert auch nicht, schau mal in die <util/delay.h> da steht das drinnen.
Dake erstmal für eure Tipps.
Also der Code ist komplett. Ich habe bloß eine main.c und eine Usart.c. Ich finde das auch komisch weil auf einem Steckbrett vor ein paar Wochen hat das ganze noch einwandfrei funktioniert. Ich verwende zum Programmieren Programmers Notepad. Ich habe jetzt nocheinmal ein anderes Testprogramm geschrieben. Komplett ohne Uart. Das Programm mach jetzt nurnoch einen Pieps mit dem Piepser auf dem Board. Dannach geht es ine eine Endlosschleife. Aber auch hier habe ich das Problem das sobald ich sei() und TIMSK |= (1<<TOIE0); zusammen aktivier das sich das Board resetet, sprich ich bekomm ein dauerpiepsen.
Ich habe jetzt auch shcon mehrere Controller und mehrere Oszilatoren und Quarze versucht. Aber es kann doch eigentlich kein Hardwarespezifisches Problem sein, oder?
Hier der neue Code:
WWas genau an der _delay_ms(1000); nich funktionieren soll versteh ich auch nicht.Code:#include <avr/io.h> #include <avr/delay.h> #include <avr/interrupt.h> int main( void ) { DDRA = 0xFF; DDRB = 0xFF; DDRC = 0xFF; DDRD = 0xFF; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; for(uint16_t i=0; i<270*15; i=i+(2*6)) { PORTD |= (1<<7); _delay_ms(6); PORTD &= ~(1<<7); _delay_ms(6); } TIMSK |= (1<<TOIE0); TCCR0 |= (1 << CS00 ) | (1 << CS02) ; TCCR0 &= ~(1 <<CS01 ); sei(); while(1) { } return 0; }
Gruß
elayne
Dir fehlt das Grundwissen,
daß Dein Programm abstürzt ist ganz normal, man aktiviert auch keine Interrupts, ohne die pasende Interupt Service Routine.
Und die Sache mit delay, tja
... sagt das Handbuch zu avr-gccThe maximal possible delay is 262.14 ms / F_CPU in MHz.
Gruß Sebastian
Linus TorvaldSoftware is like s e x: its better when its free.
Lesezeichen