Problem with Pic18f97j60

Status
Not open for further replies.

Mhadhu

Junior Member level 2
Joined
Jan 3, 2013
Messages
21
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,461
My code is working properly except in the transmission of green code. I have placed the authorised ID tag code in ucCharBuff[0] to ucCharBuff[9] and green code to be transmitted to rfid for 4 cycles in ucCharBuff[10] to ucCharBuff[19]. Whenever authorised card is exposed the green code has to be transmitted and the door has to be opened. Everything is working fine except the green code is not able to be transmitted.

Code:
Code:
#include <p18f97j60.h>
#include<delays.h>
#include<usart.h>
#pragma config XINST=OFF
#pragma config WDT=OFF, FOSC2=ON, FOSC=HSPLL, ETHLED=OFF
#pragma config WDTPS=256
#pragma interrupt interrupthandler


void interrupthandler();
void function();
void data();
unsigned char a[10];
unsigned char ucCharBuff[20];
unsigned char ucaBuffer[10];
int i = 0;
int j = 0;
int b;
int k = 0;
void delay();

void main(void) {
    OSCTUNE = 0x40;
    TRISG = 0;
    PORTG = 0X40;
    TRISC = 0X04;
    TRISJ = 0;
    PORTJ = 0X00;
    Open1USART(
            USART_TX_INT_ON & //Enabling USART
            USART_RX_INT_ON &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_CONT_RX &
            USART_BRGH_LOW,
            67);
    RCONbits.IPEN = 0;
    INTCONbits.GIE = 1; //Enabling interrupts
    INTCONbits.PEIE = 1;
    PIE1bits.RC1IE = 1;
    ADCON1 = 0X0F; // dISABLING ANALOG INPUTS
    CMCON = 0X07; //disabling comparator
    Delay100TCYx(100000);
    ucCharBuff[0] = 0x34; // rfid tag code is stored in ucCharBuff
    ucCharBuff[1] = 0x32;
    ucCharBuff[2] = 0x30;
    ucCharBuff[3] = 0x30;
    ucCharBuff[4] = 0x41;
    ucCharBuff[5] = 0x34;
    ucCharBuff[6] = 0x33;
    ucCharBuff[7] = 0x35;
    ucCharBuff[8] = 0x42;
    ucCharBuff[9] = 0x31;
    ucCharBuff[10] = 0x02; //green code
    ucCharBuff[11] = 0x90;
    ucCharBuff[12] = 0x00;
    ucCharBuff[13] = 0x25;
    ucCharBuff[14] = 0x04;
    ucCharBuff[15] = 0x00;
    ucCharBuff[16] = 0x02;
    ucCharBuff[17] = 0x01;
    ucCharBuff[18] = 0x04;
    ucCharBuff[19] = 0xb6;
    while (1) {
      
    }
    Close1USART();
}
#pragma code interruptvectorhigh=0x08

void interruptvector(void) //interrupt vector
{
    _asm
    goto interrupthandler
            _endasm

}
#pragma code             //interrupt routine
#pragma interrupt interrupthandler

void interrupthandler() {
    if (PIR1bits.RC1IF == 1) {
        PIR1bits.RC1IF = 0;
        for (i = 0; i < 10; i++) {
            a[i] = RCREG1;
        }
        for (j = 0; j < 9; j++) {
            if (a[j] == ucCharBuff[j]) {
              
                function();
            }
        }
    }
}

void function() {
   for (i = 10; i < 19; i++) {
       PORTJ=0X01;
            while (!(TXSTA1bits.TRMT));
            PORTJ=0X02;

            TXREG1 = ucCharBuff[i];
                 }
     for (i = 0; i < 10; i++) {
        delay();
    }
    Delay100TCYx(1000);
    PORTG = 0X00;
    for (i = 0; i < 20; i++) {
        delay();
    }
    PORTG = 0X40;
    WDTCONbits.SWDTEN = 1;
    for (j = 0; j < 100; j++) {
        Delay10KTCYx(1000);
    }
    PIE1bits.RC1IE = 0;
    WDTCONbits.SWDTEN = 0;
}

void delay() {
    Delay10KTCYx(1000);
}
 
Last edited by a moderator:

