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.

Help with interrupt.

Status
Not open for further replies.

MrNobody

New Member
Hi.. I am using PIC18F4620 working with TCP/IP stack 4.18.
Below is the code which I hope is able to read the ADC value at frequency of 8000Hz.
The function VoIP_Main will be called from within the Main function's while loop and it will monitor boolReadADC value. boolReadADC is a flag to indicate that TIMER2 interrupt has overflow which is every 125us and if overflow occur, it will call the ReadADC function.
I have a counter cnt8000 to count how many times the interrupt occurs and it will count up to 7999 counts in 1 second and then it will reset to 0.
That is the background information of the code below.

Now, the problem is this. Instead of the ReadADC function being called everytime the interrupt occur (ie, one time when cnt8000 = 1, another time when cnt8000 = 2 etc), the first time the ReadADC function is called is when cnt8000 = 208 and then next time the function is called again is when cnt8000 = 708.. This clearly is not sampling the ADC at 8000Hz.
I couldn't figure out what went wrong.. Please advice.. thanks..


Code:
// ISR VECTOR
#if defined(__18CXX)
	#if defined(HI_TECH_C)
	void interrupt low_priority LowISR(void)
	#else
	#pragma interruptlow LowISR
	void LowISR(void)
	#endif
	{
	    TickUpdate();
	    Timer2Interrupt();		// For DoIP purposes
	}
	

/////////////////////////////////////
// ISR FUNCTION
/////////////////////////////////////
void Timer2Interrupt()
{
    if (PIR1bits.TMR2IF == 1)
    {
	PIR1bits.TMR2IF=0;
		
	boolReadADC = 1;
        
        if (cnt8000 < 8000)
	        cnt8000++;
	else 
		cnt8000 = 0;
    }
}


void VoIP_Main()               // is inside the Main funtion's while loop
{
	if (boolReadADC==1)
	{
		boolReadADC = 0;
		ReadADC();
	}
}


void ReadADC()
{
	// Code to be added later.
}
 
My guess would be that the ReadADC function is taking a lot longer than the interrupt period. For this to happen your ReadADC routine would have to be very long or your Timer2 interval very short. As you haven't included either of these routines it's rather difficult to say.

Mike.
 
Thanks Mike for the reply..
Below is the code I use.. Hope it is sufficient..
Oh.. btw, after testing with ICD2 and putting a breakpoint in the VoIP_Main() function so that it breaks before the ReadADC function is called, I found out that the problem already arises even before the ADC value is read..
I just don't know what happened..
Anyway, thanks for ur help..


Code:
// ISR VECTOR
#if defined(__18CXX)
	#if defined(HI_TECH_C)
	void interrupt low_priority LowISR(void)
	#else
	#pragma interruptlow LowISR
	void LowISR(void)
	#endif
	{
	    TickUpdate();
	    Timer2Interrupt();		// For DoIP purposes
	}
	

/////////////////////////////////////
// ISR FUNCTION
/////////////////////////////////////
void Timer2Interrupt()
{
    if (PIR1bits.TMR2IF == 1)
    {
	PIR1bits.TMR2IF=0;
		
	boolReadADC = 1;
        
        if (cnt8000 < 8000)
	        cnt8000++;
	else 
		cnt8000 = 0;
    }
}


void InitTimer2()
{
	T2CON = 0b0100100;                // Postscaler = 1:10, Prescaler = 1:1
	PR2 = 124;				// 125 counts including 0
	T2CONbits.TMR2ON = 1;
}	

void InitADC()
{
	ADCON0 = 0b00000001;
	ADCON1 = 0b00001110;
	ADCON2 = 0b00010010;
	DDRAbits.RA0 = 1;
}


void VoIP_Main()               // is inside the Main funtion's while loop
{
	if (boolReadADC==1)
	{
		boolReadADC = 0;
		ReadADC();
	}
}


void ReadADC()
{
	ADCReadings[cnt160] = ADRESH;
	ConvertADC(); // 			Start conversion
	
	if (cnt160 < 159)
		cnt160++;
	else 
		cnt160 = 0;
}
 
Your postscaller appears to be set to 5 as you only have 7 bits in your binary value. You left out your ConvertADC routine so again it is hard to comment.

Mike.
 
Hi Mike,
Umm.. the Convert function is th e same as the one in the library..
Regarding the prescaler, i might have accidentally deleted it.. Anyway, have put it back already..
By the way, i have commented the code inside the ReadADC function so that when the function is called, it does nothing so that it won't take up much time. I have tested it and seems that the result is the same even with the code in ReadADC function commented.


Code:
// ISR VECTOR
#if defined(__18CXX)
	#if defined(HI_TECH_C)
	void interrupt low_priority LowISR(void)
	#else
	#pragma interruptlow LowISR
	void LowISR(void)
	#endif
	{
	    TickUpdate();
	    Timer2Interrupt();		// For DoIP purposes
	}
	

/////////////////////////////////////
// ISR FUNCTION
/////////////////////////////////////
void Timer2Interrupt()
{
    if (PIR1bits.TMR2IF == 1)
    {
	PIR1bits.TMR2IF=0;
		
	boolReadADC = 1;
        
        if (cnt8000 < 8000)
	        cnt8000++;
	else 
		cnt8000 = 0;
    }
}


void InitTimer2()
{
	T2CON = 0b01001000;                // Postscaler = 1:10, Prescaler = 1:1
	PR2 = 124;				// 125 counts including 0
	T2CONbits.TMR2ON = 1;
}	

void InitADC()
{
	ADCON0 = 0b00000001;
	ADCON1 = 0b00001110;
	ADCON2 = 0b00010010;
	DDRAbits.RA0 = 1;
}


void VoIP_Main()               // is inside the Main funtion's while loop
{
	if (boolReadADC==1)
	{
		boolReadADC = 0;
		ReadADC();
	}
}


void ReadADC()
{
/*
	ADCReadings[cnt160] = ADRESH;
	ConvertADC(); // 			Start conversion
	
	if (cnt160 < 159)
		cnt160++;
	else 
		cnt160 = 0;
*/
}
 
Can you post a compilable version that exhibits the problem? The problem could be something as simple as the WDT causing a reset as all your variables appear to be global.

Mike.
 
Sure..
Below is the link to the actual code..
Look inside "TCPIP Demo App" folder and open "TCPIP Demo App-C18.mcw".
Inside MainDemo.c, i put 2 breakpoints before i saved the workspace.. the first breakpoint is at line 283 (inside Timer2Interrupt function) and second one at line 258 (inside DoIP_Main function).
The code should compile straight away..

Hope I didn't miss anything behind..
Thanks..

Download link: **broken link removed**
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top