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.

simple program for pic18f452 not working

Status
Not open for further replies.

wuid

New Member
hello

using mplab v8.30 with mplab c18 v3.10.

i am writing a simple program for my class assigment , i get a syntax error and don't know the reason for it.
the Code :

Code:
#include <p18f452.h>
#include <stdlib.h>
unsigned char a;
void main(void)

 {

   TRISB=0x3f; //PORT B AS INPUT 
   TRISC=0X0;  //PORT C AS OUTPUT
    INT0IE=1;  //ENABLE INT0
    INT0IF=0;   //reset INT0
    
    INTEDG0=1;  //INTERRUP ON RISING
    PEIE=0;     //ENABLE HIGH PERIORITY 
    GIE=1;     // ENABLE ALL INTERRUPT  
	while(1)
	{
        if ((a&0x1)==0)PORTCbits.RC0=1;
        else PORTCbits.RC0=0;


     	}
}
   void interrupt sw(void)
     {
       a=a+1;
      for(j1=0;j1<2000;j1++); //DELAY 
      INT0IF=0;// RESET INT0

      return;
       }

the error is in the line with the "void interrupt sw(void)"
any suggestions ?
 
Code:
void interrupt sw(void)
     {
       a=a+1;
      for(j1=0;j1<2000;j1++); //DELAY 
      INT0IF=0;// RESET INT0

      return;
       }

The problem is you can't declare interupt to have no value (void interrupt) and use the return; statement. Remove the return statement. If interrupt were to return something you would change the line to something like char interrupt. Don't do it though, you shouldn't call the ISR from your mainline code.


Edit: Looking more at the function of your code I have to say you really shouldn't just sit in an ISR as a delay, there are better methods. Any interrupts that are supposed to occur while it;s just sitting there will be ignored. If you're counting on a timed interrupt to give you specific delays the method you're attempting won't work. I could really go into a lot of boring detail here but it'd be better just to hear from you what you're trying to attempt and letting us guide you to good code.
 
Last edited:
o.k

i removed the return line , but still got the same "syntax error".

the program have to increment 'a' by 1 on evey press.

i didn't understand what it is ISR but if you meant the delay loop, it is the insterction that we(our class) were told to do from our guide.

this our first program with interrupts.

thx for the reply...
*attaching screen capture , i am suspecting maybe it is the compiler ?
 

Attachments

  • Untitled-1.jpg
    Untitled-1.jpg
    191.2 KB · Views: 326
Last edited:
Try this.

Code:
#include <p18f452.h>
#include <stdlib.h>

static volatile unsigned char a=0;
static volatile unsigned int j=0;

void interrupt sw(void)		// Interupt Routine - ISR
{
	a++;			// Increment a
	for(j=0;j<2000;j++);	// Delay
	INT0IF=0;		// Reset INT0
}

void main(void)
{
	GIE=1;     		// Enable Global Interrupts
	PEIE=0;    		// Enable Periphial Interrupts
	INTEDG0=1;		// Interupt On Rising Edge
	INT0IE=1;		// Enable INT0
	INT0IF=0;		// Reset INT0
	TRISB=0x3f;		// PORT B AS INPUT
	TRISC=0;		// PORT C AS OUTPUT

	while(1)
	{
		if (!(a & 1)){
			PORTCbits.RC0=1;
		}else{
			PORTCbits.RC0=0;
		}
     	}
}
 
Last edited:
The problem is you can't declare interupt to have no value (void interrupt) and use the return; statement. Remove the return statement.
Of course you can. 'return;' is not returning a value, it's just an early return from function statement.

