AVR -中断向量和全局变量

时间:2022-12-02 03:00:56

I am using an ATmega32 to interrupt every 32ms to do some arbitrary stuff, which isn't really important for now.
I'm using the timer overflow of timer0 to interrupt, which works predictably and perfectly.

我正在使用ATmega32来中断每32ms来做一些随意的事情,这对现在来说并不是很重要。我正在使用timer0的定时器溢出来中断,它可以预测地、完美地工作。

My problem is I have a global variable:

我的问题是我有一个全局变量

volatile int isSampling;

不稳定的int isSampling;

That isn't being written to in the interrupt vector. I read that the integer needed to be volatile to remove the possibility of compiler optimizations, but I declared it as volatile and its still not working.

它不会被写入到中断向量中。我读到,要删除编译器优化的可能性,这个整数必须是易变的,但我声明它是易变的,它仍然不能工作。

#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 I have found the offending code that is causing the problem, but I am unsure why its causing it. When I remove loadValue(studentID[i]) from the main while loop, the code works as predicted. But when I put it back, it breaks again.

好的,我找到了引起问题的代码,但是我不确定为什么会引起问题。当我从主while循环中删除loadValue(studentID[I])时,代码将按照预期工作。但当我把它放回去时,它又坏了。

3 个解决方案

#1


2  

The _delay_ms(500) lines are causing the problem as stated by Oli Charlesworth. The _delay_ms() function can cause unpredictable behavior if set to high (above 250ms).

正如Oli Charlesworth所述,_delay_ms(500)行导致了问题。如果将_delay_ms()函数设置为高(大于250ms),则会导致不可预测的行为。

#2


1  

Not sure if it explains the problem, but are you intentionally not having a break after each switch case value?

不确定它是否解释了问题,但是您是否故意在每个交换机实例值之后没有中断?

#3


-2  

the problem occurred on the definition of char array

问题出现在char数组的定义上

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

the number 1,2,...,7 should like below

数1、2、……7应该像下面

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

#1


2  

The _delay_ms(500) lines are causing the problem as stated by Oli Charlesworth. The _delay_ms() function can cause unpredictable behavior if set to high (above 250ms).

正如Oli Charlesworth所述,_delay_ms(500)行导致了问题。如果将_delay_ms()函数设置为高(大于250ms),则会导致不可预测的行为。

#2


1  

Not sure if it explains the problem, but are you intentionally not having a break after each switch case value?

不确定它是否解释了问题,但是您是否故意在每个交换机实例值之后没有中断?

#3


-2  

the problem occurred on the definition of char array

问题出现在char数组的定义上

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

the number 1,2,...,7 should like below

数1、2、……7应该像下面

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