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

Interrupt problem with 12F675

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



Joined: 21 Nov 2005
Posts: 2

View user's profile Send private message

Interrupt problem with 12F675
PostPosted: Tue Dec 06, 2005 12:29 pm     Reply with quote

Hi,

First off: I am new to CCS! I am using PCWH 3.210 on Win XP. I am trying to program a PIC12F675 through a PICkit 1 board.

I have the following code:

Code:
#include <12f675.h>
#include "led_only.h"

#use fast_io(A)

#fuses INTRC_IO,NOWDT,NOMCLR,NOBROWNOUT,NOPROTECT,PUT

#byte OPTION_REG  = 0x81
#byte GPIO        = 0x05
#byte ADCON0      = 0x1F
#byte ANSEL       = 0x9F
#byte CMCON       = 0x19

#bit GPIO3  = 0x05.3

#bit GPIF   = 0x0B.0
#bit GPIE   = 0x0B.3
#bit GIE    = 0x0B.7
#bit GPPU   = 0x81.7
#bit IOCB3  = 0x96.3


unsigned char   Inner;
unsigned char   Outer;
int            LedDirection;

void         Init();
void         Led1();
void         Led2();
void         Led3();
void         Led4();
void         Led5();
void         Led6();
void         Led7();
void         Led8();
unsigned char Debounce();
void         Delay(char value);

void
main ()
{

   ext_int_edge(l_to_h);
   enable_interrupts(int_ext);
   enable_interrupts(global);

   Init();

   while(TRUE)
   {
      Led1();

      Delay(1000);
      
      if (LedDirection == FORWARD)
         Led8();
      else
         Led4();

      Delay(100);
   }
}

void
Init ()
{
   #asm
      call  0x3FF
      bsf   0x03,5
      movwf 0x90
   #endasm

   IOCB3 = SET;
   GPIE = SET;
   GIE = SET;
   LedDirection = FORWARD;
}

// Services Timer 0, GPIO bit change and A/D conversion.
#int_ext
Isr()
{
   if ((GPIE & GPIF) == SET)      // GPIF indicates change in GPIO bits.
   {
      if (Debounce() == TRUE)      // Check if direction change button has been pressed.
      {
         if (LedDirection == FORWARD)
            LedDirection = BACKWARD;
         else
            LedDirection = FORWARD;
      }
      GPIF = CLEAR;
   }

}

// LED 1 - D0 on schematic.
void
Led1 ()
{
   set_tris_A (LED1TRIS);
   output_A (LED1ON);
}

// D1
void
Led2 ()
{
   set_tris_A (LED2TRIS);
   output_A (LED2ON);
}

// D2
void
Led3 ()
{
   set_tris_A (LED3TRIS);
   output_A (LED3ON);
}

// D3
void
Led4 ()
{
   set_tris_A (LED4TRIS);
   output_A (LED4ON);
}

// D4
void
Led5 ()
{
   set_tris_A (LED5TRIS);
   output_A (LED5ON);
}

// D5
void
Led6 ()
{
   set_tris_A (LED6TRIS);
   output_A (LED6ON);
}

// D6
void
Led7 ()
{
   set_tris_A (LED7TRIS);
   output_A (LED7ON);
}

// D7
void
Led8 ()
{
   set_tris_A (LED8TRIS);
   output_A (LED8ON);
}

unsigned char
Debounce()
{
   if (GPIO3 == SET)
   {
      return FALSE;
   }
   else
   {
      return TRUE;
   }
}

void
Delay (char value)
{
   for (Outer = value; Outer != 0; Outer--)
      for (Inner = 0xFF; Inner != 0; Inner--)
         ;

   return;
}

header file:

#ifndef LED_ONLY_H
#define LED_ONLY_H

#define   LED1TRIS   0b11001111
#define   LED2TRIS   0b11001111
#define   LED3TRIS   0b11101011
#define   LED4TRIS   0b11101011
#define   LED5TRIS   0b11011011
#define   LED6TRIS   0b11011011
#define   LED7TRIS   0b11111001
#define   LED8TRIS   0b11111001
#define   LED1ON      0b00010000
#define   LED2ON      0b00100000
#define   LED3ON      0b00010000
#define   LED4ON      0b00000100
#define   LED5ON      0b00100000
#define   LED6ON      0b00000100
#define   LED7ON      0b00000100
#define   LED8ON      0b00000010

#define   OPEN             1
#define   CLOSED         0
#define   SET               1
#define   CLEAR           0

#define   FIRSTLED   0
#define   LASTLED      7
#define   FORWARD      0
#define  BACKWARD    1

#endif // LED_ONLY_H


The expected behaviour: Led's 1 and 8 flash in an alternating fashion. Once the pushbutton is pressed, Led's 1 and 4 flash. If the pushbutton is pressed again, it's back to Led's 1 and 8 and so on...

