Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

need help on pic16f690 stopwatch debug

Status
Not open for further replies.

tigerpoh

New Member
dear all, my stopwatch seems like not working. as for timing, it should be inside the interrupt loop together with my external interrupt (infrared sensor), * once the infrared sensor detect signal, the stopwatch will start to count, once detect again the stop watch will stop.

based on my current code, it seems like when the infrared detect, the stopwatch will run , but when a second interrupt occur, the stopwatch cannot stop. May some one help to edit my code. i had already cleared all possible flag after each interrupt.

#include <pic.h>
#define _XTAL_FREQ 4000000L
//__CONFIG (FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & BOREN_OFF);
unsigned int n,g,p,q,r,s,t,a,b,c,d,start,x,counter=0;
unsigned char display []={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0 1 2 3 4 5 6 7 8 9


void main (void)
{
ANSEL=0x00;
TRISC=0b00000000;
TRISB=0x00;
TRISA=0b00000100;
nRABPU=0;
WPUA=0b00000100;
PORTC=0X00;
PORTB=0b00000000;

OPTION_REG=0x07;
TMR0=0xd8;
IOCA=0x04;//ENABLE RA2 INTERRUPT
RABIE=1;// PROTA/PORTB change interrupt enable
//PEIE=1;
T0IE=0;// Timer0 overflow interrupt enable
GIE=1; // Global interrupt enable



while(1)
{

}
}
static void interrupt isr(void)
{
if(RABIF)
{


if (x==1)
{
x=0;
}
else
{
x=1;
TMR0=0;
T0IE=0;
T0IF = 0;
RABIF = 0;

}

if (x==0)
{
T0IE=1;
TMR0=0xd0;

PORTB=0b11100000;
PORTC=display[d];
__delay_ms(1);
PORTB=0b11010000;
PORTC=display[c];
__delay_ms(1);
PORTB=0b10110000;
PORTC=display;
__delay_ms(1);
PORTB=0b01110000;
PORTC=display[a];
__delay_ms(1);
d++;
if(d>9)
{
d=0;
if (c<10)
c++;
else c=0;
}
if(c>9)
{
c=0;
if(b<10)
b++;
else b=0;
}
if(b>9)
{
b=0;
if(a<5)
a++;
else a=0;
}

TMR0=0xd8;
T0IF = 0;
RABIF = 0;
}
}
}
 
Last edited:
Try posting the code (with spaces) inside the proper tags so that it's easier to read. Click the "#" symbol in the editor window, and then copy and paste your code directly between the tags that show up. It will make it much easier to read ;)
 
oh i see i am new over here~ sorry bout the messy code~

Code:
#include <pic.h>
#define _XTAL_FREQ 4000000L
//__CONFIG (FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & BOREN_OFF);
unsigned int n,g,p,q,r,s,t,a,b,c,d,start,x,counter=0;
unsigned char display []={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0 1 2 3 4 5 6 7 8 9


void main (void)
{
 ANSEL=0x00;
 TRISC=0b00000000;
 TRISB=0x00;
 TRISA=0b00000100;
 nRABPU=0;
 WPUA=0b00000100;
 PORTC=0X00;
 PORTB=0b00000000;
  
 OPTION_REG=0x07;
 TMR0=0xd8;
 IOCA=0x04;//ENABLE RA2 INTERRUPT
 RABIE=1;// PROTA/PORTB change interrupt enable
 //PEIE=1;
 T0IE=0;// Timer0 overflow interrupt enable
 GIE=1; // Global interrupt enable
 


while(1)
 {
 
 }
}
static void interrupt isr(void)
{
 if(RABIF)
 {


 if (x==1)
{
x=0;
}
else
{
		x=1;
   		 TMR0=0;
		T0IE=0;
  		  T0IF = 0;
 		 RABIF = 0;

} 

if (x==0)
{
   T0IE=1;
   TMR0=0xd0;
 
    PORTB=0b11100000;
  PORTC=display[d];
 __delay_ms(1);
  PORTB=0b11010000;
  PORTC=display[c];
  __delay_ms(1);
  PORTB=0b10110000;
  PORTC=display[b];
  __delay_ms(1);
  PORTB=0b01110000;
  PORTC=display[a];
  __delay_ms(1);
   d++;
   if(d>9)
   {   
    d=0;
    if (c<10)
    c++;
    else c=0;
    }
    if(c>9)
    {
    c=0;
    if(b<10)
    b++;
    else b=0;
    }
    if(b>9)
    {
    b=0;
    if(a<5)
    a++;
    else a=0;
    }
 
    TMR0=0xd8;
    T0IF = 0;
  RABIF = 0;
 }
}
}
 
Like this
Code:
#include <pic.h>
#define _XTAL_FREQ 4000000L
//__CONFIG (FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & BOREN_OFF);
unsigned int n,g,p,q,r,s,t,a,b,c,d,start,x,counter=0;
unsigned char display []={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0 1 2 3 4 5 6 7 8 9


void main (void)
	{
	ANSEL=0x00;
	TRISC=0b00000000;
	TRISB=0x00;
	TRISA=0b00000100;
	nRABPU=0;
	WPUA=0b00000100;
	PORTC=0X00;
	PORTB=0b00000000;

	OPTION_REG=0x07;
	TMR0=0xd8;
	IOCA=0x04;//ENABLE RA2 INTERRUPT
	RABIE=1;// PROTA/PORTB change interrupt enable
	//PEIE=1;
	T0IE=0;// Timer0 overflow interrupt enable
	GIE=1; // Global interrupt enable



	while(1)
		{

		}
	}
	
static void interrupt isr(void)
	{
	if(RABIF)
		{
		if (x==1)
			{
			x=0;
			}
		else
			{
			x=1;
			TMR0=0;
			T0IE=0;
			T0IF = 0;
			RABIF = 0;

			} 

		if (x==0)
			{
			T0IE=1;
			TMR0=0xd0;

			PORTB=0b11100000;
			PORTC=display[d];
			__delay_ms(1);
			PORTB=0b11010000;
			PORTC=display[c];
			__delay_ms(1);
			PORTB=0b10110000;
			PORTC=display[b];
			__delay_ms(1);
			PORTB=0b01110000;
			PORTC=display[a];
			__delay_ms(1);
			d++;
			if(d>9)
				{ 
				d=0;
				if (c<10)
				c++;
				else c=0;
				}
			if(c>9)
				{
				c=0;
				if(b<10)
				b++;
				else b=0;
				}
			if(b>9)
				{
				b=0;
				if(a<5)
				a++;
				else a=0;
			}

		TMR0=0xd8;
		T0IF = 0;
		RABIF = 0;
		}
	}
}

It's probably not a good idea to use delays in an interrupt routine... Especially seeing as the TMR0 interrupt is being enabled at the same place..
 
dear sir, tmr0 is to set the prescalar for the timing to millisecond as 216 is d8 in hex. ( as wat i know , the timer need to be activated and being run inside the interupt loop. there is no problem in the timing but the interupt seems like not working for the second external interupt. the stop watch can start counting by using infrared sensor but cannot stop counting. This is the main problem i am facing. Or maybe you have a batter solution on this? Thanks
 
Last edited:
oh i see i am new over here~ sorry bout the messy code~

No worries :) We were all new once. Thought I'd show you one of the many great features this site has to offer ;):)
 
dear sir~ or maybe you can show me a proper code for making a normal stopwatch with a start and stop function from the external interrupt so that i can learn from there. Thanks~
 
Personally I would use a flip flop on the T1G pin once to bring the timer gate on then once again to switch it off...

What Pic are you using?

Edit... Scratch that... it was in the title...
 
Last edited:
pic16f690 . this is an embeded project whch only required to use a microchip pic 16f690 to program a stopwatch with c language. do u have any idea on this?
 
Don't use RABIE at all.... There is an interrupt on RA2 anyway

Also leave the TMR0 going all the time WITH the timer enabled.. That way you can always see the output. Only count after the on command then when you stop the watch you'll be able to see the final count...

I modified the code for you..

Code:
#include <pic.h>
#define _XTAL_FREQ 4000000L
//__CONFIG (FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & BOREN_OFF);
unsigned int n,g,p,q,r,s,t,a,b,c,d,start,x,counter=0;
unsigned char display []={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0 1 2 3 4 5 6 7 8 9
 
 
void main (void)
	{
	ANSEL=0x00;
	TRISC=0b00000000;
	TRISB=0x00;
	TRISA=0b00000100;
	nRABPU=0;
	WPUA=0b00000100;
	PORTC=0X00;
	PORTB=0b00000000;
 
	OPTION_REG=0x07;
	TMR0=0xd8;
	INTE=1;// INT interrupt enable
	T0IE=1;// Timer0 overflow interrupt enable
	GIE=1; // Global interrupt enable
 
 	while(1)
		{
 
		}
	}
 
static void interrupt isr(void)
	{
	if(INTF)
		{
		x =~x;
		if (x)
			{
			TMR0 = 0;
			INTF = 0;
			T0IF = 0;
			d = c = b = a = 0; // if you need to reset the count
			}
		else
			{
			TMR0 = 0;
			T0IF = 0;
			INTF = 0;
 			} 
		}
 	else
		{
		TMR0=0xd0;
 		PORTB=0b11100000;
		PORTC=display[d];
		__delay_ms(1);
		PORTB=0b11010000;
		PORTC=display[c];
		__delay_ms(1);
		PORTB=0b10110000;
		PORTC=display[b];
		__delay_ms(1);
		PORTB=0b01110000;
		PORTC=display[a];
		__delay_ms(1);
		if(x)
			{
			d++;
			if(d>9)
				{ 
				d=0;
				if (c<10)
				c++;
				else c=0;
				}
			if(c>9)
				{
				c=0;
				if(b<10)
				b++;
				else b=0;
				}
			if(b>9)
				{
				b=0;
				if(a<5)
				a++;
				else a=0;
			}
		}
 	TMR0=0xd8;
	T0IF = 0;
	}
}

I hope this works as expected
 
Last edited:
dear sir thanks for the edit and code it works well!! great!! but because i need to display my student id at the beginning of the code before the timer starts to count. so i cannot enable the timr0 at the starting of the header. need to activate it after the display of my student id. because if i activated the tmr0 earlier, would the timer be accurate as what i had calculated in the prescaler? or the below coding is fine ?
 
Last edited:
You are actually nearing the time in your code to use interrupts just to update the display..

You would be better off writing an LCD interrupt that just updates the LCD no matter what it reads..

Update the counter using the same interrupt ( you could use Timer 1 as the LCD re-fresh )

The YOU can easily control the LCD from outside the interrupt..


Sorry... The code you posted works... Just place the"GIE = 1" before the while() statement in main().
 
Last edited:
View attachment 65483 may i add the t0ie inside the interrupt loop as well? so that i will not need to activate the timer at the beginning. but seems like not working. and why there is a d0 at the tmr0? i tot it should be d8 at the top and bottom of the code. thanks sir
 
sorry sir i had already manage to solve it by my self. anyway thanks alots really thank you~ i had added you in my skype. keep in touch ya~
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top