Jump to content
ryeg

12f683 Interrupt Problem....

Recommended Posts

I am trying to get an interrupt driven timer working on a 12F683 and have encountered a perplexing problem. When nothing is going in in main(), the interrupt seems to work, but if I insert anything into main it stops working.

 

In the code below the interrupt generates a 500ms ticks and flashes the LED accordingly. It works fine when there in nothing happening in the main() function, but inserting the code shown makes the interrupt erratic.

 

 

#include "system.h"
#include <stdlib.h>
#pragma DATA _CONFIG, _FCMEN_OFF&_IESO_OFF&_MCLRE_OFF&_WDT_OFF&_INTOSCIO 
#pragma CLOCK_FREQ  4000000 //processor is 12F683 using internal oscillator</P> <P>int xseconds = 0;
unsigned char tick;
unsigned char tick1;
void interrupt( void )
{
  tmr0 +=9;	
  tick++;	   
  if(tick>19)   
  {
 tick=0;
 tick1++;	  
 if(tick1>49)	   //every 500 ms 
 {
  gpio.4 = xseconds.0; //flash LED 
  tick1=0;		  //reset tick1.
  xseconds++;
 }
  }
intcon.2=0;	   //clear TMR0 overflow flag
}	
void main()
{ intcon = 0b1000000;
option_reg = 0b10000000;
osccon =  0b01100000;   // 4 MHz internal oscillator (high accuracy not reqired)
wdtcon =  0x00;		 // Watchdog not used
trisio =  0b00001001;   // GP3 and GP0 are inputs
cmcon0 =  7;   // all inputs are digital not   (for comparitor manual page 56)
ansel  =  0x00;   // sets ports 0-2 for digital use (not for A/D manual page 33)   
gpio   =  0x00;		// initialize GPIO port bits to zero</P> <P> for(i=0;i<10;i++)	// flashing LED indicates successful start
{ gpio.5= 1; 
 delay_ms(50);
 gpio.5 = 0;
 delay_ms(50);
} while(1)	
{	  
 delay_ms(200);	  // if this code runs the interrupt gets crazy
 gpio.5 = !gpio.5; 
}	  
}

 

I have read the manual (honest), but after considerable study I can't seem to find the problem.

 

...and I wish I could figure out how to insert code correctly in these posts.........

 

 

Happy New Year all

Share this post


Link to post
Share on other sites

Hi Rye,

 

But did you read the 'C' manual though ?

 

Have you tried using a do {...} while(1);

	do {
	gpio.5 = 1; 
	delay_ms(50);
	gpio.5 = 0;
	delay_ms(50);
} while (1);

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Looks like a classic RMW (read modify write) issue to me.

 

See Microchip Wiki: Read-modify-write issue when setting/clearing single port register bits

 

The fix is:

1. add this line with the other global variables before any functions:

volatile unsigned char gpio_buf;

2. for all instances of gpio where it is modified (i.e. not just testing input bits), replace it with with gpio_buf and add after it a statement to copy gpio_buf to gpio.

e.g. (snipped parts of code shown as ...)

...
unsigned char tick1;
volatile unsigned char gpio_buf;
void interrupt( void )
...
 if(tick1>49)	   //every 500 ms
 {
  gpio_buf.4 = xseconds.0; //flash LED
  gpio=gpio_buf;
  tick1=0;		  //reset tick1.
...
ansel  =  0x00;   // sets ports 0-2 for digital use (not for A/D manual page 33)  
gpio_buf   =  0x00;		// initialize GPIO port bits to zero
	gpio=gpio_buf;
	for(i=0;i<10;i++)	// flashing LED indicates successful start
{ gpio_buf.5= 1;
	   gpio=gpio_buf;
	   delay_ms(50);
	   gpio_buf.5 = 0;
	   gpio=gpio_buf;
	   delay_ms(50);
	 }
	 while(1)	
	 {	  
		delay_ms(200);	  // X[if this code runs the interrupt gets crazy]X Interrupt should be ok now.
		gpio_buf.5 = !gpio_buf.5;
		gpio=gpio_buf;
	  }	  
}

Edited by IanM

Share this post


Link to post
Share on other sites
I am trying to get an interrupt driven timer working on a 12F683 and have encountered a perplexing problem. When nothing is going in in main(), the interrupt seems to work, but if I insert anything into main it stops working.

 

In the code below the interrupt generates a 500ms ticks and flashes the LED accordingly. It works fine when there in nothing happening in the main() function, but inserting the code shown makes the interrupt erratic.

 

 

