AVR C как остановить прерывание - PullRequest
0 голосов
/ 13 февраля 2012

Я программирую AVR MCU.

У него есть POT, который считывает аналоговый вывод. Кажется, что прерывание вызывается постоянно, и оно должно вызываться во время метода LCD_display, так как он связывается с моим LCD.

Есть ли способ ОСТАНОВИТЬ Inturrupts до тех пор, пока блок не будет запущен?

int main(void)
{
/*Turn on ADC Interrupt */
ADCSRA |= (1 << ADIE); 

/*Turn On GLobal Interrupts*/
sei();


/* Intalise LCD */
lcd_init(LCD_DISP_ON);                /* initialize display, cursor off */
lcd_clrscr();
lcd_puts("READY");

DDRB &= ~(1 << PINB5);   //set input direction
ADC_Init(128, 0); //initalize ADC


while (1)                         
{

if (!bit_is_clear(PINB, 5))
{
_delay_ms(500);

if (!pressed)
{           
lcd_gotoxy(0,0);
lcd_clrscr();
lcd_puts("test");  //Doesnt work unless I dont comment out the last line of interrupt
pressed = 1;
}

}

/* INTERRUPTS */

//ADC INTERRUPT
ISR(ADC_vect) 
{ 

char adcResult[4];

uint8_t theLowADC = ADCL;
uint16_t theTenBitResults = ADCH<<8 | theLowADC;
itoa(theTenBitResults, adcResult, 10);
ADCSRA |= (1 << ADSC);  //next conversion  *if i comment out this line it works*


} 

Ответы [ 3 ]

3 голосов
/ 13 февраля 2012

Если обработчик прерываний ведет себя плохо с вашим кодом, причина может быть в том, что вы слишком много времени проводите в обработчике прерываний.Вы должны выполнять только критическую работу в обработчике прерываний и откладывать менее критическую работу в коде приложения;используйте флаг volatile, общий для обработчика и кода приложения, чтобы сообщить коду приложения, есть ли у него работа.В вашем примере вы должны отложить вызов itoa в коде приложения.

0 голосов
/ 08 марта 2018

Полагаю, я немного опоздал, но все же у меня возникла та же проблема, которую я решил, используя следующий метод:

Прерывания включаются с использованием двух флагов 1. Глобальный флаг прерываний 2. Флаг связанных с модулем прерываний(в вашем случае ADC)

Вы можете контролировать флаг, связанный с модулем, в вашем случае в регистре управления ADCSRA есть флаг ADIE-ADC Interrupt Enable, который вы можете использовать для управления прерываниями.

Например, в основной функции вы можете включить флаг и в ISR отключить флаг.

main()
{
    //enable global flag and ADC flag
    while(1)
    {
        //your logic
        // enable ADC flag
    }
}

ISR()
{
   //disable the ADC flag
}

Я надеюсь, что это решит вашу проблему.

0 голосов
/ 15 февраля 2012

Используйте cli ();отключить прерывания и sei ();чтобы включить их снова после завершения процедуры отображения.Какой MCU вы используете?Вероятно, вы должны использовать таймер вместо задержки 500 мс.

...