Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] 3 timers interrupt use

Status
Not open for further replies.

Ranbeer Singh

Full Member level 5
Joined
Jul 30, 2015
Messages
259
Helped
22
Reputation
44
Reaction score
22
Trophy points
1,298
Location
Faridabad India
Activity points
3,266
Hello

I want to use 3 timers(timer0,1,3) of Pic18f4520. In my codes when i enable any one timer ISR function works fine. But when i enable any two/three timers in main function ISR and other codes misbehave.

Codes

Code:
#include <p18f4520.h>

// High priority interrupt vector
void chk_isr(void);
void InitTimer0(void);
void InitTimer1(void);
void InitTimer3(void);
void TMR0_Func(void);
void TMR1_Func(void);
void TMR3_Func(void);
#pragma interrupt chk_isr
void chk_isr(void)
{
	if(PIR1bits.TMR1IF) TMR1_Func();
	if(PIR2bits.TMR3IF) TMR3_Func();
	if(INTCONbits.TMR0IF) TMR0_Func();
}

#pragma code isr = 0x08 // store the below code at address 0x08
void isr(void)
{
	_asm
		GOTO chk_isr
	_endasm
}
#pragma code


void main ()
{
	TRISA=0xCF;
	PORTA=0x00;
	TRISB=0x07;
	PORTB=0x00;
	TRISC=0x00;
	PORTC=0x00;
	TRISD=0x00;
	PORTD=0x00;
	TRISE=0x00;
	PORTE=0x00;


	PIE1bits.TMR1IE=1;
	PIR1bits.TMR1IF=0;
	PIE2bits.TMR3IE=1;
	PIR2bits.TMR3IF=0;
	INTCONbits.TMR0IE=1;
	INTCONbits.TMR0IF=0;
	INTCONbits.PEIE=1;
	INTCONbits.GIE=1;

	InitTimer0();
	InitTimer1();
	InitTimer3();
	while(1){}

}

//************************************************************************************

void InitTimer0(){
	T0CON = 0x84;
	INTCONbits.TMR0IF = 0;
  	TMR0H = 0xFF;		//
  	TMR0L = 0x5E;
  	T0CONbits.TMR0ON = 1;
} 
void InitTimer1(){
	T1CON = 0x19;
	PIR1bits.TMR1IF = 0;
    	TMR1H = 0x3C;		
    
	TMR1L = 0xE5;
	T1CONbits.TMR1ON = 1;
}
void InitTimer3(){
	T3CON = 0x19;
	PIR2bits.TMR3IF = 0;
    	TMR3H = 0x00;		
    
	TMR3L = 0xE5;
}

void TMR0_Func()
{
	// Functiin codes
}

void TMR1_Func()
{
	// Functiin codes
}

void TMR3_Func()
{
	// Functiin codes
}
 

You might consider initializing the timers before enabling interrupts so you don't risk spurious interrupts but otherwise it looks OK.

Your TMRx_Func() routines must clear the interrupt flags as soon as possible but you do not show code for those routines. Personally, I would clear the interrupt in the "chk_isr" routine and set a flag to tell "main()" the interrupt service is required. My method minimises the time spent checking for the interrupt source and does the servicing without blocking subsequent interrupts.

You didn't say which compiler you are using but check the line "#pragma interrupt chk_isr" doesn't conflict with "#pragma code isr = 0x08". I could be completely wrong but you could be making it confuse "chk_isr" with "isr".

Brian.
 
I am clearing all timers interrupt in TMRx_Func(). I am using C18 compiler.

- - - Updated - - -

Code:
void TMR0_Func(){
	unsigned char UpData,DownData;
	unsigned int value;

	INTCONbits.TMR0IF = 0;          // Clear interrupt flag

	value=(M1_ADC * 9)+55000;	  // Delay value accroding ADC input;
	DownData=value;
	UpData=(value-DownData)/256;				
	M3_EN=1;
	Index1++;
	if(Index1==4) Index1 = 0;
}
 

