Erst 'mal "Guten Tag" an alle die wie ich den Brückentag nutzen ! Leider hat mir die freie Zeit die ich heute habe nicht viel gebracht weil ich mal wieder mit dem leidigen s(n)printf rumschlage. Wenn ich im AVR Studio 5.1 folgendes einfache Programm durchsimuliere: //--------------------------------------------- #include <avr/io.h> #include <avr/interrupt.h> #include <stdio.h> #define F_CPU 14745600UL #define UART_BAUD_RATE 9600UL #define N1_PRESCALER 1024 #if N1_PRESCALER == 1024 #define TIMER1_TOP (F_CPU/(N1_PRESCALER))-1 #endif uint8_t volatile FktNr = 0; //=================== 16Bit timer Timebase ================ void Init_16Bit_Timebase(void) { TCCR1A = (1<<WGM10) | (1<<WGM11); // Fast PWM, TOP = OCR1A, No OC1A/B pin toggled TCCR1B = (1<<WGM13) | (1<<WGM12); //to finish settings above OCR1A = TIMER1_TOP; TIMSK1 |= (1<<TOIE1); // Overflow Interrupt Enable if(N1_PRESCALER == 1024) { TCCR1B |= (1<<CS12)|(1<<CS10); // Start Timer with prescaler 1024 } return; } //----------------------------------------------- ISR(TIMER1_OVF_vect) // occurs at first "Top" { char SendBuffer[32]; static uint32_t TimeInSecs = 0; PORTB ^= (1<<PB2); TimeInSecs++; // snprintf(SendBuffer,31,"R_%d_0_0_#",(int)TimeInSecs); sprintf(SendBuffer,"R_%d_0_0_#",(int)TimeInSecs); uart_puts(SendBuffer); } //========================================== int main(void) { // =========== Start Timer =============== Init_16Bit_Timebase(); //======================================= sei(); DDRB |= (1<<PB2); // Define Pin B1 as output DDRB |= (1<<PB3); // Define Pin B1 as output for(;;) { // PORTB ^= (1<<PB3); } //for } // main PS: der Aufruf: "uart_puts(SendBuffer);" benutzt die von Peter Fleury geschriebene (Standard-) Uart Funktionen die ich der Einfachheit halber hier nicht mit eingefügt habe //********************************************************************** *** geschehen merkwürdige Dinge: Das Programm resetted ständig, die Unterroutine Init_16Bit_Timebase() wird ständig auf's Neue ausgeführt obwohl weder ein Watchdog noch das entsprechende Fuse-Bit gesetzt ist. Richtig interessant wird's im Disassembly wo er in einen File mit dem Weg: "D:\usr\local\avr32studio\hudson\workspace\avr8-gnu-toolchain\src\avr-li bc\libc\stdio\vfprintf.c " springen will. Ich vermute mal das Mr Hudson (siehe Path) für Atmel arbeitet aber nicht für mich, jedenfalls entspricht der Weg nicht einer existierenden Adresse. Vermutlich hat's was mit den Compiler bzw. Linker Settings zu tun: Hier die definierten Settings: Compiler: -x c -funsigned-char -funsigned-bitfields -O1 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=($DEVICE) Linker: -Wl,-Map="$(OutputFileName).map" -Wl,-lm -Wl,-lprintf_flt -Wl,-lm -Wl,-u,vfprintf -mmcu=($DEVICE) ($MEMORY_SETTINGS) Last not least: Alles funktioniert wie erwartet wenn ich entweder die "s(n)printf" oder die uart_puts(SendBuffer) auskommentiere. Zugegebenermaßen ziemlich viel auf einmal aber jetzt wurschtle ich schon seit Tagen an dem Problem 'rum und habe langsam die Faxen dicke ... Wäre wirklich prima wenn mir jemand dazu eine Idee hätte ! Danke: Hermann
> Wäre wirklich prima wenn mir jemand dazu eine Idee hätte !
In einer ISR auszugeben ist meistens eine schlechte Idee.
Ganz besonders schlecht ist die Idee allerdings, wenn die
Ausgabefunktionen darauf angewiesen sind, dass sie per Interrupt ihre
zwischengespeicherten Daten ausgeben können. Das ist speziell dann ganz
besonders unangenehm, wenn die uart_puts Funktion die Daten nicht in den
Buffer stellen kann, weil der Buffer voll ist und darauf wartet, dass
endlich ein paar Zeichen aus dem Buffer per UART auf die Reise geschickt
werden. Was aber nie passiert, da in einer ISR die Interrupts gesperrt
sind.
Fazit: Man macht keine Ausgaben in einer ISR. Ausgaben kommen in die
Hauptschleife und die ISR signalsiert mit einem Flag der Hauptschleife,
die Ausgabe vorzunehmen.
Danke Karl Heinz, musste erst 'mal den Familiensegen retten ("du verbringst die ganze Zeit hinter deiner blöden Kiste ..."), daher die späte Rückmeldung. Natürlich hast du recht: ISR's nicht überladen ! Leider hat ein Flag (wie von dir empfohlen) das Problem nicht gelöst, Die ISR setzt jetzt das Flag und der UART wird jetzt in der "for(;;)"- Schleife aufgerufen (und das Flag zurückgesetzt) aber mit dem gleichen Ergebniss. Hab's auch nochmals unter dem AVR Studio4 compiliert (und simuliert) ebenfalls mit der gleichen Konsequenz. Zum Mäusemelken ! Hermann
Hallo Hermann, hast du mal probiert, auf sprintf() ganz zu verzichten?
1 | sprintf(SendBuffer,"R_%d_0_0_#",(int)TimeInSecs); |
lässt sich ohne größere Verrenkungen auch zu Fuß erledigen.
Grüss dich Markus, wahrscheinlich nicht, ich habe das Programm nur auf's Minimum reduziert um das Problem klarzumachen. snprintf wird im eigentlichen Programm leider ständig gebraucht. Langsam habe ich das Gefühl das irgendetwas mit dem Uart-Teil nicht stimmt. Die Library von Fleury nutzt noch die alte "Signal" Syntax die heute nicht mehr verwendet werden soll (zugunsten von USART0_TX_vect und Konsorten). Ich habe daher die ISR Headers umgeschrieben ins "Neue" Format, dies hat auch bislang gut funktioniert. Witzigerweise ist auch da ein Fehler im AVR5.1 Studio, für zB "USART0_RX_vect" wie im Datenblatt angegeben will er die ISR mit "USART0__RX_vect" (2 Underscores vor __RX) für den Atmega234p (in "iom324.h" so definiert) sonst sagt er "kenn' ich nich'" ! Ich habe jetzt die Programmabfolge soweit auseinandergedröselt das ich sehe wo's hapert: Ganz am Ende vom uart_putc(unsigned char date) (in Fleurys Program) sagt mir der Dissembler noch: 000000FB CALL 0x0000016B Call subroutine 000000FD JMP 0x00000A18 Jump --- No source file -------------------------------------------------------- 000000FF JMP 0x00000000 Jump und springt dann ins Nirwana bzw auf den Anfang. Scheint das die ISR Einsprungsadresse für "USART0_RX_vect" irgendwie nicht stimmt, er kommt da nämlich nie an (wahrscheinlich mit obig genanntem Problem zusammenhängend). Die Aussage "No source File" weis ich nicht so recht zu interpretieren. Ich Kompiliers mal mit 'ner anderen CPU um zu sehen ob was mit den Atmel Dateien für den Atmega324p nicht stimmt. -> schon gemacht: Gleiches Problem für den Atmega644 Grüsse: Hermann
wollte sagen: Scheint das die ISR Einsprungsadresse für "USART0_TX_vect" irgendwie nicht stimmt und nicht: Scheint das die ISR Einsprungsadresse für "USART0_RX_vect" irgendwie nicht stimmt...
Für alle dies interessiert, das Problem scheint wirklich in der ATmega324p Bibliothek zu liegen. Wie schon in einem anderen Thread bemerkt kennt AVR_Studio5.1 den Atmega324p nicht (man kann ihn zwar aussuchen aber hinterher jammert der Compiler das er die Datei "iom324p.h" nicht findet. Nachdem ich mein Programm bis aufs Letzte reduziert habe und dies immer noch aus dem Resetten nicht mehr rauskam hab' ich's nochmals als ATmega644 compiliert und siehe da: alles funzt und er springt (endlich) auch nicht mehr auf den Anfang sondern in die "USART0_TX_vect" ISR ! Also Achtung, die ATmega324 Dateien scheinen fehlerhaft im Studio5.1 !! Zur Lösung werde ich eben einen ATmega644 einschrauben, was solls, lieber 2€ mehr ausgeben als sich zu Tode ärgern. Hermann
Auch auf die Gefahr hin mich nur mit mir selbst zu unterhalten denke ich dass ich der Community schuldig bin das Ende der Geschichte zu erzählen: Nach weiterem Rumfummeln scheint die Lage jetzt klar: Die UART Datei von Peter Fleury nutzt noch die alte "SIG_xxx" Syntax in den ISR-Routinen. Das Neue AVR Studio 5.1 weiss damit nicht viel anzufangen. Da ich wie beschrieben diese Software für mich selbst schon in die neue Syntax (wie zb: "USART0_UDRE_vect") umgeschrieben hatte, glaubte ich davor geschützt zu sein. Jetzt kommt das eigentlich Heimtückische: Für den Atmega324p sind die beiden Vektoren "USART0_RX_vect" und "USART0_UDRE_vect" in meinen Augen falsch geschrieben, man muß sie nämlich wie "USART0_RX_vect" und "USART0__UDRE_vect" angeben (doppelter Underscore nach dem "USART"). Der AVR ist also in eine nicht vorhandene ISR gesprungen (USART0_UDRE_vect) und hat daraufhin resetted. Letztlich hat mich mich die geniale "ISR(BADISR_vect){...}" - die nur empfehlen kann- auf die Idee gebracht. Also nochmals: Achtung mit der Fleurischen UART Datei in Kombination mit AVR Studio5.1 Hermann
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.