weird looping bug after setting register

I’m using a Diecimila board, and I have a tiny program that uses the analog comparator. I’ve encountered a weird bug - when I set the analog comparator status register (ACSR), my program seems to loop forever in the setup() routine. Here’s a small program that replicates the behavior:

#include <avr/io.h>
void setup()
{
ACSR = 0x48;
Serial.begin(19200);
Serial.println(“hello”);
}

void loop()
{
}

When I run the program I get a loop of “hello”'s displayed to my monitor. If I comment out the line setting ACSR, I see a single hello as would be expected.

Has anyone seen anything like this and can you suggest a workaround? I’ve tried fiddling with things like putting the assignment of the ACSR after the print statements, but I always see the same behavior. I checked the 168 header files and it seems I’m referencing the ACSR correctly, but even if I wasn’t I don’t see how that would cause the setup method to infinitely loop. Any help is greatly appreciated.

Thanks in advance -
Dawn

My only suggestions right now are:

  1. try putting any function into the loop() routine so that it has something to do. I don’t know if this will have any affect but it can’t hurt to try.
  2. create a specific ISR to assign to the analog comparator interrupt. maybe this code is defaulting to setup() when the AC interrupt triggers and loops that.

Granted that i’m sure your actual program probably has both of these, but I don’t know what else to suggest this late (bought to go to bed). Good luck.

I solved my problem, thought I would post that in case someone else sees the same thing, as a newbie I’ve found the info about the comparator that’s out there to be kind of confusing.

In the end the behavior had to do with the ACIE bit in the ACSR, which enables the interrupt. Any time I set this bit I ended up in the infinite loop. I knew there was some interaction with this bit and the comparator, but since I didn’t have a signal I was sending to the comparator, I didn’t think it would cause me any trouble. Apparently not. In the end I ended up disabling the interrupt, turning off the comparator, setting the other register fields as I needed them (in my case the bandgap select bit, ACBG)), clearing the ACR bit, and then in the next step reenabling the comparator, and the interrupt.

ACSR|= (0<<ACIE) | //Comparator Interrupt disabled
(1<<ACD) | //confirm comparator is off
(1<<ACBG)| //selects the bandgap
(1<<ACI); //clears the interrupt

ACSR|= (0<<ACD) | //turns on the comparator,
(1<<ACIE); //Comparator Interrupt enabled
sei(); //global interrupt enabled

hopes this maybe helps someone, and I’m certainly open to any assistance myself if you have a better solution. Thanks - dawn