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

PIC16f877a Timer and interrupt problem

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



Joined: 26 May 2009
Posts: 12

View user's profile Send private message

PIC16f877a Timer and interrupt problem
PostPosted: Wed Jul 01, 2009 6:12 am     Reply with quote

I am doing a programming on a rpm (revolution per minute) counter for a toy car. When an IR sensor signal input to the PIC, interrupt will be enabled and timer 0 will started to count the rpm and display the value in 16x2 lcd.
The below code shows about the interrupt and timer0:
Code:

#use delay (clock = 20000000)
#include <LCD.C>
#define INTS_PER_MINUTE 153   // (40000000/(4*256*256))

BYTE minutes;      // A running minutes counter
BYTE int_count;    // Number of interrupts left before a minute has elapsed

#int_rtcc   // This function is called every time
void clock_isr() {  // the RTCC (timer0) overflows (255->0).
   BYTE start;
   int_count=INTS_PER_MINUTE;   
   set_timer0(0);
   setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_EXT); // For this program this is apx 153 times
   
   if(--int_count==0) {  // per minute.
   ++minutes;
   int_count=INTS_PER_MINUTE;
    }
 }


And the to display the rpm value per minute in lcd, the code is shown below:
Code:

void main ( void )
{
   char display [ 4 ];

   // Initialization
   input(PIN_B0);
   output_high(PIN_A0);
   output_high(PIN_A1);
   output_high(PIN_A2);
   output_high(PIN_A3);
   output_low(PIN_A4);
   output_low(PIN_A5);

   lcd_init();

   lcd_gotoxy (1,1);
   lcd_putc ("RPM:" +minutes );
}


The above code are combined together but nothing shown in the lcd.
Can anyone correct my mistakes? Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jul 01, 2009 12:53 pm     Reply with quote

Quote:
#int_rtcc // This function is called every time
void clock_isr() { // the RTCC (timer0) overflows (255->0).
BYTE start;
int_count=INTS_PER_MINUTE;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT); // For this program this is apx 153 times

if(--int_count==0) { // per minute.
++minutes;
int_count=INTS_PER_MINUTE;
}
}

Never enable global interrupts inside an interrupt routine. The 16F877a
does not support nested interrupts.

Also, the PIC has a built-in module CCP that can be used to measure
frequency. There are several example threads on the forum which
show how to do this. Do a search for Tachometer on the forum's
search page.
khwoo



Joined: 26 May 2009
Posts: 12

View user's profile Send private message

Problem on ccs compiler ver. 4.068 code
PostPosted: Thu Jul 02, 2009 3:46 am     Reply with quote

Code:

#include <16f877a.h>
#use delay (clock = 20000000)
#fuses NOWDT,NOPUT,HS,NOPROTECT
#include <LCD.C>
#define INTS_PER_10SECOND 153     // (4000000/(4*256*256*0.1))

BYTE ten_seconds;      // A running seconds counter
BYTE int_count;    // Number of interrupts left before ten second has elapsed

#int_rtcc                          // This function is called every time
void clock_isr() {                 // the RTCC (timer0) overflows (255->0).
                                   // For this program this is apx 76 times
    if(--int_count==0) {           // per second.
      ++ten_seconds;
      int_count=INTS_PER_10SECOND;
    }
}


Can anyone check the problem for the above code? I m using 4Mhz crystal oscillator, and i would like to count for every 10 seconds... I had refered to the examples in ccs..

The code below is about interrupt and lcd display:
Code:

void main() {

   BYTE start;

   int_count=INTS_PER_10SECOND;
   
   set_timer0(0);
   setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT);
   enable_interrupts(INT_RB);
  // enable_interrupts(GLOBAL);

   while (TRUE)
   {
   set_tris_a(1);
   lcd_init();
   lcd_putc("\RPM:\n");
   lcd_putc("++ten_seconds");
   }   
}


My interrupt pin is RB0 (INT) and RA0 to RA3 are my output pins connected to LCD pin 11 to 14.
Anything wrong in the code above kindly correct me.
Because its cannot display anything..

Thanks..
Ttelmah
Guest







PostPosted: Thu Jul 02, 2009 7:50 am     Reply with quote

The obvious thing is that you do need to enable_interrupts(GLOBAL) _in the main_.
The point about this, is that you _must_ have it, or the interrupt will not be responded to, but you must _never have it inside the interrupt_ (not only pointless here, since the global interrupt must be enabled, or you will never arrive in the handler, but 'lethal', since the hardware disables this during the interrupt, and re-enabling it,can result in interrupts inside interrupts, which the chip does not support.....).

Best Wishes
mkuang



Joined: 14 Dec 2007
Posts: 257

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

Re: Problem on ccs compiler ver. 4.068 code
PostPosted: Thu Jul 02, 2009 8:43 am     Reply with quote

khwoo wrote:
Code:

#include <16f877a.h>
#use delay (clock = 20000000)
#fuses NOWDT,NOPUT,HS,NOPROTECT
#include <LCD.C>
#define INTS_PER_10SECOND 153     // (4000000/(4*256*256*0.1))

BYTE ten_seconds;      // A running seconds counter
BYTE int_count;    // Number of interrupts left before ten second has elapsed

#int_rtcc                          // This function is called every time
void clock_isr() {                 // the RTCC (timer0) overflows (255->0).
                                   // For this program this is apx 76 times
    if(--int_count==0) {           // per second.
      ++ten_seconds;
      int_count=INTS_PER_10SECOND;
    }
}


Can anyone check the problem for the above code? I m using 4Mhz crystal oscillator, Thanks..


You are using a 4Mhz crystal? The code says 20Mhz.

That said, if you are using a 4Mhz crystal, the basic tick is 1us, so your timer0 in 8 bit mode will overflow every 1us times 256 * 256 = 65.536ms. Timer0 overflows 15.259 times per second.

If you want your interrupt to fire every 10s you have to use timer0 in 16 bit mode. I am not sure how you would do that in your device but chances are if you use:

setup_counters( RTCC_INTERNAL | RTCC_DIV_256 );
it would be in 16 mode. By trial and error you can figure out that with a 4Mhz crystal (1 Mhz instruction clock) you would set timer0 to 26473 so that it would overflow every (65536-26473)*1us*256 = 10.000128 seconds. Your complete code in main() would be something like:

Code:

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
set_timer0(26473);
clear_interrupt(int_timer0);
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);
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