What are you trying to achieve with 3 Timers ? Mention in detail. Maybe there is a solution where you can use only One Timer or I can provide a sample code to run three timers.
 

when i enable any one timer ISR function works fine. But when i enable any two/three timers in main function ISR and other codes misbehave

Not clear what exactly do you mean by "misbehaving", anyway the content itself of each interrupt routine may affect the overall working of the code. I'm assuming you suppressed it just for clarity purpose.

Code:
void TMRx_Func()
{
	// Function codes
}
 

It is quite possible for a IF flag to be set on a timer that does not have the IE bit set. As there is only a single ISR, you really need to follow the convention of testing for BOTH the IE and IF flags as in
Code:
if( PIE1bits.TMR1IE && PIR1bits.TMR1IF) xxxx
This will stop false calls to your various functions.
Also, inside any function that is called from the ISR, if you update a global variable then it should be declared volatile.
Susan
 
What are you trying to achieve with 3 Timers ? Mention in detail. Maybe there is a solution where you can use only One Timer or I can provide a sample code to run three timers.

We have talked on this topic. I want to run my three numbers of motors.


I worked on it tomorrow and i have run successfully my all timers at a time. My two motors(Timer0, Timer3) are working fine. I found mistake under TMRx_Func() function. Second... i defined timer Init function before declaration of interrupt bits as Betwixt's instruction.
At this time i am getting a problem when i change ADC input value PORTC upper & lower nibbles work same. I mean M1_ADC is for PORTC lower nibble( work with Timer0 interrupt). When i change M1_ADC value PORTC upper nibble output work same as lower nibble.

Code:
#include <p18f4520.h>

// High priority interrupt vector
void chk_isr(void);
void InitTimer0(void);
void InitTimer1(void);
void InitTimer3(void);
void Run_Motor1(void);
void Run_Motor2(void);
void Run_Motor3(void);
#pragma interrupt chk_isr
void chk_isr(void)
{
	if(INTCONbits.TMR0IF) Run_Motor1();
	if(PIR1bits.TMR1IF) Run_Motor2();
	if(PIR2bits.TMR3IF) Run_Motor3();
}

#pragma code My_HiPrio_Int = 0x08 // store the below code at address 0x08
void My_HiPrio_Int(void)
{
	_asm
		GOTO chk_isr
	_endasm
}
#pragma code
char FullStepForward1 [4]={0x03, 0x09, 0x0C, 0x06};
char FullStepBackward1[4]={0x06, 0x0C, 0x09, 0x03};
char FullStepForward2 [4]={0x03, 0x09, 0x0C, 0x06};
char FullStepBackward2[4]={0x06, 0x0C, 0x09, 0x03};
char FullStepForward3 [4]={0x03, 0x09, 0x0C, 0x06};
char FullStepBackward3[4]={0x06, 0x0C, 0x09, 0x03};

char data1,data2,data3;
int M1_ADC,M2_ADC,M3_ADC;
char Index1=0;
char Index2=0;
char Index3=0;
char status1=0;
char status2=0;
char status3=0;
char M1Forward=1;
char M2Forward=1;
char M3Forward=1;

void main ()
{
	TRISA=0xCF;
	PORTA=0x00;
	TRISB=0x07;
	PORTB=0x00;
	TRISC=0x00;
	PORTC=0x00;
	TRISD=0x00;
	PORTD=0x00;
	TRISE=0x00;
	PORTE=0x00;

	ADCON0=0x01;
	ADCON1=0x0B;
	ADCON2=0xAE;

	InitTimer0();	
	InitTimer1();
	InitTimer3();
	PIE1bits.TMR1IE=1;
	PIR1bits.TMR1IF=0;
	PIE2bits.TMR3IE=1;
	PIR2bits.TMR3IF=0;
	INTCONbits.TMR0IE=1;
	INTCONbits.TMR0IF=0;
	T0CONbits.TMR0ON = 1;	// Timer0 on
	T1CONbits.TMR1ON = 1;	// Timer1 on
	T3CONbits.TMR3ON = 1;	// Timer3 on
	INTCONbits.PEIE=1;
	INTCONbits.GIE=1;
	   
	M3_ADC=512;
while(1)
	{

		ADC_ALL();

	}
}

