My program works wrong because of c compiler's optimization. If I use "volatile" to declare some varibles and functions, the optimization will be affetced, and perhaps the program works well, but if I changed the program, I would have to add "volatile" to other varibles or functions. I have to try many times to make compiler compile my program "correctly" after change the program. Is there a way to remove optimization completely? I use #pragma SAVE #pragma OPTIMIZE(0) my_func1() { ...; } #pragma RESTORE but I know optimize level 0 doesn't mean no optimization, and my program can't be compiled correctly even at optimize level 0, if without "volatile" to most varibles and functions. I only use P0, P1 and P2, to read and write some IO lines. Compiler is keil c51 v6.12
Could you show us an example of the incorrect optimization with C source and assembly code output from the compiler? I don't understand what you mean by a volatile function. You can't declare a function "volatile" in C. "volatile" is supposed to affect the optimization of code. That's its main purpose, actually. If, without "volatile", your program doesn't work correctly, it could mean that you have problems with updating shared variables and getting interrupted inside critical sections.
Yes, interrupt affects the program. Here is the example: /* global varibals shared between uart_listener() and main() */ volatile uchar uart_input_flag; volatile uchar uart_input_grp; volatile uchar uart_input_smc; void uart_listener(void) interrupt 4 { static uchar stat = 0; uchar c; if (!RI) return; c = SBUF; RI = 0; if (stat == 0) { if (c == KVM_CMD_DATA) stat = 1; } else if (stat == 1) { uart_input_grp = c; stat = 2; } else if (stat == 2) { uart_input_smc = c; uart_input_flag = 1; stat = 0; } } If I remove uart_listener(), my program works well; or if I add "volatile" to local varibal "stat" and "c" my program works well too. Perhaps it's not a optimize problem? /* global varibals shared between uart_listener() and main() */ volatile uchar uart_input_flag; volatile uchar uart_input_grp; volatile uchar uart_input_smc; void uart_listener(void) interrupt 4 { static volatile uchar stat = 0; volatile uchar c; if (!RI) return; c = SBUF; RI = 0; if (stat == 0) { if (c == KVM_CMD_DATA) stat = 1; } else if (stat == 1) { uart_input_grp = c; stat = 2; } else if (stat == 2) { uart_input_smc = c; uart_input_flag = 1; stat = 0; } } ============ Another problem, functions as static volatile void test1() { ....; } static volatile char test2() { ....; } can be compiled well. I'm not sure what's the meaning of a volatile function, or does it means nothing?
I have found the real reason is the broken hardware! The AT89C52 I was using is damaged, and caused wrong IO. After using new AT89S52 instead of the old chip, everything OK. There is no bussiness about optimize and volatile varibles, it's a hardware fault. Thanks.