PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Interrupts in avr-gcc (gelöst)



n0body
20.11.2006, 12:25
Hallo.
Nur mal vorab zur Info: Ich verwende AVR Studio (v4.12/SP3) in kombination mit avr-gcc (aus WinAVR Release 20060421).

Für unser Schulprojekt (https://www.roboternetz.de/phpBB2/viewtopic.php?t=23280&start=0) bin ich seit einiger Zeit dabei mit in die Programmierung von AVRs einzuarbeiten. (mein ziemlich spärliches C-Wissen auffrischen/erweitern; dokus lesen, etc.)

Hab bisher leider noch keine Hardware, an der ich rumspielen kann, aber solange probier ich das ganze einfach mit dem Simulator und so.

Nun zum Problem: Ich hab gestern versucht eine Interrupt Routine zu programmieren und hab mir dann im Disassembler View den Assembler code angeschaut.

Hab ich das nun richtig verstanden, dass der Compiler die IRS einfach irgendwo in den Program Memory tut und an der Adresse des Interrupt Vektors steht dann ein Jump Befehl zu dieser ISR?

Hab dann einfach mal diese "Programm" geschrieben, um zu sehen, was passiert.


#include <stdint.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/io.h>

int main(void)
{

ISR(TIMER0_OVF_vect)
{
PINA |= (1 << PINA3);
}

return 0;
}

Beim Controller handelt es sich um einen ATmega32. Bei diesem ist der Interrupt Vektor bei Überlauf von Timer0 an $016. Sollte jetzt nicht an dieser stelle ein JMP an irgendeine adresse stehn, wo die ISR ist, die er im Falle eines Timer0 Overflows ausführen soll?

Außerdem bekomm ich noch 2 Warnings:
../Firmware_v0.1.c:95: warning: static declaration of '__vector_11' follows non-static declaration
../Firmware_v0.1.c:94: warning: previous declaration of '__vector_11' was here

Jedenfalls bin ich jetzt ziemlich verwirrt, was den erzeugten Code angeht:


@00000000: __vector_11
+00000000: 940C002A JMP 0x0000002A Jump
+00000002: 940C0045 JMP 0x00000045 Jump
+00000004: 940C0045 JMP 0x00000045 Jump
+00000006: 940C0000 JMP 0x00000000 Jump
+00000008: 940C0045 JMP 0x00000045 Jump
+0000000A: 940C0045 JMP 0x00000045 Jump
+0000000C: 940C0045 JMP 0x00000045 Jump
+0000000E: 940C0045 JMP 0x00000045 Jump
+00000010: 940C0045 JMP 0x00000045 Jump
+00000012: 940C0045 JMP 0x00000045 Jump
+00000014: 940C0045 JMP 0x00000045 Jump
+00000016: 940C0045 JMP 0x00000045 Jump
+00000018: 940C0045 JMP 0x00000045 Jump
+0000001A: 940C0045 JMP 0x00000045 Jump
+0000001C: 940C0045 JMP 0x00000045 Jump
+0000001E: 940C0045 JMP 0x00000045 Jump
+00000020: 940C0045 JMP 0x00000045 Jump
+00000022: 940C0045 JMP 0x00000045 Jump
+00000024: 940C0045 JMP 0x00000045 Jump
+00000026: 940C0045 JMP 0x00000045 Jump
+00000028: 940C0045 JMP 0x00000045 Jump
+0000002A: 2411 CLR R1 Clear Register
+0000002B: BE1F OUT 0x3F,R1 Out to I/O location
+0000002C: E5CF LDI R28,0x5F Load immediate
+0000002D: E0D8 LDI R29,0x08 Load immediate
+0000002E: BFDE OUT 0x3E,R29 Out to I/O location
+0000002F: BFCD OUT 0x3D,R28 Out to I/O location
+00000030: E010 LDI R17,0x00 Load immediate
+00000031: E6A0 LDI R26,0x60 Load immediate
+00000032: E0B0 LDI R27,0x00 Load immediate
+00000033: EDE2 LDI R30,0xD2 Load immediate
+00000034: E0F0 LDI R31,0x00 Load immediate
+00000035: C002 RJMP PC+0x0003 Relative jump
+00000036: 9005 LPM R0,Z+ Load program memory and postincrement
+00000037: 920D ST X+,R0 Store indirect and postincrement
+00000038: 36A0 CPI R26,0x60 Compare with immediate
+00000039: 07B1 CPC R27,R17 Compare with carry
+0000003A: F7D9 BRNE PC-0x04 Branch if not equal
+0000003B: E010 LDI R17,0x00 Load immediate
+0000003C: E6A0 LDI R26,0x60 Load immediate
+0000003D: E0B0 LDI R27,0x00 Load immediate
+0000003E: C001 RJMP PC+0x0002 Relative jump
+0000003F: 921D ST X+,R1 Store indirect and postincrement
+00000040: 36A3 CPI R26,0x63 Compare with immediate
+00000041: 07B1 CPC R27,R17 Compare with carry
+00000042: F7E1 BRNE PC-0x03 Branch if not equal
+00000043: 940C0047 JMP 0x00000047 Jump
+00000045: 940C0000 JMP 0x00000000 Jump
@00000047: main
---- Firmware_v0.1.c ------------------------------------------------------------------------------
89: {
+00000047: E5CF LDI R28,0x5F Load immediate
+00000048: E0D8 LDI R29,0x08 Load immediate
+00000049: BFDE OUT 0x3E,R29 Out to I/O location
+0000004A: BFCD OUT 0x3D,R28 Out to I/O location
101: }
+0000004B: E080 LDI R24,0x00 Load immediate
+0000004C: E090 LDI R25,0x00 Load immediate
+0000004D: 940C0068 JMP 0x00000068 Jump


Hab schon mehrfach die lib-c Dokumentation des Interrupt.h gelesen, gegoogelt und hier im Forum gesucht, aber irgendwie hat mich das eher noch mehr verwirrt.

Wär nett, wenn mir irgendwer helfen könnte, Danke!

mfg nobody

Hubert.G
20.11.2006, 12:48
Lies dir in der Doku des Mega32 nach wie man den Timer 0 aktiviert, das fehlt dir nämlich. Wenn dieser nicht losläuft kann er auch nicht überlaufen und einen ISR auslösen.

Hubert

n0body
20.11.2006, 13:01
Naja, aber der Interrupt-Vektor sollte ja trotzdem auf die ISR springen, auch wenn der Timer jetzt nichts macht.

Ich bin grad draufgekommen, dass ich die Definition der ISR in main geschrieben hab, was scheinbar net funktioniert.

Also statt:


int main(void)
{

ISR(TIMER0_OVF_vect)
{
PINA |= (1 << PINA3);
}

return 0;
}



ISR(TIMER0_OVF_vect)
{
PINA |= (1 << PINA3);

int main(void)
{
}

return 0;
}