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 CCS Technical Support

Timers
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Mar 15, 2005 8:45 am     Reply with quote

What are you trying to do? The counter will continue to count since you do not stop it. Also, quit using goto's. Stick it in a while loop. This is C not BASIC.
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timer
PostPosted: Wed Mar 16, 2005 1:51 am     Reply with quote

Hi

I want the counter to count to say 2hrs than to run the code below. In code, it works but then the counter stops counting for the duration it takes to complete the while loop.



Code:

{
start:

 
   
    while(secs==0 && hrs==2)
    {     
   output_high(PIN_C2);
  // i have a couple of delays and other code like the one above ( //output_high(PIN_C2);)   
    }       
    goto start;
}
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 16, 2005 3:48 am     Reply with quote

I don't see any obvious errors in your code. What makes you think the clock stops counting? I mean, what did you see or measure?

I still have no clue as to what you want to achieve, but one thing that worries me in your code is the line:
Code:
    while(secs==0 && hrs==2)
This will loop for one second, but if your code is fast this loop may be executed many times. Is that what you intended?
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timer
PostPosted: Wed Mar 16, 2005 4:13 am     Reply with quote

Hi

Below is my exact code. All im doing is switching on and off relays at a specific time (secs==0 && mins==0 && hrs==1). After the 2nd time hrs == 1(after 24hrs), the program execute 34secs later.

Code:

#include <18F452.h> 
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000)

#define INTS_PER_SECOND 76         // (4000000/(4*1*65536))  = 15 for a 4Mhz Crystal - 262144


int8 secs=0;      // A running seconds counter
int8 mins=0;
int8 hrs=0;
int8 int_count=0;    // Number of interrupts left before a second has elapsed
int8 loop_condition=0;



void reset_one_second_counter(void);

#INT_TIMER1                         // This function is called every time
void clock_isr() {                  // timer 1 overflows (65535->0), which is
                                    // approximately 19 times per second for
      if(--int_count==0) {          // this program.
      ++secs;
     
      if(secs==60){
      mins=mins+1;
      secs=0;
      }
     
      if(mins==60){
      hrs=hrs+1;
      mins=0;
      }
     
      if(hrs==24){
     hrs=0;
     }       
   
   
      int_count = INTS_PER_SECOND;
    }
}


#int_EXT
EXT_isr()                     
{
delay_ms(10000);

//if (!input(PIN_A4))       
  //  {
  //  output_high(PIN_C2);   
  //  delay_ms(100);
   // output_low(PIN_C2);
//   delay_ms(100);
//   output_high(PIN_C2);   
//   delay_ms(100);
//    output_low(PIN_C2);
//   }
//   else
 //   delay_cycles( 1 );       //clear


if (!input(PIN_B0))
   {   
   output_high(PIN_A1);   
   delay_ms(5000);
    output_low(PIN_A1);
   delay_ms(1000);
   
   output_high(PIN_A2);   
   delay_ms(500);
    output_low(PIN_A2);
   delay_ms(1000);
   
   output_high(PIN_A2);   
   delay_ms(500);
    output_low(PIN_A2);
   delay_ms(1000);
   
   output_high(PIN_A5);    //call - menu
   delay_ms(500);
    output_low(PIN_A5);
   delay_ms(15000);       
   
   output_high(PIN_A1);   //end - menu - requesting
   delay_ms(2000);
    output_low(PIN_A1);
    delay_ms(1000);   
        
//   delay_ms(10000);      //delay to resend message
   }
   else
    delay_cycles(250);       //clear
}




#int_EXT1
EXT1_isr()                   
{   
delay_ms(10000);
if (!input(PIN_B1))
   { 
   output_high(PIN_A1);    //clear
   delay_ms(5000);
    output_low(PIN_A1);
   delay_ms(1000);
   
   output_high(PIN_A2);    //down
   delay_ms(500);
    output_low(PIN_A2);
   delay_ms(1000);
   
   output_high(PIN_A2);    //down
   delay_ms(500);
    output_low(PIN_A2);
   delay_ms(1000);
   
   output_high(PIN_A5);    //call - menu
   delay_ms(500);
    output_low(PIN_A5);
   delay_ms(15000);       
   
   output_high(PIN_A1);   //end - menu - requesting
   delay_ms(2000);
    output_low(PIN_A1);
    delay_ms(1000);   
        
//   delay_ms(10000);      
   }
   else
    delay_cycles( 250 );       
}




