Hallo, wenn ich hardware-seitig einen Interrupt auslöse springe (->) ich in folgende interrupt-routinen: int0 -> int1 int1 -> pcint1 pcint0 -> wdt pcint1 -> timer2 compB pcint2 -> timer1 capt sieht so aus als wäre die interrupt-vektor-tabelle verbogen. weiss allerdings nicht warum. hier meine fusebits: bootrst x (x=checked also unprogrammed) bootszo 0 (0=unchecked also programmed) bootsz1 0 hab schon alles ausprobiert aber vielleicht hat noch jemand eine idee. hier das programm: #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #define FOSC 16000000 // Clock Speed #define BAUD 9600 #define MYUBRR FOSC/16/BAUD-1 SIGNAL(SIG_INTERRUPT0){ sendt("1"); } SIGNAL(SIG_INTERRUPT1){ sendt("2"); } SIGNAL(SIG_PIN_CHANGE0){ sendt("3"); } SIGNAL(SIG_PIN_CHANGE1){ sendt("4"); } SIGNAL(SIG_PIN_CHANGE2){ sendt("5"); } SIGNAL(SIG_WATCHDOG_TIMEOUT){ sendt("6"); } SIGNAL(SIG_OUTPUT_COMPARE2A){ sendt("7"); } SIGNAL(SIG_OUTPUT_COMPARE2B){ sendt("8"); } SIGNAL(SIG_OVERFLOW2){ sendt("9"); } //usw... void sendc(unsigned char c) { while (!(UCSR0A & (1<<UDRE0))); UDR0 = c; } int main (void) { UBRR0H = (unsigned char)(MYUBRR>>8); UBRR0L = (unsigned char)MYUBRR; UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); UCSR0C =(3<<UCSZ00); sei(); while(1); } die usart funktioniert allerdings nicht die rx complete routine. dort hängt er sich dann ganz auf. vielen dank im vorraus grüsse, andreas.
Hast du dem Compiler auch den richtigen Mikrocontroller angegeben?
es gibt eine fuse-bit... "boot reset vector enable" setzte oder lösche es mal zum test
habe mit den fusebits bootrst x (x=checked also unprogrammed) bootszo 0 (0=unchecked also programmed) bootsz1 0 rumgespielt und es hatte keine auswirkung auf meine falschen interrupt-sprungadressen.
Liest du denn in der RXC-ISR auch das UDR aus? Ansonsten wird die immer wieder erneut aufgerufen, weil die Interrupt-Bedingung anhängig bleibt.
habe ich auch ausprobiert. allerdings schiesst mein rxc interrupt komplett ins leere und schreibt den bilschirm mit leerzeichen voll. ein int1 interrupt ruft aber die pcint1 routine auf. wie oben beschrieben. ich verstehe nicht warum.
Wo ist den die
1 | sendt(char *); |
routine, is sehe nur eine
1 | sendc(char); |
?
sorry sendt gibt einen string und enter zurück.. hab nur vergessen es in der mail abzuändern.. wer hat eine idee. oder wer weiss wie ich meine vektortabelle verändern kann, warum sich oben beschriebene fusebit-änderungen nicht bemerkbar machen?? bin frustriert.. trotzdem danke
> warum sich oben beschriebene fusebit-änderungen nicht bemerkbar > machen? Weil sie gar nichts an der Vektortabelle ändern können. Der ATmega168 hat keine Möglichkeit, die Vektortabelle in den Bootloader zu verlagern (nur der Reset-Vektor kann verbogen werden). Für dein eigentliches Problem ist das alles zu vage, das musst du schon konkret anhand von Symboltabellen oder Mapfiles analysieren oder aber dein gesamtes Projekt als Zip-Datei irgendwo zur Verfügung stellen.
bin gerade am falschen rechner und kann erst morgen früh symboltabelle und mapfile posten. als anhang nochmal ein zusammenhängendes prog. makefile habe ich übernommen und nur # MCU name MCU = atmega168 geändert. Das ganze lief(mit ein bisschen anderen registernamen) vorher schon ganz wunderbar auf einem atmega8. jetzt brauche ich aber mehr externe interrupts bzw. pinchanges und deswegen der atmega168.
Also hier noch mal ein Programm mit mapfile, systemtabelle, fusebits und der bildschirmausgabe. Alles aus einem Guss.. (bitte das alte main.c nicht mehr beachten!) Sorry dass ich deswegen 3mal poste aber es geht nicht anders. Vielleicht werdet ihr daraus schlau. Vielen Dank also die Fusebits:(x:unprogrammed(checked); o:programmed(unchecked)) LB1=LB2=BLB01=BLB02=BLB11=BLB12=x CKSEL0=CKSEL1=CKSEL2=CKSEL3=x SUT0=o SUT1=CKOUT=CKDIV8=x BODLEVEL0=BODLEVEL1=BODLEVEL2=x EESAVE=WDTON=DWEN=RSTDISBL=x BOOTRST=x BOOTSZ0=BOOTSZ1=o
Compiliert wurde folgendes: -------- begin -------- avr-gcc (GCC) 3.4.1 Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiling: main.c avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst -std=gnu99 -DF_OSC=16000000 -MD -MP -MF .dep/main.o.d main.c -o main.o Linking: main.elf avr-gcc -mmcu=atmega168 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o -std=gnu99 -DF_OSC=16000000 -MD -MP -MF .dep/main.elf.d main.o --output main.elf -Wl,-Map=main.map,--cref -lm Creating load file for Flash: main.hex avr-objcopy -O ihex -R .eeprom main.elf main.hex Creating load file for EEPROM: main.eep avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \ --change-section-lma .eeprom=0 -O ihex main.elf main.eep Creating Extended Listing: main.lss avr-objdump -h -S main.elf > main.lss Creating Symbol Table: main.sym avr-nm -n main.elf > main.sym
Bildschirmausgabe: . . . . . . . . . . i glob on warte auf eingabe: 2_INTERRUPT1 //hier habe ich Int0 ausgelöst 2_INTERRUPT1 2_INTERRUPT1 2_INTERRUPT1 2_INTERRUPT1 2_INTERRUPT1 2_INTERRUPT1 2_INTERRUPT1 4_PIN_CHANGE1 //hier habe ich Int1 ausgelöst 4_PIN_CHANGE1 4_PIN_CHANGE1 4_PIN_CHANGE1 4_PIN_CHANGE1 4_PIN_CHANGE1 4_PIN_CHANGE1 4_PIN_CHANGE1 4_PIN_CHANGE1 //hier habe ich ein Zeichen gesendet Er hängt sich dann auf und erlaubt auch keinen anderen Interrupt mehr. Für mich ein Zeichen dass er noch irgendwo beschäftigt ist. Kommentiere ich sei() aus kann ich ganz normal Zeichen von der Tastatur empfangen und wieder am Bildschirm ausgeben. Vielen Dank für eure Aufmerksamkeit. Andreas
> Sorry dass ich deswegen 3mal poste aber es geht nicht anders.
Klar, alles in ein .tar.gz- oder .zip-File packen. ;-)
mir ist gerade etwas eingefallen: als ich anfing am atmega168 rumzuprogrammieren meckerte der compiler: Linking: main.elf avr-gcc -mmcu=atmega168 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o -std=gnu99 -DF_OSC=16000000 -MD -MP -MF .dep/main.elf.d main.o --output main.elf -Wl,-Map=main.map,--cref -lm F:\Programme\avr\WinAVR\bin\..\lib\gcc\avr\3.4.1\..\..\..\..\avr\bin\ld. exe: crtm168.o: No such file: No such file or directory make.exe: *** [main.elf] Error 1 also habe ich nach crtm168.o gesucht und nicht gefunden. allerdings crtm48.o und crtm88.o. Da die atmegas48/88/168 dasselbe datenblatt haben und die crtm´s ebenfalls gleich waren habe ich die crtm168.o erstellt (kopierte crtm88.o) und in ..\lib\gcc\avr\3.4.1 eingefügt. war das böse von mir? löst es meinen fehler? wo bekomme ich die richtige crtm168.o her? Vielen dank für eure erneute Aufmerksamkeit. andreas
> war das böse von mir? Ja. Das crtXXX.o ist die einzige Datei, die komplett prozessorabhängig ist, sie kennt auch die korrekten Speichergrößen der jeweiligen Chips. > wo bekomme ich die richtige crtm168.o her? Wenn du ein crtm48.o und crtm88.o hast, solltest du auch ein crtm168.o haben -- alle drei sind gleichzeitig in avr-libc eingeführt worden. crtm168.o ist allerdings in einem anderen Verzeichnis (avr4 vs. avr5).
Ganz frisch (vorgestern) aus avr-libc 1.2.5 unc avr-gcc 3.4.4 kompiliert.
es geht.. vielen dank hab mir ganz schön die zähne daran ausgebissen euch ein sonniges wochenende vielen dank für eure aufmerksamkeit andreas
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.