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 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timers
PostPosted: Tue Mar 08, 2005 7:58 am     Reply with quote

Hi

I still have a problem using timers

Could someone please have a look at my code. Im using a 18F452 at a frequncy of 4mhz. After 20secound an led should flash but it doesn't. The program doesn't seem to come out of the timer loop

Thanks


Code:

#include <18F452.h>
#device ICD=TRUE
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)


int i;
long secs=0;
long mins=0;
long hrs=0;
long counter=0;





#int_TIMER1
TIMER1_isr() {
counter=counter+1;


secs=secs+1;
set_timer1(0x3CAF);
if (secs==60){
   mins=mins+1;
   secs=0;
   }
if (mins==60){
   hrs=hrs+1;
   mins=0;
   }
if (hrs==24){
   hrs=0;

   }   
set_timer1(0x00);

}

void main(){
/* **************************************************************/
/*              INITIALISATION SECTION
/*
/* Part of Bootup Sequence.  All peripherals
/* are configured and activated.
/*
/* ************************************************************* */

   


   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   
   if(secs==20){   
       output_high(PIN_A1);   
      delay_ms(1000);
       output_low(PIN_A1);
      mins=0;
      secs=0;
   }
         

   }   
MikeValencia



Joined: 04 Aug 2004
Posts: 238
Location: Chicago

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

Here is sample code...
PostPosted: Tue Mar 08, 2005 8:41 am     Reply with quote

I just slapped this together using example stwt1.c

It counts 20 seconds, then starts blinking. In this case, i used RB1 for the LED pin, so you ought to change your code accordingly. otherwise most of it is cut-and-paste-able...

Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#define INTS_PER_SECOND 15         // (4000000/(4*1*65536))

int8 seconds;      // A running seconds counter
int8 int_count;    // Number of interrupts left before a second has elapsed

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.
      ++seconds;
      int_count = INTS_PER_SECOND;
    }
}

void main() {
   int_count = INTS_PER_SECOND;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
   set_timer1(0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   reset_one_second_counter();
   
   while (seconds < 20)
   {
       // wait til 20 secs is up
   }

   // seconds is now >= 20
   while(TRUE)
   {
       output_high(PIN_B1);
       delay_ms(1000);
       output_low(PIN_B1);
       delay_ms(1000);
   }
}

void reset_one_second_counter(void)
{
    int_count = INTS_PER_SECOND;
    seconds = 0;
}


-Mike
(valemike)
valemike
Guest







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

oops, i forgot to change something...

it should say
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);

and not

setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);

Other than that, both should work, just the previous program would take a bit longer.
Mark



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

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

Re: Timers
PostPosted: Tue Mar 08, 2005 9:31 am     Reply with quote

bhyatyab wrote:
Hi

I still have a problem using timers

Could someone please have a look at my code. Im using a 18F452 at a frequncy of 4mhz. After 20secound an led should flash but it doesn't. The program doesn't seem to come out of the timer loop

Thanks


Code:

#include <18F452.h>
#device ICD=TRUE
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT, WDT128, HS, NOPROTECT, NOOSCSEN, NOBROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)


int i;
long secs=0;
long mins=0;
long hrs=0;
long counter=0;





#int_TIMER1
TIMER1_isr() {
counter=counter+1;


secs=secs+1;
set_timer1(0x3CAF);
if (secs==60){
   mins=mins+1;
   secs=0;
   }
if (mins==60){
   hrs=hrs+1;
   mins=0;
   }
if (hrs==24){
   hrs=0;

   }   
set_timer1(0x00);

}

void main(){
/* **************************************************************/
/*              INITIALISATION SECTION
/*
/* Part of Bootup Sequence.  All peripherals
/* are configured and activated.
/*
/* ************************************************************* */

   


   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   
   if(secs==20){   
       output_high(PIN_A1);   
      delay_ms(1000);
       output_low(PIN_A1);
      mins=0;
      secs=0;
   }
         

   }   


Without looking that closely, the obvious thing that stands out is no endless loop.



Code:

while(1)
{
  if(secs==20){   
    output_high(PIN_A1);   
    delay_ms(1000);
    output_low(PIN_A1);
    mins=0;
    secs=0;
  }
}
         
ckielstra



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

View user's profile Send private message

PostPosted: Tue Mar 08, 2005 9:43 am     Reply with quote

And to get the timing correct he has to remove the following line:
Code:
set_timer1(0x00);
Mark



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

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

PostPosted: Tue Mar 08, 2005 9:50 am     Reply with quote

ckielstra wrote:
And to get the timing correct he has to remove the following line:
Code:
set_timer1(0x00);


Actually his timing is all screwed up. With a divide by 8 and not setting the timer the timer will int every half second so he is going to have to do a count like what Mike suggested.
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timers
PostPosted: Wed Mar 09, 2005 1:01 am     Reply with quote

Hi

Ok now say I want this timer to do something say after 2hrs - how do I do this?

Thanks for all the info guys
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timer
PostPosted: Wed Mar 09, 2005 2:10 am     Reply with quote

Hi

1. (4000000/(4*1*65536)) - how do we get the figures 4*1? - how will my calculation change if I use a 20MHz Crystal?
2. Will this code work? I want a delay for 2hrs?

Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#define INTS_PER_SECOND 15         // (4000000/(4*1*65536))

int8 seconds;      // A running seconds counter
int8 int_count;    // Number of interrupts left before a second has elapsed

int secs=0;
int mins=0;
int hrs=0;
int counter=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
   
secs=secs+1;
      if (secs==60){
      mins=mins+1;
      secs=0;
      }
   if (mins==60){
      hrs=hrs+1;
      mins=0;
      }
   if (hrs==24){
      hrs=0;
      }


}



void main() {
   int_count = INTS_PER_SECOND;
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
   set_timer1(0);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   reset_one_second_counter();
   
   while (seconds < 20)
   {
       // wait til 20 secs is up
   }

   // seconds is now >= 20
   while(hrs==2)
   {
       output_high(PIN_B1);
       delay_ms(1000);
       output_low(PIN_B1);
       delay_ms(1000);
   }
}

void reset_one_second_counter(void)
{
    int_count = INTS_PER_SECOND;
    seconds = 0;
}

ckielstra



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

View user's profile Send private message

PostPosted: Wed Mar 09, 2005 3:31 am     Reply with quote

Quote:
1. (4000000/(4*1*65536)) - how do we get the figures 4*1? - how will my calculation change if I use a 20MHz Crystal?
4000000 = Clock frequency
4 = A fixed value, the number of clock cycles it takes for 1 instruction to execute.
1 = prescaler setting (for example the T1_DIV_BY_1 in the call to setup_timer_1).
65536 = The number of ticks before the timer has an overflow. Timer 1 is a 16 bit timer,hence the 65536. An often applied method is to adjust this value in software; in the timer interrupt routine a new value is written to the timer so it will overflow sooner (see your own first code example where you call set_timer1(0x3CAF)).
Mark



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

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

PostPosted: Wed Mar 09, 2005 7:17 am     Reply with quote

The code will wait until seconds is equal to 20 and then the PIC will goto sleep. The hidden sleep instruction the compiler puts at the end of main. You do not have a while(1) loop. The first time the while(hrs==2) is evaluated it will not be true and simply skip the statements. You probably wanted to do a less than check. Also you seem to know that timer1 is going to interrupt about 15.25 times per second from your calculations. Therefore your seconds are 15.25 times too fast. At 20MHz they will be 5 times faster or 76.29 times too fast.
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timers
PostPosted: Wed Mar 09, 2005 7:25 am     Reply with quote

Sorry to be a pain - Im still lost

