简体   繁体   中英

AVR C how to stop interrupt

I am programming a AVR MCU.

It has a POT that reads off an analogue pin. It seems that the interrupt is constantly called, and it must be called during a LCD_display method as it is messing with my LCD.

Is there a way to STOP the inturrupts until after the block is run?

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*


} 

If the interrupt handler behaves bad with your code, the reason could be you spend too much time in the interrupt handler. You should only do critical work in the interrupt handler and defer the less critical work in the application code; use a volatile flag shared between the handler and the application code to let the application code know if it has work to do. In your example, you should defer the itoa call in the application code.

I believe, I am little late but still I had the same issue I solved it using the following method,

Interrupts are enabled using two flags 1.A global interrupt flag 2.A module related interrupt flag (in your case ADC)

You can have control over module related flag, in your case in the ADCSRA control register there is a flag named ADIE- ADC Interrupt Enable flag you can use that to control the Interrupts.

For example, In main function you can enable the flag and in ISR disable the flag.

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

ISR()
{
   //disable the ADC flag
}

I hope this solves the issue you are having.

Use cli(); to disable interrupts and sei(); to enable them again after you finished the display routine. Which MCU are you using? You should propably use a timer instead of a delay of 500ms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM