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.

PIC12F675 Timer0 interrupts

Status
Not open for further replies.
Hello everyone. Man it's been forever since I've posted here

Anywhoo here's the situation. for a class project dealing with a different micro-controller, the HCS12, we were to build a spectrum analyzer. Succeeded, and thankfully passed.

So, for fun, I figured why not try to do the same thing using a PIC. In this case, the PIC12F675. I've gotten the setup to "work", but not quite to the state I'd like. I'd like to refresh its display every so often instead of as fast as possible, so I figured a timer interrupt would be perfect.


Here's the situation. I'm having a bit of trouble tripping an interrupt from the timer0 module. I think I've got all of my initialization registers setup correctly, but I could be wrong. In particular the OPTION and INTCON registers.

Code:
	/* setup stuff */
	COUNT	=	0x00;	//clear timer module counter
	OVERFLOW = 0;		//clear the flag
	TRISIO	=	0x09;	// GP3 always input, GP0 is analog input
	GPIO	=	0x00;	//	clear all outputs
	STROBE  = 	1;		// when not in use, should remain high
	SELECT	=	1;		// same case
	
	WPU		=	0x00;	// clear all weak pullups


	//A/D MODULE
	ADCON0	= 0x01; // AN0 selected, set ADON to turn on module, set GO/DONE to start an A/D conversion
	ANSEL	= 0x61; // AN0 selected as analog input, all other ports are digital
	

	OPTION_REG	=	0b10000101;	//set timerpre-scaler to 64/prescaler assigned to timer module 
		//	nGPPU = 1;		// internal pullups disabled
		//	INTEDG = 0;		// falling edge trigger the interrupt__don't care
		//	T0CS = 0;		// timer transistion on cycle clock
		//	T0SE = 0		// increment on low to high transistion of GP2
		//	PSA = 0			// prescaler is set to the TIMER0 module
		//  ps>>101, or 64
	INTCON	= 0b11100000;
		//GIE = 1 	//enable global interrupts
		//PEIE = 1 	//enable peripheral interrupts
		//T0IE = 1	//enable TMR0 interrupts
		//INTE = 0	//disables GP2 interrupt
		//GPIE = 0	//disables GPIO port change interrupt
		//T0IF = 0	//timer0 overflow flag
		//INTF = 0	//GP2 interrupt flag
		//GPIF = 0	//ext pin change interrupt
	T1CON	=	0x00; //clear the friggin unused timer
	PIE1	=	0x00;	//nothing here is needed


Having broken down to the problem as much as I can, I've got a simple tidbit of code in the actual interrupt routine:

Code:
void interrupt ISR(){

	if(T0IF){
	//GPIO ^= 0x02 ;//pulse strobe
		if (STROBE == 1){
			STROBE = 0;
		}
		else{
			STROBE = 1;
		}
		
		if(COUNT == 2){//prescaler =64, w/ 4mhz clock, this will reset overflow around 30Hz
		OVERFLOW = 1;
	}
	T0IF = 0;//clear the overflow bit
	TMR0 = 0;
	//}
return;
}


My main routine after setup simply sits in a never ending for loop periodically kicking the dog, heheh.

The intent with this test is to try to pull a ~60Hz square wave on the scope from the appropriate pin (strobe is set to GPIO1), eventually changing my pre-scaler and counter values to adjust a display refresh rate. However I can't seem to get anything out of it from the ISR, as my scope signal lays dead at the logical high STROBE is left at initially.

Any thoughts, comments, suggestions? Possible conflicts you've dealt with in the past? I'm fairly new to PIC's with C, especially using any of the extra modules packed in the MCU. A slap in the face stupid newbie mistake is probably what you'll find (well, new to C with these little guys, just decided to make the switch from .asm) Thanks in advance for your time fellas!
 
Last edited:
Try taking the 'return' command out of the ISR function. That 'might' be exiting the ISR without re-enabling interrupts.

What C compiler are you using?
 
"HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.82"

I got 'er to run! there were multiple things I changed, including the return, so I'm not sure what all fixed it in sum.

Disabled the comparator (almost forgot about this one)
Cleared TRM0 before starting anything
no-more return in isr
disabled watchdog timer
new name for isr (found an example using lowercase, but I'm having a hard time believing that's what did it)

anywhoo, as an example for those browsing, the below code works
Code:
#include	<htc.h>

	__CONFIG(CP_OFF & CPD_OFF & BOREN_OFF & MCLRE_ON  & PWRTE_ON & WDTE_OFF & FOSC_INTRCIO);


#define	CLK		4	//GP4	//SPI clock	
#define	MOSI	        2	//GP2	//Master_out_slave_in PIC is master
#define	Z		2	//status z flag
#define	STROBE	GP1	//graphic equalizer "poll" frequency band data is available when low
#define	SELECT	GP5	//chip select bit 
static unsigned char	        TIMER	;///timer for delay unit
static unsigned char 	COUNT	;//timer module for timer interrupt routine
static unsigned char 	OVERFLOW;
static unsigned int		i;
static unsigned int		j;



////////////////////////////////////////////////////////////////////////////////////////////////


void interrupt isr(){

	//if(T0IF){
	//GPIO ^= 0x02 ;//pulse strobe
		if (STROBE == 1){
			STROBE = 0;
		}
		else{
			STROBE = 1;
		}
		
		if(COUNT == 2){//prescaler =64, w/ 4mhz clock, this will reset overflow around 30Hz
		OVERFLOW = 1;
	}
	T0IF = 0;//clear the overflow bit
	TMR0 = 0;
	//}
//return;
}


int	main(void){
	/* setup stuff */
	COUNT	=	0x00;	// clear timer module counter
	OVERFLOW = 0;		// clear the flag
	//I/O initialization
	GPIO	=	0x00;	// clear all outputs
	CMCON	=	0x07;	// disable the comparator
	TRISIO	=	0x09;	// GP3 always input, GP0 is analog input
	WPU		=	0x00;	// clear all weak pullups

	STROBE  = 	1;		// when not in use, should remain high
	SELECT	=	1;		//	



	//A/D MODULE
	ADCON0	= 0x01; // AN0 selected, set ADON to turn on module, set GO/DONE to start an A/D conversion
	ANSEL	= 0x61; // AN0 selected as analog input, all other ports are digital
	
	TMR0 = 0;
	OPTION_REG	=	0b10000101;	//set timerpre-scaler to 64/prescaler assigned to timer module 
		//	nGPPU = 1;		// internal pullups disabled
		//	INTEDG = 0;		// falling edge trigger the interrupt__don't care
		//	T0CS = 0;		// timer transistion on cycle clock
		//	T0SE = 0		// increment on low to high transistion of GP2
		//	PSA = 0			// prescaler is set to the TIMER0 module
		//  ps>>101, or 64
	INTCON	= 0b11100000;
		//GIE = 1 	//enable global interrupts
		//PEIE = 1 	//enable peripheral interrupts
		//T0IE = 1	//enable TMR0 interrupts
		//INTE = 0	//disables GP2 interrupt
		//GPIE = 0	//disables GPIO port change interrupt
		//T0IF = 0	//timer0 overflow flag
		//INTF = 0	//GP2 interrupt flag
		//GPIF = 0	//ext pin change interrupt
	T1CON	=	0x00; //clear the friggin unused timer
	PIE1	=	0x00;	//nothing here is needed 




	for(;;){
		if (OVERFLOW==1){
			OVERFLOW = 0;	//clear the overflow bit   
		}
		//CLRWDT();	// Idly kick the dog
	}
}

Thanks geko for the suggestion!
 
Last edited:
well, sorta a success. I've got the timer running with my test, but if I try refreshing within the isr, I get a blank screen.


I'm bit-banging an SPI routine using in-line assembly. Perhaps the isr is "interrupting" something it shouldn't be.
 
I noticed you enable the peripheral interrupt too, I dont think you need to do that to enable interrupts for timer0, you just need to enable the timer0 interrupt enable and global enable.
 
Status
Not open for further replies.

Latest threads

Back
Top