void ADC_ALL()
{


	ADCON0bits.ADON=1;
	ADCON0=0x09;       // Use AN2 for motor 1 speed control
	ADCON0bits.DONE=1;
	while(ADCON0bits.GO==1);
	M1_ADC=ADRESL+(ADRESH*256);
	ADCON0bits.ADON=0;
	if(M1_ADC>20 && status1==0){
		T0CONbits.TMR0ON = 1;
		status1=1;}
	else if (M1_ADC<20) {
		T0CONbits.TMR0ON = 0;
		status1=0;}

	Time_5ms();
	ADCON0bits.ADON=1;
	ADCON0=0x0D;       // Use AN3 for motor 2 speed control
	ADCON0bits.DONE=1;
	while(ADCON0bits.GO==1);
	M2_ADC=ADRESL+(ADRESH*256);
	ADCON0bits.ADON=0;
	if(M2_ADC>20 && status2==0){
		T1CONbits.TMR1ON = 1;
		status2=1;}
	else if (M2_ADC<20) {
		T1CONbits.TMR1ON = 0;
		status2=0;}



}
void Time_5ms()
{
	int Delay;
	for(Delay=0;Delay<10000;Delay++);

}




//************************************************************************************

void InitTimer0(){
	T0CON = 0x04;
  	TMR0H = 0xCC;		
  	TMR0L = 0x5E;
} 
void InitTimer1(){
	T1CON = 0xB4;
    	TMR1H = 0x2A;		
    
	TMR1L = 0xE5;
}
void InitTimer3(){
	T3CON = 0xB0;
    	TMR3H = 0x0A;		
    
	TMR3L = 0xE5;
}


void Run_Motor1()
{
	unsigned char UpData,DownData;
	unsigned int value;

	INTCONbits.TMR0IF = 0;			// Motor1 control with Timer0

	value=(M1_ADC * 9)+55000;		// Delay value accroding ADC input;
	DownData=value;
	UpData=(value-DownData)/256;
		
    
	TMR0H = UpData;
	TMR0L = DownData;
	if(M1Forward)LATC=(PORTC & 0xF0) | FullStepForward1[Index1];
	else {LATC=(PORTC & 0xF0) | FullStepBackward1[Index1];}
	Index1++;
	if(Index1==4) Index1 = 0;
}

void Run_Motor2(){
	unsigned char UpData,DownData;
	unsigned int value;

	PIR1bits.TMR1IF = 0;			// Motor2 control with Timer1

	value=(M2_ADC * 26)+35000;	 	 // Delay value accroding ADC input;
	DownData=value;
	UpData=(value-DownData)/256;
		
    
	TMR1H = UpData;
	TMR1L = DownData;
	if(M2Forward)LATC=(PORTC & 0x0F) | (FullStepForward2[Index2]<<4);
	else {LATC=(PORTC & 0x0F) | (FullStepBackward2[Index2]<<4);}
	Index2++;
	if(Index2==4) Index2 = 0;

}

void Run_Motor3(){
	unsigned char UpData,DownData;
	unsigned int value;

	PIR2bits.TMR3IF = 0;			// Motor3 control with Timer3

	value=(M3_ADC * 26)+35000;	  	// Delay value accroding user input value by use of keyboard
	DownData=value;
	UpData=(value-DownData)/256;	
	
    
	TMR3H = UpData;
	TMR3L = DownData;
	M3_EN=1;
	if(M3Forward)LATB=(PORTB & 0x0F) | (FullStepForward3[Index3]<<4);
	else {LATB=(PORTB & 0x0F) | (FullStepBackward3[Index3]<<4);}
	Index3++;
	if(Index3==4) Index3 = 0;

}
 
//*******************************************************************************
 

I had given you the code which uses 1 Timer for all the three steppers. Why did you change it to three timers ?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top