Program Does Nothing, Can't Figure it Out

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Hi all,

I am writing myself a journal of knowledge for mid-range PIC microcontroller programming in C using XC8 and MPLAB X. Since I am nothing more than a hobbyist and recreational programmer at best, I can easily go stretches without writing any programs, and it's easy to forget some programming things in between. My little journal is a quick reference for me to come back to when I'm stuck.

This entry talks about the basics of writing an Interrupt Service Routine. I am using the PIC12F629. The intent is to simply have 2 LEDs connected to the MCU. Upon power-up, the blue LED is on. A button press connected to the INT pin of the MCU should turn off the blue LED and flash the red LED on/off 20 times with a 50mS delay.

Throwing power to the device results in nothing happening. I have tried multiple changes to the code, I have tried another MCU chip in case the first one was bad, and I have tested to ensure I have 5V to the device. I indeed have power into the device, but no voltage on the LED outputs at any point. I'm figuring something has to be wrong with the code but it looks fine to me. I need some fresh and more knowledgeable eyes on it.

As always, thanks for the help. Code to follow:

Code:
#include <xc.h>

/**********CONFIGURATION WORD******************/
#pragma config BOREN = OFF, MCLRE = OFF, PWRTE = ON, WDTE = OFF, FOSC = INTRCIO
/**********************************************/

/**********DEFINE GLOBAL VARIABLES*************/
unsigned char GPIOimg;  //SHADOW REGISTER FOR I/O
bit request;  //A FLAG BIT NAMED "request"

/****************I/O MAP***********************/
#define GPIOinit 0b00000000  //ALL GPIO INITIALIZED OFF
#define TRISIOinit 0b00000100  //GPIO <7:3>, <1:0> OUTPUT, GPIO 2 IS INPUT

#define REDmask 0b00010000  //THE BIT LOCATION OF THE RED LED
#define BLUEmask 0b00001000  //THE BIT LOCATION OF THE BLUE LED

/****************BIT VARIATIONS****************/
#define FALSE 0
#define TRUE 1

/*************OSCILLATOR***********************/
#define _XTAL_FREQ 4000000  //OSCILLATOR IS 4MHz

/***********SHADOWED I/O ROUTINES**************/
void doRED_LED_ON(void)
{
  GPIOimg |= REDmask;
  GPIO = GPIOimg;
}

void doRED_LED_OFF(void)
{
  GPIOimg &= ~REDmask;
  GPIO = GPIOimg;
}

void doBLUE_LED_ON(void)
{
  GPIOimg |= BLUEmask;
  GPIO = GPIOimg;
}

void doBLUE_LED_OFF(void)
{
  GPIOimg &= ~BLUEmask;
  GPIO = GPIOimg;
}

/***********INTERRUPT**************************/
void interrupt isr(void)
{
  request = TRUE;
}
/**********THE PROGRAM*************************/
void main(void)
{
  TRISIO = TRISIOinit;
  GPIOimg = GPIOinit;
  GPIO = GPIOinit;
  request = 0;
  INTF = 0;
  GIE = 1;
  INTE = 1;

  while(1)
  {
  doBLUE_LED_ON();
  if (request == TRUE)
  {
  doBLUE_LED_OFF();
  request = FALSE;
  for (unsigned char count = 20; count > 0; count--)
  {
  doRED_LED_ON();
  __delay_ms(50);
  doRED_LED_OFF();
  __delay_ms(50);
  }
  INTF = 0;
  }
  }
}
 

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
You need to initialize the ports as digital I/O.

See ANSEL on page 46 and CMCON on page 36 of the datasheet.
1. I don't recall ever needing to do this with previous projects I've done using this MCU
2. I believe the Analog Inputs are specific only to the 12F675 device, i am using 12F629.

I'm not brushing off your response, only thinking out loud in a group setting.
 

tshuck

Joined Oct 18, 2012
3,534
Yes, ANSEL doesn't affect you, then.

You also need to clear your interrupt source in the ISR, otherwise, it will lockup in an interrupt service loop.

Edit: I vaguely remember someone saying that GIE must be set after all interrupt masking and clearing is done (e.g. clear INTF after setting INTE and setting GIE should be the last bit of initialization done), otherwise it may generate an interrupt.
 
Last edited:

Thread Starter

ke5nnt

Joined Mar 1, 2009
384
Yes, ANSEL doesn't affect you, then.

You also need to clear your interrupt source in the ISR, otherwise, it will lockup in an interrupt service loop.

Edit: I vaguely remember someone saying that GIE must be set after all interrupt masking and clearing is done (e.g. clear INTF after setting INTE and setting GIE should be the last bit of initialization done), otherwise it may generate an interrupt.
Thanks tshuck. I made the changes you suggested. After powering on the device I still did not get the blue LED on GP3 to light, however the interrupt routine now works and the red LED flashes as intended. After reading through the I/O section of the datasheet again, I noticed this:

PIC12F629 Datasheet said:
The exception is GP3, which is input-only
and its TRISIO bit will always read as ‘1’.
Oops, not sure how I missed that the first go. Changing ports for that LED solved that problem. Thanks for the help!
 

tshuck

Joined Oct 18, 2012
3,534
[...]Oops, not sure how I missed that the first go. Changing ports for that LED solved that problem. Thanks for the help!
..and I assumed that the bit in your TRIS settings set to input was the input-only pin. I hadn't thought to check it as a result. Whoops! You live and learn.;)

Glad you got it!
 
Top