Ok lets start over - using my code, How do I set off the timer to run some code after 2hrs using a 4Mhz and a 20Mhz crystal? What must I change in my code so that it runs after 2hrs?
Mark



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

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

PostPosted: Wed Mar 09, 2005 8:15 am     Reply with quote

Code:

  // wait until hours reaches 2
  while(hrs<2);

  // signal that the time is up
  while(1)
  {
    output_high(PIN_B1);
    delay_ms(1000);
    output_low(PIN_B1);
    delay_ms(1000);
  }


Now your timer1 is wrong. I am going to leave it to you to do a search on the board. There are plenty of examples on this. Search for RTC or Real Time Clock and you should find some examples.
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timers
PostPosted: Fri Mar 11, 2005 1:18 am     Reply with quote

Hi

I finally got my timer to work. The problem is that the event time happened, the program just loops. How can I make it exit till the next time.

Quote:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12

#define INTS_PER_SECOND 15 // (4000000/(4*1*65536))


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

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.
++seconds;

if(seconds==60){
mins=mins+1;
seconds=0;
}

if(mins==60){
hrs=hrs+1;
mins=0;
}

if(hrs==24){
hrs=0;
}


int_count = INTS_PER_SECOND;
}
}

void main() {
int_count = INTS_PER_SECOND;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

reset_one_second_counter();

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

// seconds is now >= 20
while(TRUE)
{
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_ms(1000);
output_high(PIN_B1);
delay_ms(1000);
output_low(PIN_B1);
delay_cycles( 1 );

}




}


void reset_one_second_counter(void)
{
int_count = INTS_PER_SECOND;
seconds = 0;
}
Ttelmah
Guest







PostPosted: Fri Mar 11, 2005 4:51 am     Reply with quote

Think for a moment about what happens.
Code:
void main() {
  int_count = INTS_PER_SECOND;
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  set_timer1(0);
  enable_interrupts(INT_TIMER1);
  enable_interrupts(GLOBAL);

  reset_one_second_counter();

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

  // seconds is now >= 20
  while(TRUE)  {
     output_high(PIN_B1);
     delay_ms(1000);
     output_low(PIN_B1);
     delay_ms(1000);
     output_high(PIN_B1);
     delay_ms(1000);
     output_low(PIN_B1);
     delay_cycles( 1 );
  }
}

When your timer 'expires', you move on into a loop that runs for ever, and will never come out. Also you now have no way of going 'back' to the timer code. So do something like this instead:

Code:


  while (true) {
     //This is now the 'main' loop, inside which everything will happen.
     while (seconds < 20)  {
        // wait till 20 secs is up
     }
     //Immediately reset the seconds, so the timer continues
     seconds=0;
     // seconds has now reached 20 and restarted
     //Just toggle the output twice
     //need a variable added called 'count'
     for count=0;count<2;count++) {
        output_high(PIN_B1);
        delay_ms(1000);
        output_low(PIN_B1);
        delay_ms(1000);
     }
     //At this point we loop back to the 'wait', the timer has allready been
     //running for about 4 seconds, and we wait again for it to expire.
  }
}


Best Wishes
bhyatyab



Joined: 26 Jan 2005
Posts: 13

View user's profile Send private message

Timers
PostPosted: Tue Mar 15, 2005 2:34 am     Reply with quote

Hi All

I have a problem with me code. Everything works fine, my clock works 100%. The problem is, when say secs==10, it starts executing the code .... but the timer seems to stop counting than after the code has executed, the timer continues to count. Why is this and how can I resolve it. Thanks guys

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




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;
    }
}






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(GLOBAL);   
 
   



   reset_one_second_counter();

{
start:

 
   
    while(secs==10)
    {      
   output_high(PIN_C2);    //switch phone OFF
    }       
    goto start;
}
}






void reset_one_second_counter(void)
{
    int_count = INTS_PER_SECOND;
    secs = 0;
}
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 1, 2  Next
Page 1 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