proper usage of ADC

Thread Starter

clintonb

Joined Mar 6, 2011
52
I've been experiencing a strange issue where my adc interrupt stops responding after a random amount of time and updating values no longer happens until I remove power and restart the mcu.

Things I've tried include..

1. Reading the interrupt code where some exception might occur but looks ok.

2. I used atomic_block in the main loop that displays the variables that the interrupt updates.

3. I declared all the variable as static volatile when shared between the main loop and the adc interrupt.

I get good results but the avcc aref and gnd pins are unconnected. I noticed some talk about connecting the avcc to vcc and aref to gnd with a capacitor between the 2 and then connecting gnd to ground.

Is this a major issue in using the adc?

I'm using an atmega32. The adc reference is set to avcc with external capacitor on aref pins
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
Generally it is bad practice to allow any input pin to float. So even if there is an internal reference voltage you are using do connect these two pins to to vcc and to gnd. I'd add that cap anyway though with an internal reference it probably is not necessary.

However, this smells like some sort of stack overflow or additional unhandled interrupt.
 

Thread Starter

clintonb

Joined Mar 6, 2011
52
Generally it is bad practice to allow any input pin to float. So even if there is an internal reference voltage you are using do connect these two pins to to vcc and to gnd. I'd add that cap anyway though with an internal reference it probably is not necessary.

However, this smells like some sort of stack overflow or additional unhandled interrupt.

I hadn't considered an unhandled interrupt. It uses 2 ext pin interrupts and the adc. It does smell of an overflow but seems to be slipping by.
 

Thread Starter

clintonb

Joined Mar 6, 2011
52
It was infact an overflow. It s
Generally it is bad practice to allow any input pin to float. So even if there is an internal reference voltage you are using do connect these two pins to to vcc and to gnd. I'd add that cap anyway though with an internal reference it probably is not necessary.

However, this smells like some sort of stack overflow or additional unhandled interrupt.
It was in fact an overflow. Turns out when the ADSC is set to 1 you might get more than one interrupt. I turned the ADIE to 0 after the interrupt triggers and on again when it finishes to prevent more than one occurence and having all those local variables.

Seems stable now.

1. Disable interrupts in the ISR before processing the event and re enable after done.

2. Declare the IRS variables as static.
3. Declare any shared vars between the main loop and Interrupt as static volatile.

4. Any shared variables in the main loop and Interrupt must be put in an atomic block to prevent the writing of large 16 bits itc being interrupted.
 

ErnieM

Joined Apr 24, 2011
8,377
1. Strange, though I do not know the specifics of your processor. With those I am familiar with an interrupt firing during the interrupt itself will just cause the ISR to refire when you attempt to exit.

2. I do not see the need unless you are reusing values.

3. Is this C? I did not think one function's variables are visible to another function. To share variables like this they should be global in scope.

3. Volatile is correct in this situation.

4. Unsure what "atomic block" means to you. Other ways to handle this are to disable interrupts till the data is processed, other way is to copy & verify to a shadow variable that doesn't change [ while (A != B) A=B; ]

4. When you get a reading you want to process it, then take another reading, correct? Why not let ISR disable ADC interrupts, and use that (or something else) as a flag that a reading is available. Process that, then re enable interrupts. Of course, this depends on the architecture of the whole program.
 
Top