0

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*


} 
2
  • What is ADCSRA? Is it defined as volatile? Does it control both the display and ADC? Do you need a special interrupt acknowledge action for the interrupt controller and/or the I/O devices? Are your ISRs slow enough to miss some interrupts? Commented Feb 13, 2012 at 9:34
  • @AlexeyFrunze - ADCSRA is a special function register that directly manipulates the hardware settings. It is defined as volatile. Commented Jun 21, 2013 at 3:35

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

1 Comment

Would interrupt fire when the interrupt flag is raised even if it occured while the flag was "off"?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.