If this page [https://www.xargs.com/pic/picc18-vs-c18.html] is valid, it looks like you're using the wrong syntax to declare your ISR. Use the c18 syntax, not the PICC-18 syntax.

Also, check out the MPLAB C18 manual, or even the quick reference [https://ww1.microchip.com/downloads/en/DeviceDoc/51225c.pdf] for how to declare an ISR.


In fact, try some of these: mplab c18 interrupt - Google Search
 
Of course you can. 'return;' is not returning a value, it's just an early return from function statement.

My mistake.

I've never used MPLAB, browsing through the manual a bit it seems to be quite different than what I'm used to.

In reading this is an example ISR - Interrupt Service Routine

Code:
#pragma code low_vector=0x18
void low_interrupt (void)
{
  _asm GOTO timer_isr _endasm
}
#pragma code
#pragma interruptlow timer_isr save=PROD
void
timer_isr (void)
{
  static unsigned char led_display = 0;
  INTCONbits.TMR0IF = 0;
  s_count = s_count % (NUMBER_OF_LEDS + 1);
  led_display = (1 << s_count++) - 1;
  PORTB = led_display;
}
 
managed to work things with your helps guys thanks ...

now i moved to more "complicated" problem

my goal is to turn led 1,2,3 in turn if INT0 is pressed it is changed to led 3,2,1(working)
if INT1 is pressed the delay between the light is changing.
the int1 command seems to be ignored not sure why...

Code:
#include <p18f452.h>
#include <stdlib.h>
#include <portb.h>
unsigned char a;
void delay(int);
void time(void);
void sw(void);
#pragma code high_vector=0x08
void high_vector(void)
{
if (INTCONbits.INT0IE==1)
_asm GOTO sw _endasm
if (INTCON3bits.INT1IE==1)
_asm GOTO time _endasm

}
#pragma code
////////////////////////////////////////
#pragma interrupt sw 
void sw(void)
     {
       unsigned int j1;
       a=a+1;
      for(j1=0;j1<2000;j1++); //DELAY 
      INTCONbits.INT0IF=0;// RESET INT0

      return;
       }
////////////////////////////////////////
#pragma interrupt time 
void time(void)
     {
       unsigned int j1;
       a=a+1;
      for(j1=0;j1<2000;j1++); //DELAY 
      INTCONbits.INT0IF=0;// RESET INT0

      return;
       }
/////////////////////////////////////////  
void delay(int i)
	{
	int i1;
	for (i1=0;i1<i;i1++);
	} 

void main(void)

 {

   TRISB=0x3f; //PORT B AS INPUT 
   TRISC=0X0;  //PORT C AS OUTPUT
    INTCONbits.INT0IE=1;  //ENABLE INT0
    INTCONbits.INT0IF=0;   //reset INT0
    INTCON3bits.INT1IP==1;
    INTCON3bits.INT1IE==1;
    INTCON3bits.INT1IF==0;

    
    INTCON2bits.INTEDG0=1;  //INTERRUP ON RISING //INTERRUP ON RISING
    INTCON2bits.INTEDG1=1;
    INTCONbits.PEIE=0;     //ENABLE HIGH PERIORITY 
    INTCONbits.GIE=1;     // ENABLE ALL INTERRUPT  
	
            while(1)
	{
             //////////////LEDS OPERATION/////////////////
		if ((a&0x1)==0) //condition for led light direction
		{        
	 	PORTCbits.RC0=1;
 		delay(0x3000);
                          PORTCbits.RC0=0;
		delay(0x3000);
		PORTCbits.RC1=1;
		delay(0x3000);
		PORTCbits.RC1=0;
		delay(0x3000);
		PORTCbits.RC5=1;
		delay(0x3000);
		PORTCbits.RC5=0;
		delay(0x3000);
     	}
		else
		{
		PORTCbits.RC5=1;
		delay(0x3000);
		PORTCbits.RC5=0;
		delay(0x3000);
		PORTCbits.RC1=1;
		delay(0x3000);
		PORTCbits.RC1=0;
		delay(0x3000);
		PORTCbits.RC0=1;
 		delay(0x3000);
                          PORTCbits.RC0=0;
		delay(0x3000);
		}

}


}
i know i should change the 'time' function for my case , but i first want that the INT1(switch number 1) interrupt will work.

uploading the picdemo board as it seen in proteus...

again thanks...
 

Attachments

  • Untitled-1.jpg
    Untitled-1.jpg
    225.1 KB · Views: 427
It might have something to do with the fact you copied and pasted the same code for sw and time without altering

Code:
INTCONbits.INT0IF=0;// RESET INT0

in the time section to

Code:
INTCONbits.INT1IF=0;// RESET INT1.
Also if I'm understanding what you're trying to do you can't give delay a cont value

Code:
PORTCbits.RC5=1;
delay(0x3000);

You need to make delay carry a value that's altered in the time function as desired.

Another issue is that you're declaring unsigned char a; globally and using it in two interrupt routines. If that's intended then ok but in case you weren't aware of the issues that it could raise I figured I'd bring your attention to it.
 
Last edited:
the delay function gets an 'int' variable so it is possible to send number,
the program works fine, but my problem that interrupt (INT1) is ignored
i am tracking it with breakpoint on the first 'if' condition. by pressing the RB0 button the program jump to 'void high_vector' , but if i turn on and off the switch that connected to RB1/INT1(can be seen in the picture.) the intrurrped is ignored and i don't see any break at the breakpoint.

**again i know i should change the time function for my purpose but for now i just want the the function will work.
 
....i know i should change the 'time' function for my case , but i first want that the INT1(switch number 1) interrupt will work.....

....**again i know i should change the time function for my purpose but for now i just want the the function will work.....

I miss-interpreted what you meant by that, sorry.

Try adding RCONbits.IPEN=1; to your main function, by where you put INTCON3bits.INT1IP==1;.

Edit: I just noticed something
Code:
    INTCON3bits.INT1IP==1;
    INTCON3bits.INT1IE==1;
    INTCON3bits.INT1IF==0;

You're using two = = signs to assign a value for the INT1 control bits, try this

Code:
    INTCON3bits.INT1IP=1;
    INTCON3bits.INT1IE=1;
    INTCON3bits.INT1IF=0;

If that doesn't work try what I suggested above.
 
Last edited:
still not working ... :confused:
few changes...

Code:
#include <p18f452.h>
#include <stdlib.h>
unsigned char a;
void delay(int);
void time(void);
void sw(void);

#pragma code high_vector=0x08
void high_vector(void)
{
if (INTCONbits.INT0IF==1)
_asm GOTO sw _endasm
if (INTCON3bits.INT1IF==1)
_asm GOTO time _endasm

}
#pragma code
////////////////////////////////////////
#pragma interrupt sw 
void sw(void)
     {
       unsigned int j1;
       a=a+1;
      for(j1=0;j1<2000;j1++); //DELAY 
      INTCONbits.INT0IF=0;// RESET INT0

      return;
       }
////////////////////////////////////////
#pragma interrupt time 
void time(void)
     {
       unsigned int j1;
       a=a+1;
      for(j1=0;j1<2000;j1++); //DELAY 
      INTCONbits.INT1IF=0;// RESET INT0

      return;
       }
/////////////////////////////////////////  
void delay(int i)
	{
	int i1;
	for (i1=0;i1<i;i1++);
	} 

void main(void)

 {

   TRISB=0x3f; //PORT B AS INPUT 
   TRISC=0X0;  //PORT C AS OUTPUT
    
    INTCONbits.PEIE=0;     //ENABLE HIGH PERIORITY 
    INTCONbits.GIE=1;     // ENABLE ALL INTERRUPT 
    INTCONbits.INT0IE=1;  //ENABLE INT0
    INTCONbits.INT0IF=0;   //reset INT0
    INTCON3bits.INT1IP=1;
    INTCON3bits.INT1IE=1;
    INTCON3bits.INT1IF=0;

    
    INTCON2bits.INTEDG0=1;  //INTERRUP ON RISING 
    INTCON2bits.INTEDG1=1;  //INTERRUP ON RISING
   
	
            while(1)
	{
             //////////////LEDS OPERATION/////////////////
		if ((a&0x1)==0) //condition for led light direction
		{        
	 	PORTCbits.RC0=1;
 		delay(0x3000);
        PORTCbits.RC0=0;
		delay(0x3000);
		PORTCbits.RC1=1;
		delay(0x3000);
		PORTCbits.RC1=0;
		delay(0x3000);
		PORTCbits.RC5=1;
		delay(0x3000);
		PORTCbits.RC5=0;
		delay(0x3000);
     	}
		else
		{
		PORTCbits.RC5=1;
		delay(0x3000);
		PORTCbits.RC5=0;
		delay(0x3000);
		PORTCbits.RC1=1;
		delay(0x3000);
		PORTCbits.RC1=0;
		delay(0x3000);
		PORTCbits.RC0=1;
 		delay(0x3000);
        PORTCbits.RC0=0;
		delay(0x3000);
		}

}


}
 
Last edited:
Try changing

Code:
#pragma code high_vector=0x08
void high_vector(void)
{
if (INTCONbits.INT0IF==1)
_asm GOTO sw _endasm
if (INTCON3bits.INT1IF==1)
_asm GOTO time _endasm

}

To

Code:
#pragma code high_vector=0x08
void high_vector(void)
{
	if (INTCONbits.INT0IF==1){
		_asm GOTO sw _endasm
	}
	if (INTCON3bits.INT1IF==1){
		_asm GOTO time _endasm
	}
}

If that doesn't work try adding RCONbits.IPEN=1; again along with the change from above, everything else looks good from what I can tell.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top