CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

1 Hz clock implementation without interference

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sonicfire



Joined: 11 Feb 2007
Posts: 19
Location: Cedar Rapids

View user's profile Send private message

1 Hz clock implementation without interference
PostPosted: Mon Mar 26, 2007 1:37 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Mar 26, 2007 2:15 pm     Reply with quote

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







PostPosted: Mon Mar 26, 2007 2:49 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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