AVR C как остановить прерывание

Я программирую микроконтроллер AVR.

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

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

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*


} 

person michael    schedule 13.02.2012    source источник
comment
Что такое АДКСРА? Он определяется как изменчивый? Он управляет и дисплеем, и АЦП? Вам нужно специальное действие подтверждения прерывания для контроллера прерываний и/или устройств ввода/вывода? Достаточно ли медленны ваши ISR, чтобы пропустить некоторые прерывания?   -  person Alexey Frunze    schedule 13.02.2012
comment
@AlexeyFrunze - ADCSRA - это регистр специальной функции, который напрямую управляет настройками оборудования. Он определяется как летучий.   -  person Fake Name    schedule 21.06.2013


Ответы (3)


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

person ouah    schedule 13.02.2012

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

person user1176976    schedule 15.02.2012

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

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

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

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

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

ISR()
{
   //disable the ADC flag
}

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

person Anil Nair    schedule 08.03.2018