I tried it. But thats not working. And i have few more doubts too.
1. Is including number of operations to be performed within the routine a good way of writing program.
2. When i took some of the tasks that were not needed to be include within the interrupt outside and placed in main() function those function did not seem to work. I think the interrupt routine is not returning back to main. Also the interrupt routine is executing only once. Can anyone plz help me in explaining what exactly is wrong about my coding.
Here is my interrupt routine.
Code:
Code:
#pragma code high_vector=0x08
void interrupt_at_high_vector(void) //interrupt vector
{
    _asm
    goto high_isr
            _endasm

}
#pragma code             //interrupt routine
#pragma interrupt high_isr

void high_isr()
{
    INTCONbits.GIE = 0; //Disabling interrupts
   
   
    if (PIR1bits.RC1IF == 1)
    {
         for (i = 0; i < 10; i++)
        {
            a[i] = RCREG1;
        }
    }
    PIE1bits.RC1IE = 1;
    PIR1bits.RC1IF = 0;
    
}
 
Last edited by a moderator:

YEs UART is working properly. I have checked it already. Am not able to find out where am making mistake.

- - - Updated - - -

Now am able to perform the interrupt function any number of times required. But interrupt routine is not returning to main function. What should i include in my coding inorder to return interrupt to main () function
 

Which Compiler are you using. Can you zip and post your project files so that I can check?

Edit: I think you are using C18 Compiler. Right?

What is the baudrate and Fosc you are using?
 
Last edited:

Yes am using C18. Baud Rate is 9600. And FOSC2=ON, FOSC=HSPLL. Returning to main problem is solved now by using INTCON as a whole register instead of INTCONbits.GIE and INTCONbits.PEIE. I have used watchdog timers so that my code would work continuously without hanging. But my staff has said me not to use watchdog timer as it would reset the entire process. So is there any alternative for watchdog timer. Here is my edited code.

Code:
Code:
#include<p18f97j60.h>
#include<usart.h>
#include<delays.h>
#pragma config XINST=OFF
#pragma config WDT=OFF, FOSC2=ON, FOSC=HSPLL, ETHLED=OFF, STVR = ON
#pragma interrupt high_isr
#pragma config WDTPS=128

unsigned int i;
volatile unsigned char a[10];
volatile unsigned int m;
unsigned char ucCharBuff[10];


void function();

void high_isr(void);
#pragma code high_vector=0x08

void interrupt_at_high_vector(void) //interrupt vector
{
    _asm
    goto high_isr
            _endasm
}
#pragma code             //interrupt routine
#pragma interrupt high_isr

void high_isr() {
    if (PIR1bits.RC1IF == 1) {
        PORTJ = 0X01;
       [B] INTCONbits.PEIE = 0;[/B]
        for (i = 0; i < 10; i++) {
            a[i] = RCREG1;
        }
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        PIR1bits.RC1IF = 0;
        PORTJ = 0X00;
        m = 1;
    }
}

void main()
{
    OSCTUNE = 0X40;
    TRISJ = 0;
    PORTJ = 0X00;
    TRISG = 0;
    PORTG = 0X00;
    RCONbits.IPEN = 0;
    PIE1bits.RCIE = 1;
  [B]  INTCON = 0XC0;[/B]
    Open1USART(
            USART_TX_INT_ON & //Enabling USART
            USART_RX_INT_ON &
            USART_ASYNCH_MODE &
            USART_EIGHT_BIT &
            USART_CONT_RX &
            USART_BRGH_LOW,
            67);
    ucCharBuff[0] = 0x34; // rfid tag code is stored in ucCharBuff
    ucCharBuff[1] = 0x32;
    ucCharBuff[2] = 0x30;
    ucCharBuff[3] = 0x30;
    ucCharBuff[4] = 0x41;
    ucCharBuff[5] = 0x34;
    ucCharBuff[6] = 0x33;
    ucCharBuff[7] = 0x35;
    ucCharBuff[8] = 0x42;
    ucCharBuff[9] = 0x31;
    while (1) {
        WDTCONbits.SWDTEN = 1;              //Watchdog timer.
        if (m == 1)
        {
            WDTCONbits.SWDTEN = 0;
            for (i = 0; i < 10; i++)
            {
                if (a[i] == ucCharBuff[i])
                    function();
            }
            m = 0;

        }
    }
    Close1USART();
}

void function()
{
    PORTG = 0X40;
    Delay10KTCYx(10000);
    Delay10KTCYx(10000);
    Delay10KTCYx(10000);
    Delay10KTCYx(10000);
    Delay10KTCYx(10000);
    PORTG = 0X00;
}
Can plz make corrections in my code so that it would work continuously without watchdog timers?
 
Last edited by a moderator:

