void main(void){ /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ DDRB_BIT6 = 1; // set portB bit 6 to output (light outout) DDRB_BIT7 = 1; // set portB bit 7 to output (status_led) DDRA_BIT6 = 0; //set portA bit 6 to input gate_open_flag = 0; light_on_delay = 20; while(1) { if(light_trigger==0) // trigger turns on light { counter_1sec = 0; Light = !Light; while(light_trigger==0 && ( counter_1sec < 4)); //wait for button to be released or 4 sec to pass //TIE_C0I = 0; if(counter_1sec < 4) // button not held down , light on - TIMED { timeout_flag = 1; //enable timeout in 1ms timer module status_led_mode = 0; } else // button held down , light on permanently { //flashes status led (x) times status_led_mode = 1; //set led to flash-- delay 2 sec-- flash timeout_flag = 0; } while(light_trigger==0); }//--------------------------------------- if(gate_open_flag && Light == 0) //gate turns on light for delay time { counter_1sec = 0; Light = 1; } if( counter_1sec > light_on_delay && gate_open_flag) { gate_open_flag = 0; Light = 0; } //--------------------------------------- }
Status_led_mode is a variable. An insigned int. Sorry it's declared higher up in the code which I have not shown.
I have been doing some experimenting and this is what I have found. Code has been stripped down to this.
Code:
while(1) { if(light_trigger==0) // trigger turns on light { // counter_1sec = 0; Light = !Light; while(light_trigger==0 ) ; TIE_C0I = 0; if(counter_1sec < 4) // button not held down , light on - TIMED { timeout_flag = 1; //enable timeout in 1ms timer module status_led_mode = 0; } else // button held down , light on permanently { //flashes status led (x) times status_led_mode = 1; //set led to flash-- delay 2 sec-- flash timeout_flag = 0; } while(light_trigger==0); }
I have found this:
If I comment out this line counter_1sec = 0; then the code works like it should.
Status_led_mode always gets a value of 1 in the ELSE statement
If I leave it in , the value of Status_led_mode becomes one more than counter_1sec( which is an unsigned int). ie If I hold the light_trigger input low for 15s the value in status_led_mode becomes 16.
Still confused :0(
P.S Thanks for the sidenote.
Cheers
Rob
Hi there.
Using volatile has solved my problem:0) I did try that before but it did not seem to work. Maybe there was another problem that I was not aware of. I was under the impression that you should use the 'volatile' keyword on registers that may be changed at random by external events unknown to the compiler.
Does this mean that I should declare EVERY variable as volitile just in cast the compiler decides to optimize it in some way?
Thanks again for the help.
Cheers
Rob
But any variable that is modified in an ISR will "be changed at random by external events unknown to the compiler".
I was under the impression that you should use the 'volatile' keyword on registers that may be changed at random by external events unknown to the compiler.
Ha , makes sense.
Thanks for the help guys.This is something very easy to miss and could cause endless problems for the unwary. I'm lucky this was a small/simple piece of code!!
Cheers
Rob
Sorry I forgot to mention the processor.
I'm using the MC9S12c32CFU16 part.
Cheers
Rob