Once the program starts, Led's 1 and 8 do flash. However, when I press the pushbutton, system freezes and Led 1 is on permanently (but not flashing).

Here's the funny thing: The EXACT code compiled with Hi-Tech PICC Lite works fine -- that is the pushbutton works as expected. Of course I know there are differences in compiler startup code, but I can't see what the problem is here.

Any help would be appreciated.

Todd
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Tue Dec 06, 2005 12:58 pm     Reply with quote

Todd,

I'm just starting on my morning coffee so this is sort of a dumb question, but I can't quite see how you'd "lock out" the state change resulting in an interrupt if a person sits on the button.

Pushing a button to us seems fast, but not for these chips. I guess I'm wondering what happens if a button press slams you into the ISR, you perform some action, but then, the button remains pressed for hundreds of milliseconds before one can remove the finger. Does one keep re-entering the ISR, or is the interrupt somehow masked until you let go?

(In POLLING a button, it is easy to construct software that forces one to release the button before the system will listen to the next button press. But the problem is more intricate when interrupts are involved.)

(I am having a problem on some connected 8722s in which an interrupt is serviced a few times just fine, but then stops working. I am apparently not servicing it correctly, so I'm interested in all posts with interrupt problems.)

One of my problems is that I don't know what the little patch of assembly does in your init() routine.

Not much help, I'm afraid. But I urge you to think carefully about the "sit on the line" problem. There may well be a difference between the HiTech compiler and CCS in the "overhead" code for interrupt servicing. HiTech, for example, may enter the ISR and immediately mask the B0 interrupt until one exits the ISR. You appear comfortable in assembly, so you could check out the differences in entry/exit code.

Good luck,

Smile Robert
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 06, 2005 1:37 pm     Reply with quote

You're using #INT_EXT, but according to other things in your code,
you want to use GPIO change interrupts. Those are two different
types of interrupts. Look near the end of the 12F675.H file, and
you'll see a list of all the interrupt constants that can be used with
that PIC. You likely want to use INT_RA or one of the pin specific
versions of that interrupt. Look at the list. Change your setup
code, and the isr.

Also, you're doing a lot things that are not needed in CCS. All
the interrupt detection (ie., checking flags, etc.) is automatically
done for you by the compiler. You don't need that stuff in your isr.
Also, if you're using interrupt-on-change, you need to read the GPIO
port in the isr, to clear the "change" condition. See section 3.2.2 of
the 12F675 data sheet.

The compiler also will take care of reading the OSCCAL value and
updating the register. You don't need that ASM code in there.
Basically, if you used CCS standard i/o mode, you could reduce the
total line count in your program to at 25% or less, of your current
program size.
toddintr



Joined: 21 Nov 2005
Posts: 2

View user's profile Send private message

PostPosted: Tue Dec 06, 2005 3:40 pm     Reply with quote

PCM programmer,

THANKS! Per your comments, I changed #int_ext to #int_ra, which immediately solved the problem and enabled the pushbutton. The program now works as expected.

I realize that my code uses the CCS compiler in the least efficient manner (directly twiddling bits and registers). However, I haven't come across documentation that explains the effective methodology for using CCS C. The CCS C Reference Manual has hints in it, but not the big picture.

I know there are the examples that come w/ the code, plus there is this forum, but a central tutorial that explains the CCS way of doing things would be most welcome. (Otherwise, the true strength of the CCS compiler may not be understood. Just some feedback from a customer.)

Regards,

Todd

PS: You are doing an EXCELLENT job. Everyone should be so lucky to have their question answered by PCM programmer! Very Happy



PCM programmer wrote:
You're using #INT_EXT, but according to other things in your code,
you want to use GPIO change interrupts. Those are two different
types of interrupts. Look near the end of the 12F675.H file, and
you'll see a list of all the interrupt constants that can be used with
that PIC. You likely want to use INT_RA or one of the pin specific
versions of that interrupt. Look at the list. Change your setup
code, and the isr.

Also, you're doing a lot things that are not needed in CCS. All
the interrupt detection (ie., checking flags, etc.) is automatically
done for you by the compiler. You don't need that stuff in your isr.
Also, if you're using interrupt-on-change, you need to read the GPIO
port in the isr, to clear the "change" condition. See section 3.2.2 of
the 12F675 data sheet.

The compiler also will take care of reading the OSCCAL value and
updating the register. You don't need that ASM code in there.
Basically, if you used CCS standard i/o mode, you could reduce the
total line count in your program to at 25% or less, of your current
program size.
toddintr



Joined: 21 Nov 2005
Posts: 2

View user's profile Send private message

PostPosted: Tue Dec 06, 2005 3:44 pm     Reply with quote

Robert,

The assembly code retrieves the calibration value from the last position in memory (where it is stored when leaving the factory) and uses it to set the chip calibration register.

Thanks for your response,

Todd

RKnapp wrote:
Todd,

One of my problems is that I don't know what the little patch of assembly does in your init() routine.

Smile Robert
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