No no. Actually am working with rfid tags and reader. the code works fully whenver the tag is exposed first. But it does not respond when second card is exposed. That is problem. If the pic board is reset using reset button then it works for one time. for each time , before exposing the card if i press the reset button in pic board then it works for that time. so to avoid this i included watchdog timer. it worked fine without pressing reset button for any number of cards exposed. but now my staff has asked me to remove WDT as it would reset the whole pic and entire process would start from first without any updation. This is what i meant in my previous post.

- - - Updated - - -

Also the reader allows access to all cards . I think i might have made some mistake in the card access part (if loop). Plz check that too.
 

In your earlier code the ucCharbuffer had 20 elements. Why did you change that? You were transmitting some data using uart, why have you removed that?
You did not mention the clock frequency you are using. You should not use delays inside interrupt routine. The interrupt routine has to be serviced as quickly as possible. If you use delays inside interrupt routine it will cause not to detect any interrupt while executing the delays inside interrupt routine. Try the below code
Code:
#include<p18f97j60.h>
#include<usart.h>
#include<delays.h>

#pragma config XINST=OFF
#pragma config WDT=OFF, FOSC2=ON, FOSC=HSPLL, ETHLED=OFF, STVR = ON
#pragma interrupt high_isr
#pragma config WDTPS=128

unsigned int i, counter = 0, counter2 = 0;
volatile unsigned char a[10];
volatile unsigned int m;
unsigned char ucCharBuff[10];


void function();


void high_isr(void);
#pragma code high_vector=0x08

void interrupt_at_high_vector(void) //interrupt vector
{
	_asm
		goto high_isr
	_endasm
}

#pragma code //interrupt routine
#pragma interrupt high_isr

void high_isr() {
	if (PIR1bits.RC1IF == 1) {
		PORTJ = 0X01;
		INTCONbits.PEIE = 0;
		//for (i = 0; i < 10; i++) {
			a[counter] = RCREG1;
			counter++;
		//}
		//Delay10KTCYx(10000);
		//Delay10KTCYx(10000);
		//Delay10KTCYx(10000);
		//Delay10KTCYx(10000);
		//Delay10KTCYx(10000);
		PIR1bits.RC1IF = 0;
		PORTJ = 0X00;
		//m = 1;
	}
}

void main()
{
	OSCTUNE = 0X40;
	TRISJ = 0;
	PORTJ = 0X00;
	TRISG = 0;
	PORTG = 0X00;
	RCONbits.IPEN = 0;
	PIE1bits.RCIE = 1;
	INTCON = 0XC0;

	Open1USART(USART_TX_INT_ON & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 67);

	ucCharBuff[0] = 0x34; // rfid tag code is stored in ucCharBuff
	ucCharBuff[1] = 0x32;
	ucCharBuff[2] = 0x30;
	ucCharBuff[3] = 0x30;
	ucCharBuff[4] = 0x41;
	ucCharBuff[5] = 0x34;
	ucCharBuff[6] = 0x33;
	ucCharBuff[7] = 0x35;
	ucCharBuff[8] = 0x42;
	ucCharBuff[9] = 0x31;

	while (1) {
		
			if(counter == 10) {
				for (i = 0; i < 10; i++)
				{
					if (a[i] == ucCharBuff[i])
						counter2++;
				}

				if(counter2 == 10) {
						function();
                                                counter2 = 0;
				}
				counter = 0;
			}
			
	}
	
}

void function()
{
	PORTG = 0X40;
	Delay10KTCYx(10000);
	Delay10KTCYx(10000);
	Delay10KTCYx(10000);
	Delay10KTCYx(10000);
	Delay10KTCYx(10000);
	PORTG = 0X00;
}

When I compile I am getting the errors "no prototype defined for functions Open1USART() and Close1USART()" Please zip and post all your mplab c18 project files. Are you simulating in Proteus?

See the below code
Code:
 for (i = 0; i < 10; i++) {
			a[i] = RCREG1;
			counter++;
		}
which is inside the interrupt routine. When an interrupt occurs then (let us say character a is read from usart) for 1=0 to 1 = 9 that is the a[0] to a[9] is given the value a. Why do you want to do that? Every time a character is read it should be stored in the array. So, if you rfid code is 0123456789 then your array a[] should be like below.
Code:
a[0] = '0'
a[1] = '1'
a[2] = '2'
a[3] = '3'
a[4] = '4'
a[5] = '5'
a[6] = '6'
a[7] = '7'
a[8] = '8'
a[9] = '9'
[code]

but according to your code it will be like 

 [code] 
