Tut mir leid, noch immer Probleme, aber andere (ist eigentlich off topic). Das geringere ist: UART läuft nur ohne Interrupt - sobald ich "sei;" sage, gehts nicht mehr - habe ich aber vorerst zur Seite geschoben.
Aktuelles Problem: trotzt sicherer Funktion von Timer0 (LED´s signalisieren ihre Funktion korrekt ) läuft der extInt0 nicht (und auch nicht der extInt1).
Der code:
Code:
/* =================================================================================
##### Hier ISR und ISR - Initialisierung(en)
================================================================================= */
/* === Initialisierung fuer EXT_INT0/1 auf Pin 16+17/mega16(32) ==================
$002 jmp SIG_INTERRUPT0 ; IRQ0 Handler und
$004 jmp SIG_INTERRUPT1 ; IRQ1 Handler */
void XTI_01_init( void )
{ //Initialisiere beide Interrupts auf rising edge
// d.h. MCUCR ISC00,01,10+11 auf 1 (doc,S68)
MCUCR |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);
GICR |= (1<<INT1)|(1<<INT0); // und erlaube diese I´s in GICR
}
/* ============================================================================== */
/* === Initialisierung fuer Timer mega16(32) =====================================
SIGNAL (SIG_OVERFLOW0)
Beachte zu TIMSK:
OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0 TIMSK
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0
RNControl 0 0 1 1 1 1 0 0 hex 3c
###>>> dieser Wert wird GESETZT, d.h. Bit 0, 1, 6 und 7 gehen auf NULL.
Hier wird: TIMSK |= (1<<OCIE0) mit ODER! eingeführt, d.h.
1
*/
void TMR_0_init( void )
{ //Initialisiere 8-Bit-Timer auf 10 kHz
TCCR0 |= (1<<CS01 | 1<<CS00); // Prescaler 1/64 / Clock <- CPU
TCCR0 |= (1<<WGM01 | 0<<WGM00); // Timer im CTC-Mode
OCR0 = 25; // Preset 25 für 100µs bei 16Mhz
TIMSK |= (1<<OCIE0); // Compare Match IRQ
}
/* ============================================================================== */
/* === Nicht unterbrechbare ISR für EXT_INT0 auf Pin 16/PD2/mega16(32) ======== */
/* Routine setzt einfach einen Zähler hoch. Der Zähler wird im main
ausgelesen ##>> cli/sei setzen <<## und nach 2 (od. 5) hunderstel Sekunden
auf den Speicher WEG_L/_R vorzeichenrichtig aufaddiert und dann zurückgesetzt.
##>> Beim Richtungswechsel (cli/sei) wird der Zähler ausgelesen und genullt,
damit ist eine saubere Wegmessung möglich.
Der zugehörige Motor auf RNControl auf PB0/PB1 = li,re und PD5 Geschwind.
Der alternat. Motor auf RNControl auf PC7/PC6 = li,re und PB4 PWM/Geschw.
$002 jmp EXT_INT0 ; IRQ0 Handler */
SIGNAL(SIG_INTERRUPT0)
{
Iencdr1 ++; //zähle Counter/encoder 1 hoch
Iz_yseci1 = Izeit_1; //Weise musi den akt. Timerwert zu
Iz_diff1 = Iz_yseci1-Iz_ysecv1; //Neue Zeit-Differenz1 ausrechnen
Iz_ysecv1 = Iz_yseci1; //der aktuelle Zeitwert wird "Alter"
{
if (Iencdr1 == 5000);
PORTC ^= (1<<PC3); //LED4 toggeln alle 5000 Interrupts
}
PORTC ^= (1<<PC4); //LED5 toggeln bei JEDEM Interrupt
}
/* ============================================================================== */
/* ============================================================================== */
/* === Nicht unterbrechbare ISR für EXT_INT1 auf Pin 17/PD3/mega16(32) ======== */
/* Routine setzt einfach einen Zähler hoch.
Sonst wie ISR für EXT_INT0 für Motor auf PC7/PC6 = li,re und PB4 PWM/Geschw.
$004 jmp EXT_INT1 ; IRQ1 Handler */
SIGNAL(SIG_INTERRUPT1)
{
Iencdr2 ++; //zähle Counter/encoder 2 hoch
Iz_yseci2 = Izeit_1; //Weise Iz_yseci den akt. Timerwert zu
Iz_diff2 = Iz_yseci2-Iz_ysecv2; //Neue Zeit-Differenz2 ausrechnen
Iz_ysecv2 = Iz_yseci2; //der aktuelle Zeitwert wird "Alter"
PORTC ^= (1<<PC5); //LED6 toggeln bei JEDEM Interrupt
}
/* ============================================================================== */
/* ============================================================================== */
/* === Nicht unterbrechbare ISR für timer ====================================== */
/* Diese Routine zählt hoch im Takt 10 kHz.setzen.
Dieser Wert wird von den beiden anderen ISR ausgelesen und den Werten */
// SIGNAL(SIG_OVERFLOW0)
// #define SIG_OUTPUT_COMPARE0 //Interuptvektor, siehe Tabelle
SIGNAL(SIG_OUTPUT_COMPARE0)
{
{
if (Izeit_1 <= 10000)
Izeit_1 ++; //Zeitstand Interupt-Timer läuft von 1 .. 10 000
else
Izeit_1 = 0;
}
{ // von hier bis Ende (LED2 toggeln) nur Testphase
if (Izeit_1 == 1)
PORTC ^= (1<<PC2); //LED3 toggeln alle Sekunde
}
PORTC ^= (1<<PC1); //LED2 toggeln jeden Interrupt
}
/* ============================================================================== */
läßt die LED auf PC1 genau mit 0,1 ms blinken, die LED auf PC2 im Sekundenrhythmus - 10 000 mal 0,1 ms - aber die in den ISR für extInt0 und ~1 angesprochenen LED´s tun nichts.
Ich habe PD2 und PD3 mit 10k gegen GND geschaltet und taste sie von Hand auf Vcc. Es geschieht nichts
.
Frage:
Ist die Initialisierung in void XTI_01_init( void ) korrekt?
Sind die ISR SIGNAL(SIG_INTERRUPT0) und die SIGNAL(SIG_INTERRUPT1) korrekt?
Ich gehe davon aus, dass der mega16 seine Interrupt-Vektortabelle über die <avr/interrupt.h> einlädt. Das ist doch ok? Sonst würde ja schon die ISR für Timer0 nicht laufen. Und in der iom16.h steht ja auch:
Code:
/* Interrupt vectors */
/* Vector 0 is the reset vector. */
/* External Interrupt Request 0 */
#define INT0_vect _VECTOR(1)
#define SIG_INTERRUPT0 _VECTOR(1)
/* External Interrupt Request 1 */
#define INT1_vect _VECTOR(2)
#define SIG_INTERRUPT1 _VECTOR(2)
... und das ist genau meine Schreibweise.
Danke im Voraus.
Lesezeichen