1

I'm having a problem with some C code for a microcontroller. It seems like a language or compiler problem, but the program will compile just fine. When ran on the microcontroller, however, the problem manifests.

(This is for an Atmel AVR AtTiny26.)

I'm reading a value from the analog to digital converter and multiplying it by 10:

int SD;
SD = ADCH * 10;

This did not work correctly. I thought trying to read from the ADC in a calculation was the problem, so I tried:

int SD;
SD = ADCH;
SD = SD * 10;

This also did not work, causing instability on the micro. (It works as long as the analog value is low, but once a certain value is reached, a value is never obtained from ADC again until reset.)

This seems to work:

int SD;
int TEMP;
TEMP = ADCH;
SD = TEMP * 10;

Introducing another variable fixes the problem, but seems confusing. What's going on?

Related question on EE: https://electronics.stackexchange.com/q/38404/2028

Edit:

This may have something to do with compile optimizations. I get different results when I specify -Os versus -O2 or -O3 on the command line when compiling. Could optimization change how such variable assignment works?

Community
  • 1
  • 1
JYelton
  • 32,870
  • 25
  • 119
  • 184
  • Using Atmel Studio 6 with GCC 4.6.2 I have tried compiling both of your scenarios (using a temp variable and not). Looking at the assembly instructions in the .LSS file both seem to be working as intended. Especially nothing that would cause the latch up behavior you mentioned. Can you explain in very careful detail what happens when you don;t use the temp variable? eg. at what voltage value does it want to lock up where you need to reset the board. – justing Aug 23 '12 at 19:16
  • I have two 330 ohm resistors connected to a 50k potentiometer in such a way that the pot is connected to +5V and ground through the 330's and the center pin goes to the ATTINY26 ADC (pin 7). When using code from the versions that lack a temp variable, the micro latches at approximately 2 volts when read from pin 7 to ground. I expect this to be an integer value from the ADC of about 100. In other words, it works properly from ~0 to 2 volts, then gets stuck. – JYelton Aug 23 '12 at 19:59
  • The Latch up does not happen at all when you use the temp variable? It works from 0 - 5V up and down (perfectly as expected)? This is interesting, I can't figure out what would cause this in the software. – justing Aug 23 '12 at 21:16

1 Answers1

0

You have to declare SD as volatile:

volatile int SD;

This means that the value of the register may be changed by hardware (not controlled by the compiler). In your case, the value of ADCH may be changed by hardware, so, by setting SD as volatile, you will force the compiler to read it (update it) again, before using it.

Rubens
  • 13,469
  • 10
  • 56
  • 90
ChrisB
  • 488
  • 3
  • 10