You may see every key checking, flag1 bit 0 will set. This flag will signal the set timer task that key has been pressed, so on entering it will check if this bit = 1, it will not repeat running.
The task that reset this bit will check if all keys have been released is shown below. using logical AND P3 with 0x3C. If all bits are '1', then clear bit 0 of flag1.
key_release() { if((P3&0x3c) == 0x3c) flag1 &= ~1; } |
run_timer( ) can be one second resolution, so we put it running every second with the help of incrementing of one_second variable. All four timers will run every second then. The shutdown task also runs every second. We will see later for shutdown detail.
run_timer() { if(++one_sec>=100) { one_sec = 0; run_timer1(); run_timer2(); run_timer3(); run_timer4(); shutdown(); // run shutdown checking every second } } |
Now look at the sample code that runs timer1.
run_timer1() { if(timer1 != -1) // enter only preset value != -1 { if(timer1 != 0) // enter only timer1 != 0 { timer7 = 0; // reset shutdown timeout buzzer1 = off; flag1 |= 0x02; setbit(output1) if(++timer1_clk >= 60) // timer1 is one min based! |
We have three states that will be executed. Below table shows the action for each state. Note that timer7 is a timer that we used for shutdown timeout. Flag1 bit 1 is for dot blinking signal flag.
State | Action |
Timer1 = -1 | flag1 &= ~0x02; // no dot blink flag2 &= ~0x01; buzzer1 = off; // off buzzer1 |
Timer1 = 0 | clrbit(output1) // fire output1 buzzer1 = on; // on buzzer flag flag1 &= ~0x02; // no dot blink flag2 &= ~0x01; |
Timer1 = 3, 5,.... | timer7 = 0; // reset shutdown timeout buzzer1 = off; flag1 |= 0x02; setbit(output1) if(++timer1_clk >= 60) {timer1_clk = 0; timer1--; } |
As shown above the shutdown task also resided in one second resolution the same as timer running. Timer7 will reset every timer1 is not equal 0. However when user set all timers off, or all value of timer1-timer4 will be -1, then the shutdown task will run. The timeout is 10 seconds, you may see that when timeout, the MAX7219 will be set to shutdown mode and the PD bit in PCON will be set to one to enable power down! The on chip oscillator stops!, and display will show blank. There will no response from any key pressing then. To wake up MCU and turn it on, the RESET button will help exit from power down mode!
shutdown() { if((timer1&timer2&timer3&timer4)== -1) { timer7++; if(timer7 >= 10) // 10 seconds timeout { shift(0x0c00); // enable shutdown mode asm' CLR IE.7'; asm' MOV PCON,#2'; // enter power down mode } } } |
The update display will send serial data of buffer[] array to MAX7219. You may study the code of how to convert binary data to 7-segment display in moveTimetobuffer( ) function.
SDCC version firmware
Again the reason why I wrote a new version firmware, just for fun and spend my free time learning new things. I got the problem with a big electromechanical relay, mostly the makers only produce the NO contact. The sample schematic shown in Fig 2. has the relay circuit that uses opto triac driving a NO/NC relay! So I must change the firmware to let the output turn on when start timer and turn off when time is over. To do such changing, it needs to modify the source code and recompile it. I thought why don't try with sdcc. The people can modify the source code and do-it-yourself.
Let get the sdcc for dos command line, SDCC for 8051. Unzip the package and save to drive c. I made the folder app (application programs) for my source code. Here is the new source code for sdcc, xtimer1.c
Timer4 is now modified to be delay off output. The counting is now based on minute the same as timer1 and 2. Timer3 still be hour counting based. I have made the opto-relay for big load switching.