#int_EXT2
EXT2_isr()                   
{   
   
}




void main() {
   int_count = INTS_PER_SECOND;
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);
   enable_interrupts(INT_TIMER1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_EXT1);
   enable_interrupts(INT_EXT2);
   enable_interrupts(GLOBAL);
   
   
   
   
 
 
 
   



   reset_one_second_counter();

{
start:
   
   //while (seconds < 10)
  // {
       // wait til 20 secs is up
  // }

   // seconds is now >= 20


   //while(loop_condition==0)
   
    while(secs==0 && mins==0 && hrs==1 )
    {
      
   output_high(PIN_C2);   
    delay_ms(3000);
    output_low(PIN_C2);
   delay_ms(1000);
   output_high(PIN_C2);   
   delay_ms(2000);
    output_low(PIN_C2);
   
   
    delay_ms(10000);
   
    output_high(PIN_A1);   
   delay_ms(500);
    output_low(PIN_A1);
   delay_ms(1500);
   
   output_high(PIN_A2);   
   delay_ms(500);
    output_low(PIN_A2);
    delay_ms(1500);

   output_high(PIN_A2);   
   delay_ms(500);
    output_low(PIN_A2);
    delay_ms(1500);
   
    output_high(PIN_A2);   
   delay_ms(500);
    output_low(PIN_A2);
   delay_ms(1500);
   
      output_high(PIN_A2);   
   delay_ms(500);
    output_low(PIN_A2);
   delay_ms(1500);

   output_high(PIN_A5);   
   delay_ms(500);
    output_low(PIN_A5);
      delay_ms(12000);       
      
      
      output_high(PIN_A5);   
   delay_ms(500);
    output_low(PIN_A5);
      delay_ms(1500);         

   output_high(PIN_A1);   
   delay_ms(2000);
    output_low(PIN_A1);
       
   }
   goto start;
}
 

}


void reset_one_second_counter(void)
{
    int_count = INTS_PER_SECOND;
    secs = 0;
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 16, 2005 8:34 am     Reply with quote

Code:
#int_EXT
EXT_isr()                     
{
delay_ms(10000);


NEVER put a large delay like this in an interrupt routine!!!!

Interrupt routines must be as fast as possible because while the interrupt is executing all other interrupts are disabled. So in your code, with the timer1 interrupt occurring 76 times a second, none of the other interrupts may take more than 1/76 part of a second or you will miss interrupts.

Quote:
After the 2nd time hrs == 1(after 24hrs), the program execute 34secs later.
You are counting 76 interrupts per second but to be exact there are 76.2939... interrupts per second which makes your clock 333 seconds per day too fast. The fact you have a smaller timing error might have to do with your large delays in the other interrupts.

The best RTC timer implementation I have seen was given by Neutone. Special in this routine is that despite the timer interrupt not being exactly accurate, the seconds have a zero long time drift.
Code:

//RTC variables
#define XTAL_FREQUENCY  20000000
int32 Ticker;
int8 seconds=0, hours=0, minutes=0;


/*********************************************
*    Initialize RTC                          *
*********************************************/
void Initialize_RTC(void)
{
  Ticker = XTAL_FREQUENCY;
  setup_timer_1( T1_INTERNAL | T1_DIV_BY_1 );  // initialize 16-bit Timer1 to interrupt about
                                 // 76 times per second (exactly every 65536 clock cycles)
  enable_interrupts( INT_TIMER1 ); // Start RTC
}

// Global Real Time Clock Information
#int_TIMER1                              // Clock interrupt adjusted to occur ~ 76 times/second
void TIMER1_isr()                        //  -=Process Zero Drift Real Time Clock Information=-
{
  Ticker -= 65536;                      // Decrement ticker by clocks per interrupt
  if ( Ticker < 65536 )                 // If second has expired
  {  Ticker += XTAL_FREQUENCY;          // Increment ticker by clocks per second
     seconds++;                         // Increment number of seconds
  }

  if(seconds == 60) {minutes++;seconds = 0;
  if(minutes == 60) {hours++;minutes = 0;
  if(hours == 24) {hours= 0;}}}
}


Mark said:
Quote:
Also, quit using goto's. Stick it in a while loop. This is C not BASIC.
I totally agree! Get rid of that ugly 'goto start' instruction.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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