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

Timer0 interrupt on pic12f682

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



Joined: 02 Aug 2010
Posts: 30

View user's profile Send private message

Timer0 interrupt on pic12f682
PostPosted: Mon Aug 02, 2010 12:29 pm     Reply with quote

Hello,

I am having trouble with the timer0 interrupt. The code suppose to check port GP2 for a low to high signal and interrupt on timer0 overflow.
When the code jumps to the interrupt service routine the LED suppose to turn on.

It's simply not working. Am i missing something in the code?

Code:


#include <12f683.h>
#include <math.h>
#include <stdlib.h>

#fuses INTRC_IO,NOWDT,NOPROTECT,NOMCLR
#use delay (internal=4000000) //(clock=4M)


//address of the TRISIO register
#byte   TRISIO  = 133
// bit assignment of the TRISIO registers
#bit     TRISIO_1= TRISIO.1
#bit     TRISIO_2= TRISIO.2


#byte    GPIO = 5
//bit assignment for I/O registers
#bit     GPIO_1 = GPIO.1
#bit     GPIO_2 = GPIO.2


#byte ANSEL=159
#bit ANSEL_1= ANSEL.1
#bit ANSEL_2= ANSEL.2

#byte ADCON0 = 31
#bit  ADCON0_0 = ADCON0.0
#bit  ADCON0_1 = ADCON0.1
#bit  ADCON0_2 = ADCON0.2
#bit  ADCON0_3 = ADCON0.3
#bit  ADCON0_7 = ADCON0.7

//interrupt variables
#byte TMR0=1
#bit  TMR0_0=TMR0.0
#bit  TMR0_1=TMR0.1

#byte OPTION_REG=129
#bit  OPTION_REG_0=OPTION_REG.0
#bit  OPTION_REG_1=OPTION_REG.1
#bit  OPTION_REG_2=OPTION_REG.2
#bit  OPTION_REG_3=OPTION_REG.3
#bit  OPTION_REG_4=OPTION_REG.4
#bit  OPTION_REG_5=OPTION_REG.5
#bit  OPTION_REG_6=OPTION_REG.6
#bit  OPTION_REG_7=OPTION_REG.7

#byte INTCON=11
#bit  INTCON_2=INTCON.2  //TOIF Timer0 Overflow Interrupt Flag
#bit  INTCON_4=INTCON.4
#bit  INTCON_5=INTCON.5  //TOIE Enables the Timer0 interrupt
#bit  INTCON_7=INTCON.7  //GIE Global Interrupt Enable bit

//comparator
#byte CMCON=25

//---------------------------------------------------
//function prototypes:
//---------------------------------------------------
// initialize the interrupt registers
   void Init(void);

//---------------------------------------------------
// Main
//---------------------------------------------------
  void main()
  {
   //comparator settings
   CMCON=0b00000111; //TURN OFF THE COMPARATOR

   //Pin input/output settings
   TRISIO_2=1;      // set GP2 to input
   TRISIO_1=0;       // set GP1 to output

   //Set Analog and digital pins
   ANSEL_1=0;       // pin GP1 is digital
   ANSEL_2=0;       // pin GP2 is digital

  //-----------------------------------------------------
  //main loop
  //-----------------------------------------------------

  //intitialize timer 0
    Init();

  //make sure pin GP1 output is zero
    GPIO_1=0;

  while(1)
   {
   // do nothing except when there is an interrupt
   }

 }

Void Init (void)

{
  //CLEAR THE TMRO REGISTER
    TMR0=0;

  // Assign the prescaler to watchdog timer ( 1:1)
  //interrupt pin configurations
   OPTION_REG_0=0; // 1:1 prescaler
   OPTION_REG_1=0; // 1:1 prescaler
   OPTION_REG_2=0; // 1:1 prescaler
   OPTION_REG_3=1; // ASSIGN prescaler to WATCH DOG TIMER SO THAT   //TIMER0 INCREMENTS AT 1:1 RATIO WITH INTERNAL INSTRUCTION CLOCK
   OPTION_REG_4=0; //Increment on low to high transition on T0CKI pin
   OPTION_REG_5=1;// Transition on T0CKI pin
   OPTION_REG_6=0; //Interrupt on falling edge of INT pin
   OPTION_REG_7=0; //GPIO pull-ups are enabled

   INTCON_5=1; //TOIE enable the TMRO overflow interrupts
   INTCON_7=1; //GIE enable the global interrupts
}