#include "system.h"
#include <stdlib.h>
#pragma DATA _CONFIG, _FCMEN_OFF&_IESO_OFF&_MCLRE_OFF&_WDT_OFF&_INTOSCIO 
#pragma CLOCK_FREQ  4000000 //processor is 12F683 using internal oscillator</P> <P>int xseconds = 0;
unsigned char tick;
unsigned char tick1;
void interrupt( void )
{
  tmr0 +=9;	
  tick++;	   
  if(tick>19)   
  {
 tick=0;
 tick1++;	  
 if(tick1>49)	   //every 500 ms 
 {
  gpio.4 = xseconds.0; //flash LED 
  tick1=0;		  //reset tick1.
  xseconds++;
 }
  }
intcon.2=0;	   //clear TMR0 overflow flag
}	
void main()
{ intcon = 0b1000000;
option_reg = 0b10000000;
osccon =  0b01100000;   // 4 MHz internal oscillator (high accuracy not reqired)
wdtcon =  0x00;		 // Watchdog not used
trisio =  0b00001001;   // GP3 and GP0 are inputs
cmcon0 =  7;   // all inputs are digital not   (for comparitor manual page 56)
ansel  =  0x00;   // sets ports 0-2 for digital use (not for A/D manual page 33)   
gpio   =  0x00;		// initialize GPIO port bits to zero</P> <P> for(i=0;i<10;i++)	// flashing LED indicates successful start
{ gpio.5= 1; 
 delay_ms(50);
 gpio.5 = 0;
 delay_ms(50);
} while(1)	
{	  
 delay_ms(200);	  // if this code runs the interrupt gets crazy
 gpio.5 = !gpio.5; 
}	  
}

 

I have read the manual (honest), but after considerable study I can't seem to find the problem.

 

...and I wish I could figure out how to insert code correctly in these posts.........

 

 

Happy New Year all

Hii Ryeg,

Read the code. I am a novice with PIC, but because of all the nice ppl around here I have been able to play with them especially the timer0 module. I would not use delay routine once I turn on the timer interrupt. In your case the delay_ms(200) might not get completed as while the delay function is called, the control has to leave 2 times per millisecond to jump to ISR (considering the timer0 counts upto 500usec/interrupt). Maybe this is what is causing trouble. Secondly we could save ram space by

tick1++;
if(tick1>49)
{
  tick1=0;
  gpio.4=~gpio.4 //for flashing LED this wont need xseconds to be declared
}// You are using timer0 with 1:2 prescaler which might not yeild exact 500uSec interrupt

instead of using gpio.4=xseconds.

BTW, the snippet you showed in your post is not having anything which turns on timer0 interrupt<intcon.5=1> or <intcon.T0IE=1>

I hope you find some of the above of use.

Regards

Shree

Share this post


Link to post
Share on other sites

Hi Ryeg,

Maybe the code below (its modified copy of your code) might work and serve your purpose.

#include "system.h"
#include <stdlib.h>//I dont know why you used this
#pragma DATA _CONFIG, _FCMEN_OFF&_IESO_OFF&_MCLRE_OFF&_WDT_OFF&_INTOSCIO 
#pragma CLOCK_FREQ  4000000 //processor is 12F683 using internal oscillator
unsigned char tick;
unsigned char tick1;
unsigned char tick2; //this is for 200mS counting for gpio.5
void interrupt( void )
{
tmr0 +=9;	
tick++;	   
if(tick>19)   
{
	  tick=0;
	  tick1++;
							 tick2++;
							 if(tick2>39) //every 200mS
							 {
							   gpio.5=~gpio.5;
							   tick2=0;
							 }	  
	  if(tick1>99)	   //every 500 ms 
	  {
	   gpio.4 = ~gpio.4; //flash LED 
	   tick1=0;		  //reset tick1.
  		}
  	}
	intcon.T0IF=0;	   //clear TMR0 overflow flag
}	
void main()
{ 
//intcon = 0b1000000;
option_reg = 0b10001000; //timer0 prescaler set to 1:1 for a better accuracy
osccon =  0b01100000;   // 4 MHz internal oscillator (high accuracy not reqired)
wdtcon =  0x00;		 // Watchdog not used
	trisio =  0b00001001;   // GP3 and GP0 are inputs
cmcon0 =  7;   // all inputs are digital not   (for comparitor manual page 56)
	ansel  =  0x00;   // sets ports 0-2 for digital use (not for A/D manual page 33)   
	gpio   =  0x00;		// initialize GPIO port bits to zero
unsigned char i;
for(i=0;i<10;i++)	// flashing LED indicates successful start
{
	gpio.5= 1; 
	delay_ms(50);
	gpio.5 = 0;
	delay_ms(50);
}
intcon.GIE=1;
intcon.T0IE=1;
while(1)	
{ }	  
}

Regards

Shree

P.S: I tested neither this nor your original code.

P.P.S: Sorry I didnt get it initially that you need the LED at gpio.5 flashing too but at a different rate. Hence I edited the code. I think this could would work. Again rule of thumb for me, never use delay routines when implementing timer modules. Bye and happy new year!

Edited by Shree

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...