|
|
View previous topic :: View next topic |
Author |
Message |
sonicfire
Joined: 11 Feb 2007 Posts: 19 Location: Cedar Rapids
|
1 Hz clock implementation without interference |
Posted: Mon Mar 26, 2007 1:37 pm |
|
|
I was wondering if it's possible to implement a 1Hz clock output on my 16F877 PIC without interfering with the code written below. The 1Hz clock output is somewhat unrelated to the rest of the program. It would just be nice to use the PIC to divide up the 10MHz clock signal instead of having to devise an external clock divider in my circuit.
Code: | #include <16F877.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#define TIMER_SET 65535-25000 //holds the initial condition of timer
int8 hundredths;
int8 tenths;
int8 seconds;
int overload = 0;
void check_reset() {
int reset_value = 0;
while (reset_value==0) {
reset_value = input(PIN_B0); //delays circuit until user resets circuit (emits high signal to pin B1
}
}
void check_current() {
int16 current_value;
int32 scale = 100;
set_adc_channel( 0 );
delay_us( 10 ); //get rid of this if it slows program too much
current_value = (read_adc()*scale)/1024;
if (current_value >= 82) //value of 82 corresponds to a current of 16A
{
if(overload == 0)
{
hundredths = 0;
tenths = 0;
seconds = 0;
set_timer1(TIMER_SET);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
}
overload = 1;
}
else
{
disable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
overload = 0;
}
}
void main() {
setup_timer_1(T1_INTERNAL); //1Mhz/8 gives us 125000Hz because it originally is
// divided by 4 automatically
setup_port_a(ALL_ANALOG);
setup_adc(adc_clock_internal);
//output 1Hz clock signal...
while( TRUE ) {
check_current(); //
}
}
//interupt
#INT_TIMER1
void time_increment_isr()
{
set_timer1(TIMER_SET + get_timer1() + 26);
hundredths ++;
if (hundredths == 10)
{
hundredths = 0;
tenths++;
}
if (tenths == 10)
{
tenths = 0;
seconds++;
}
if (seconds == 5)
{
output_high(PIN_B1);
check_reset();
output_low(PIN_B1);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 26, 2007 2:15 pm |
|
|
Quote: | I was wondering if it's possible to implement a 1Hz clock output
|
Your timer isr gets interrupted every 10 ms. You already have
a counter for tenths of a second. Check the value of that counter
to toggle an i/o pin when you're at 5/10 and 10/10 counts. |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 26, 2007 2:49 pm |
|
|
And remember, you already have a test for 10/10 counts, so just clear the pin here, and add one single test for the count==5, and set the pin in this. There should be no detectable change in the perfromance of the code.
As a comment though, you can save time in the interrupt handler, by re-organising things. There is no point in checking each of the later counters, unless the earlier one _has_ updated. At present you do all the tests each time. Instead look at:
Code: |
if (++hundredths == 10) {
hundredths = 0;
if (++tenths == 10) {
//Here only test when the value is incremented
tenths = 0;
//Set your one second 'tick' pin here
if (++seconds==5)
//and the same for the seconds
output_high(PIN_B1);
check_reset();
output_low(PIN_B1);
}
if (tenths == 5) {
//clear your 1 second tick pin here
}
}
|
This way each subsequent test is only performed when a value hs changed.
Technically, if you don't use the hundredths, and tenths values as numbers externally, it is slightly faster to count them down, than up.
if you do:
if (--hundredths)
The value is decremented,and the 'zero' flag gets set if the result is zero, allowing a one instruction operation to be used, instead of having to perform an extra subtraction. Obviously you have to set the value to '10 instead of zero.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|