#int_timer0      // associates the interrupt with timer0
void timer0interrupt(void)
{
     //INTCON_2 : timer0 overflow interrupt flag
     //INTCON_5  timer0 overflow interrupt Enable bit

   If (INTCON_2 && INTCON_5)
     {
      INTCON_2=0; //reset timer0 interrupt flag
      GPIO_1=1;    // light an LED

     }

 }



mkuang



Joined: 14 Dec 2007
Posts: 257

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

PostPosted: Mon Aug 02, 2010 1:13 pm     Reply with quote

You are not using any of the CCS built-in functions. That makes your code very hard to debug without looking at the datasheets. Search this forum on how to write a simple test program using standard CCS functions.
ckielstra



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

View user's profile Send private message

PostPosted: Mon Aug 02, 2010 3:42 pm     Reply with quote

Code:
   OPTION_REG_4=0; //Increment on low to high transition on T0CKI pin
This causes the Timer0 to count pulses on the external clock input pin, but you have configured the fuses to use the internal clock. Result is the timer0 not counting.

Code:
   If (INTCON_2 && INTCON_5)
Not an error, but this line can be removed. The hardware will only enter the interrupt routine when the interrupt is enabled and triggered on overflow, so no need to test these bits.
Code:
      INTCON_2=0; //reset timer0 interrupt flag
Another line not needed. CCS automatically adds code to clear this interrupt. The only interrupt you have to clear manually in CCS are the PortB interrupts.

The advantage of using the CCS supplied functions over directly accessing registers yourself is that it makes your program a lot easier to read and it is very easy to port your program to another processor (often only the processor include file has to be changed).

Note that in the converted program below a lot of your original comments can be stripped because the code has become self documenting.

Code:
#include <12f683.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOMCLR
#use delay (internal=4000000) //(clock=4M)


//---------------------------------------------------
//function prototypes:
//---------------------------------------------------
// initialize the interrupt registers
void Init(void);

//---------------------------------------------------
// Main
//---------------------------------------------------
  void main()
  {
    //TURN OFF THE COMPARATOR
    setup_comparator(NC_NC_NC_NC);
   
    // Turn off the Capture/Compare module
    setup_ccp1(CCP_OFF);

    //Pin input/output settings
    #use fast_io(A)
    set_tris_a(0b111111101);

   //Set Analog and digital pins
   // pin GP1 is digital
   // pin GP2 is digital
    setup_adc(ADC_OFF);
    setup_adc_ports(sAN0 | sAN3);       // or  setup_adc_ports(NO_ANALOGS);


  //-----------------------------------------------------
  //main loop
  //-----------------------------------------------------

    //intitialize timer 0
    Init();

    //make sure pin GP1 output is zero
    output_low(PIN_A1);

     while(1)
    {
        // do nothing except when there is an interrupt
    }
 }

void Init(void)
{
    // setup Timer 0
    set_timer0(0);
    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);

    // enable the TMRO overflow interrupts
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
}


#int_timer0      // associates the interrupt with timer0
void timer0interrupt(void)
{
    output_high(PIN_A1);
}
kbruin79



Joined: 02 Aug 2010
Posts: 30

View user's profile Send private message

PostPosted: Mon Aug 02, 2010 5:07 pm     Reply with quote

Hi Ckielstra, Thank you for taking the time to look at the code i really appreciated.
You said that "i set the Timer0 to count pulses on the external clock input pin." That's right
Code:

OPTION_REG_4=0; //Increment on low to high transition on T0CKI pin

" but you have configured the fuses to use the internal clock. Result is the timer0 not counting. "
I don't understand this part. Timer0 Clock Source Select bit "TOCS" is set to transistion on the TOCKl pin not the internal clock. Or am i missing something ?
Code:

OPTION_REG_5=1;// TOSC   1=Transition on T0CKI pin  0=internal instruction cycle clock


Thank you
ckielstra



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

View user's profile Send private message

PostPosted: Mon Aug 02, 2010 5:26 pm     Reply with quote

My mistake, I didn't read your post very well and assumed you were using the internal clock as a time base for Timer0.

There are too many variables in your setup to make a suggestion for where the problem could be. To reduce the scope I suggest you use the internal clock for the moment.
Use my posted program and modify the timer setup to:
Code:
    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256);
And replace the interrupt function by:
Code:
#int_timer0      // associates the interrupt with timer0
void timer0interrupt(void)
{
    static int count;

    if (count++ == 50)
    {
        output_toggle(PIN_A1);
        count = 0;
    }
}
These changes should toggle the LED every 0.6 seconds.

If this isn't working than you most likely have a hardware problem related to the PIC not starting up. Otherwise, if the LED is flashing, I suspect a problem with your external applied pulse.

Also post your compiler version number.
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