Which optimisation level are you using?
Unless you use -O0, be aware that debugging source code can be trickier than you think. In case of doubt, I always suggest to view and debug the assembler instead than the source code.
(What I write is correct for GCC, if you use IAR maybe things could be different, but in any case try to inspect assembler)
-Os is the maximum optimisation level for GCC. Code is optimised, compiler may decide to put some functions inline even if you did not design them this way, and so on.
You can find a lot of tutorials about GCC explaining how to use switches and various optimisation levels.
For AVR, have a look at help files. Something is accessible from the AVR studio itself, others can be found in the installation directory. There you can find all the needed information.
About your code: I suggest you to set -O0 that means no optimisation. Purists will blame me, as the general rule is "try avoiding -O0 at all costs", but if the code is small and simple using -O0 can simplify a lot the debug, especially if you are new to AVR/GCC
One last thing: be careful with the simulator, not all peripherals are emulated fully and/or correctly. Again, have a look at help files for known issues
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include<avr/io.h> #include<avr/interrupt.h> #include <math.h> volatile uint8_t i; volatile unsigned int adc_data,angleInt; /*variable for ADC results*/ volatile float angleFloat, In_value; int main(void) { GICR=0x40; /*Set the INT0 bit to enable ext INT0*/ MCUCR=0x03; /*Set INT0 to be activate on rising edge */ ADCSRA=0xCE; /*ADC on, divide with 64, interrupt unmasked and started*/ ADMUX=0xC0; /*ADC0,ARF pin as ref internal(0x00) 2,56V ref=>ADMUX=0xC0*/ DDRB=0xff; /*All B-pins set to output*/ DDRC=0xff; /*All C-pins set to output*/ DDRD=0xf3; /*All D-pins set to input*/ for (i=100;i<1000;i+=100) { adc_data = i; In_value = (float)adc_data; /*converting from int to float*/ In_value*=0.002429; if (In_value<=1.586) { angleFloat = acos((In_value/1.586)); /*calculate the arc cos */ } else { angleFloat = acos((1.586/In_value)); /*calculate the arc cos */ } angleInt = (int)(angleFloat*10000); /*using a scale factor of 10000 to get a better resolution at the 16bit output*/ PORTB = angleInt; /*Writing the lowest eight bit of angleInt to PORTB???*/ PORTC = angleInt>>8; } while(1); }
Device: atmega16
Program: [B]1872 bytes (11.4% Full)[/B]
(.text + .data + .bootloader)
Data: [B]13 bytes (1.3% Full)[/B]
(.data + .bss + .noinit)
Device: atmega16
Program: [B]4108 bytes (25.1% Full)[/B]
(.text + .data + .bootloader)
Data: [B]277 bytes (27.1% Full)[/B]
(.data + .bss + .noinit)
Typically, system libraries like libm.a are given to the final C compiler command line that performs the linking step by adding a flag -lm at the end. (That is, the initial lib and the filename suffix from the library are written immediately after a -l flag. So for a libfoo.a library, -lfoo needs to be provided.) This will make the linker search the library in a path known to the system.
I finally found what was wrong,
to link the libm.a you have to add the -lm linker flag
in AVRSstudio, go to Project -> Configuration Options .
Then go to the custom options button down the side, select linker options,
write -lm and press the add button to add it to the linker options list.
compile and enjoy.
Alex
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?