a[0] = '9'
a[1] = '9'
a[2] = '9'
a[3] = '9'
a[4] = '9'
a[5] = '9'
a[6] = '9'
a[7] = '9'
a[8] = '9'
a[9] = '9'
[code]

because the last character of the assumed rfid is 9, so, all the elements of a[] is replaced with '9'. I want to ask why you are not using ReadUSART() and WriteUSART() functions?
 
Last edited:
Reactions: Mhadhu

    Mhadhu

    Points: 2
    Helpful Answer Positive Rating
Actually each card has a code equivalent to "34 32 30 30 41 34 36 41 31 39". Whenever card is exposed this data has to copied from RCREG to another variable for comparison. So am storing each value in the form of array. And regarding ReadUSART() and WriteUSART() functions am not familiar in how to use it properly. So i did not sue them. In earlier code the first 10 elements were the code of authorised card and the next 10 elements were for green blink data. Now i first want to check for authorised card alone. So i removed that green code. Am unable to check for that.. if() loop is not working properly. Help me for that please. And thanks for all ur replies

- - - Updated - - -

And regarding the delay i dont think that it would be an issue. because the delay() is just for half a second.
 

Yes. That is what I am saying. You want to store like this

a = RCREG;

a[0] = 34;
a[1] = 32;
a[2] = 30;
a[3] = 30;
a[4] = 41;
a[5] = 34;
a[6] = 36;
a[7] = 41;
a[8] = 31;
a[9] = 39;

That's what my code does.

You will then compare a with ucCharBuff and if all the elements match you do something.
 

This is how i have also coded. I dont understand where am going wrong and which one u r pointing to be wrong. Can u be a bit more specific please ?
 

Please see the for loop in the below code
Code:
void high_isr() {
    if (PIR1bits.RC1IF == 1) {
        PORTJ = 0X01;
        INTCONbits.PEIE = 0;
        for (i = 0; i < 10; i++) {
            a[i] = RCREG1;
        }
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        Delay10KTCYx(10000);
        PIR1bits.RC1IF = 0;
        PORTJ = 0X00;
        m = 1;
    }
}

Everytime an interrupt occurs the for loop executes 10 times and the same data is written to all the elements of a[]. a[0]...a[9] will have the same element every time an interrupt occurs. Let us assume your first data is 34 then 34 is assigned to a[0]...a[9] then if data received is 36 then a[0]...a[9] is assigned 36. So finally when the last data 39 is received all the elements of a[] will hold 39. a[0]...a[9] will be 39. So, if you compare a[0]...a[9] holding value 39 with ucCharBuff[0]...ucCharBuff[9] it will never match.
 

I tried ur code but that too did not help to sort out my issue. What i found was actually in a single interrupt "34 32 30 30 41 34 36 41 31 39" code will be obtained in RCREG1 and it has to be stored in another variable for comparison. But according to ur code it doesnt happen. for a single interrupt it just stores the 34 in a[0]. other places are left empty. i think this what happens.
 

Attachments

  • RELAY.zip
    4.1 KB · Views: 101
Last edited:

Are you telling that your method stores the values "34 32 30 30 41 34 36 41 31 39" into a[0]...a[9]?

For every character an interrupt occurs. So, after 10 interrupts you get all the 10 data in the a[] array. Then you can compare each element of a[] with ucCharBuff[].

What I see in you code contained in the RELAY.zip file is this
Code:
void high_isr()
{
    if (PIR1bits.RC1IF == 1)
    {
        PORTJ = 0X01;
        INTCONbits.PEIE = 0;
        for (i = 0; i < 10; i++)
        {
            ucaBuffer[i] = RCREG1;
            m = 1;
        }
        PIR1bits.RC1IF = 0;
        PORTJ = 0X00;
        m = 1;
    }
}

In the isr your are disabling INTCONbits.PEIE = 0; and PIR1bits.RC1IF = 0; but you are not reenabling using INTCONbits.PEIE = 1;
 
Last edited:
Reactions: Mhadhu

    Mhadhu

    Points: 2
    Helpful Answer Positive Rating
Yes. I got it what you were actually explaining. Now am able to properly receive the authorised card. I have made one more change too.
USART_TX_INT_OFF.
Initially it was ON. This also caused a major problem in my comparison. Thanks a lot for all ur help. An other problem rooted out. As you can see in my code i will have to send green blink code when a authorised card is scanned. This green blink works well for 2 times card swiping. After the second time rfid gets hanged. Have to work on this issue now.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…