AVR - Interrupt-Vektor und Globale Variable

Ich bin mit einem ATmega32 zu unterbrechen, alle 32ms zu tun, einige willkürliche Sachen, die nicht wirklich wichtig für den Moment.

Ich bin mit dem timer overflow von timer0 interrupt funktioniert erwartungsgemäß und einwandfrei.

Mein problem ist ich habe eine Globale variable:

volatile int isSampling;

Ist das nicht geschrieben in der interrupt-Vektor. Ich habe gelesen, dass die integer benötigt werden volatile zu entfernen die Möglichkeit, die compiler-Optimierungen, aber ich erklärte es als volatile und seine immer noch nicht funktioniert.

#include <AVR/IO.h>
#include <util/delay.h> 
#include <avr/interrupt.h>

char studentID[12]            = {'S',1,2,3,4,5,6,7,'A','B','C','D'};

char buffer[72]; //Max bitlength = 6. * studentID length
char repcount[72];
int pointer;

volatile int isSampling;

void setup(void);
void startup(void);
void loadValue(unsigned char loadedValue);
void processValue(unsigned char processedValue, short bitLength);
void sendDot(void);
void sendDash(void);



int main(){

    setup();
    while(1)
    {

        if (isSampling == 1){
            startup();
            int i;
            for (i = 0; i < 12; i++){
                loadValue(studentID[i]);
                //Flash lights after letter sent.
                _delay_ms(500);
                PORTB = 0xF0;
                _delay_ms(500);
            }
        }
    }   
}

void setup(void){
    DDRB = 0xFF;
    sei();  
    TCCR0 = TCCR0 | 0x05;                   
    TIMSK|=(1<<TOIE0);  
    TCNT0 = 0;
    pointer = 0; 
    isSampling = 1;
}

ISR(TIMER0_OVF_vect)
{   
    //Every 32ms this interrupt vector is called.
    isSampling = 0;
}

void startup(void){
    //Play LED startup pattern
    int i;
    for (i = 0; i < 4; i++){
        PORTB = 0b11110011; //Bit 5 is constantly sampled. 4 is output
        _delay_ms(250);
        PORTB = PORTB & 0x00;
        _delay_ms(250);
    }
    _delay_ms(500);
    _delay_ms(500);
}

void loadValue(unsigned char loadedValue){
    switch (loadedValue){
        case   1: processValue(0b01111000, 5);
        case   2: processValue(0b00111000, 5);
        case   3: processValue(0b00011000, 5);
        case   4: processValue(0b00001000, 5);
        case   5: processValue(0b00000000, 5);
        case   6: processValue(0b10000000, 5);
        case   7: processValue(0b11000000, 5);
        case   8: processValue(0b11100000, 5);
        case   9: processValue(0b11110000, 5);
        case   0: processValue(0b11111000, 5);
        case 'A': processValue(0b01000000, 2);
        case 'B': processValue(0b10000000, 4);
        case 'C': processValue(0b10100000, 4);
        case 'D': processValue(0b10000000, 3);
        case 'E': processValue(0b00000000, 1);
        case 'F': processValue(0b00100000, 4);
        case 'G': processValue(0b11000000, 3);
        case 'H': processValue(0b00000000, 4);
        case 'I': processValue(0b00000000, 2);
        case 'J': processValue(0b01110000, 4);
        case 'K': processValue(0b10100000, 3);
        case 'L': processValue(0b01000000, 4);
        case 'M': processValue(0b11000000, 2);
        case 'N': processValue(0b10000000, 2);
        case 'O': processValue(0b11100000, 3);
        case 'P': processValue(0b01100000, 4);
        case 'Q': processValue(0b11010000, 4);
        case 'R': processValue(0b01000000, 3);
        case 'S': processValue(0b00000000, 3);
        case 'T': processValue(0b10000000, 1);
        case 'U': processValue(0b00100000, 3);
        case 'V': processValue(0b00010000, 4);
        case 'W': processValue(0b01100000, 3);
        case 'X': processValue(0b10010000, 4);
        case 'Y': processValue(0b10110000, 4);
        case 'Z': processValue(0b11000000, 4);
        case '.': processValue(0b01010100, 6);
        case ',': processValue(0b11001100, 6);
        case '?': processValue(0b00110000, 6);
        case '!': processValue(0b00110000, 5);
        case ':': processValue(0b11100000, 6);
        case '=': processValue(0b10001000, 5);
    }
}

void processValue(unsigned char processedValue, short bitLength){
    unsigned char result;
    int i;
    //Enter Loop at the length of bits in numerical morse code
    for (i = 0; i < bitLength; i++){
        result = processedValue & 0x80;
        processedValue = processedValue << 1;
        if (result) sendDash();
        if (!result) sendDot();
        _delay_ms(1000);
    }
}

void sendDot(void){
    //Send Dot
    PORTB = 0x05;
    _delay_ms(250);
    PORTB = 0x00;
}

void sendDash(void){
    //Send Dash
    PORTB = 0x06;
    _delay_ms(750);
    PORTB = 0x00;
}

Okay ich hab gefunden, der den fehlerhaften code, der das problem verursacht, aber ich bin nicht sicher, warum die, die es verursacht.
Wenn ich entfernen loadValue(studentID[i]) von der Haupt-while-Schleife, der code funktioniert wie vorhergesagt. Aber wenn ich es wieder, es bricht wieder.

  • Btw. Ich nehme an, Ihr mithilfe von C-code. C++ unterstützt keine default-int.
  • Für diese extrem kurze Programm, dem empfehle ich, Lesen Sie den erzeugten Assembler-code.
  • Sie sagte: "überlauf des timer0 interrupt funktioniert erwartungsgemäß und einwandfrei". Hast du wirklich überprüfen? Wenn nicht, schlage ich vor, fügen Sie einige code in der ISR schaltet einen Ausgang-Zeile und beobachten Sie es mit einem Rahmen.
  • Ich denke, das problem ist, dass der Schreibzugriff auf "isSampling" ist nicht broadcastet der main-loop oder es nie geschrieben.
  • Okay, ich habe in den code, wie verlangt. Ich fand den fehlerhaften code, so scheint es zu sein, die loadValue(studentID[i]) - Methode das ist, was es ist. Ich habe keine Ahnung, warum, aber...
  • Und ja, ich kann stellen Sie sicher, dass die interrupts arbeiten, 100%
  • Ich würde raten, dass die _delay_ms Funktion ist messing mit der interrupt-Maske irgendwie. Versuchen Sie, vereinfachen Sie den code unten, um eine viel einfachere Anwendung und sehen, ob du immer noch das Problem.
  • Hinzufügen eines default: arm auf Ihre switch-Anweisung.
  • Charlesworth. Es scheint Ihr Recht, wenn ich kommentiere alle die _delay_ms Funktionen der code funktioniert wie vorhergesagt, es ist nur einmal habe ich Sie in Sie verwirren mit der globalen variable. Ich bin mir nicht sicher, aber vielleicht, vielleicht seine aufgrund der atomaren Natur der isSampling? Bitte beantworten Sie die Frage, damit ich akzeptieren kann. Danke.
  • Ich verstehe nicht, wie _delay_ms könnte dies Auswirkungen auf die globalen Variablen; bei den meisten, ich könnte es mir vorstellen das clearing der interrupt-Maske, so dass deine ISR ist deaktiviert, wenn Sie einige Zeit.

InformationsquelleAutor Ospho | 2011-05-31
Schreibe einen Kommentar