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.

PIC18F2550 Intterupts with C18

Status
Not open for further replies.

kylemaes

Banned
Hey guys, So I cannot find out on the internet how to get this to work! IVE TRIED EVERYTHING!

I want it so when TMR0 rolls over it goes to an interrupt like Hi-Tech C... Not all this compilcated mess and if there is no way but the complicated #pragma stuff then please say how it is done.
Im also running at 48 mhz clock to let everyone know... This worked before! Just need to know where the interrupt handler is and stuff...


Here is my code:

Code:
#include <p18f2550.h>
#include "delays.h"
#pragma config  PLLDIV = 1, CPUDIV = OSC1_PLL2, USBDIV = 1, FOSC = HS, FCMEN = OFF, IESO = OFF
#pragma config  PWRT = ON,  BOR = OFF, VREGEN = OFF, WDT = OFF, PBADEN = OFF,  LPT1OSC = OFF,  MCLRE = OFF
#pragma config  STVREN = OFF,  LVP = OFF, DEBUG = OFF

/*****************************************************************************************************************************/
#define E PORTAbits.RA5
#define RS PORTAbits.RA4
#define RW PORTAbits.RA3
char fare = 0;
char huns = 0;
char tens = 0;
char ones = 0;
char huns2 = 0;
char tens2 = 0;
char ones2 = 0;
char remain = 0;
char interruptnum = 0;

const char ScreenData[39] = {
0x41, //A 0
0x42, //B 1
0x43, //C 2
0x44, //D 3
0x45, //E 4
0x46, //F 5
0x47, //G 6
0x48, //H 7
0x49, //I 8
0x4A, //J 9
0x4B, //K 10
0x4C, //L 11														//CHARACTER DEFINITIONS!
0x4D, //M 12
0x4E, //N 13
0x4F, //O 14
0x50, //P 15
0x51, //Q 16
0x52, //R 17
0x53, //S 18
0x54, //T 19
0x55, //U 20
0x56, //V 21
0x57, //W 22
0x58, //X 23
0x59, //Y 24
0x5A, //Z 25
0x20, //SPACE 26
0x3A, //: 27
0x30, //0 28
0x31, //1 29
0x32, //2 30
0x33, //3 31
0x34, //4 32
0x35, //5 33
0x36, //6 34
0x37, //7 35
0x38, //8 36
0x39, //9 37
0x25 //% 38
};

void Busy_Flag() 
{ 
  RW = 1;     //read mode
  while(PORTBbits.RB7);     //Loop until finished 
  RW=0;       //default to write mode... 
} 


void Strobe_LCD()
{
	E=1;
	Delay1KTCYx(4);
    E=0;
}
void Write_LCD(unsigned char d,unsigned char x)			//USE "Write_LCD(tabledata,1=cap0=lowercase);" (IF number Cap selection must equal 0!)
{
	char z = 0x00;
	if(!x)
		{
			z=0x20;
		}
	TRISB=0x00;
	PORTB=d+z;
	Strobe_LCD();
	Busy_Flag();
	TRISB=0xFF;
}

void lcd_init()
{
	Write_LCD(0x38,1);
	Write_LCD(0x0C,1);
	Write_LCD(0x01,1);
}


void AddressDisplay(unsigned char c) 
{ 
  Busy_Flag();    //check LCD ready
  RW = 0;     //write mode
  RS=0;       //command mode
  PORTB=c;     //place data on data port
  TRISB = 0;    //PORTB output
  Strobe_LCD();
  RS=1;
  TRISB = 0xFF;    //PORTB input
}

const char programnametext[16] = {
2,14,12,15,14,18,19,4,17,26,26,21,4,17,27,29
/*Co  m p   o  s  t  e  r        V  e  r :   1*/
};

programname()
{
	char a = 0;
	char b;
	char c;
	Write_LCD(0x01,1);
	RS = 1;
	while(a != 16)
		{

            if((a==14) | (a==0) | (a==9) | (a==10) | (a==15) | (a==11)){c=1;}
			Write_LCD(ScreenData[programnametext[a]],c);
			c=0;
			a++;
		}
	RS = 0;
}

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


void main()
{
TRISA=0;
TRISB=0xFF;
TRISC=0;
ADCON0=0;
OSCTUNE=0x0F;
lcd_init();
programname();
/**************************/
INTCON=0b11100000;
T0CON=0b11000111;

/*************************/
	while(1){}
}

#pragma interrupt foo
void foo(void)
{

//PWM DATA CATCH / TEMPERATURE **************************************//
if(interruptnum == 1)
	{
			
			fare=0;		//TEMPERATURE						SETUP ADC SUPPOSED TO BE ADRESL NOT 0!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			fare=fare*100;
			fare=fare/255;
			huns2=fare/100;
			remain=fare-(huns2*100);
			tens2=remain/10;
			ones2=remain-(tens2*10);
	}
//*******************+DISPLAY*************************//
if(interruptnum == 2)
	{
		RS=1;
		AddressDisplay(0xC0);			//FANSPEED
		Write_LCD(ScreenData[5],1);
		Write_LCD(ScreenData[0],0);
		Write_LCD(ScreenData[13],0);
		Write_LCD(ScreenData[27],1);
		if(!huns){Write_LCD(ScreenData[26],1);}else{Write_LCD(ScreenData[28+huns],1);}
		Write_LCD(ScreenData[28+tens],1);
		Write_LCD(ScreenData[28+ones],1);
		Write_LCD(ScreenData[38],1);
	
		AddressDisplay(0x90);
		Write_LCD(ScreenData[19],1);
		Write_LCD(ScreenData[4],0);
		Write_LCD(ScreenData[12],0);
		Write_LCD(ScreenData[15],0);
		Write_LCD(ScreenData[27],1);
		if(!huns2){Write_LCD(ScreenData[26],1);}else{Write_LCD(ScreenData[28+huns2],1);} 				                  //FOR TEMPERATURE!
		Write_LCD(ScreenData[28+tens2],1);
		Write_LCD(ScreenData[28+ones2],1);
		Write_LCD(ScreenData[26],1);
		Write_LCD(ScreenData[3],0);
		Write_LCD(ScreenData[4],0);
		Write_LCD(ScreenData[6],0);
		RS=0;
	}



if(interruptnum == 3)
	{
		interruptnum = 0;
	}
interruptnum++;
INTCONbits.TMR0IF = 0;
}
 
If you look at the C18 documentation..... openTimer0(); The correct settings are all done automatically.... I used to set them manually but moving from chip to chip caused issues... These routines are better...
 
I have tried
Code:
OpenTimer0( TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_EDGE_RISE & T0_PS_1_4 );
yet it still doesnt work. I have also read the Documentation and this is supposed to work. Is there anything wrong with my intterrupt?

Code:
#pragma interrupt foo
void foo(void)
{
 /*****INTTERUPT DATA*****/
}

I remember this code working! here is a pic of it working (Everything under "Composter Ver:1")
**broken link removed**

That was running Hi-Tech C code...

Thanks
 
Last edited:
This is a simple example of C18 interrupt coding.
The "#pragma code" routine tm_int is just a asm coded jump into the handler. One of the reasons for this is that asm code in a ISR will auto volatile the entire routine and all variables in it, so it's a handy compiler optimization defeat hack.

Code:
#pragma code tm_interrupt = 0x8
void tm_int (void)
{
        _asm goto tm_handler _endasm
}
#pragma code

#pragma interrupt tm_handler
void tm_handler (void)                                  // timer functions are handled here
{
static unsigned char    debo=0,bell_count=0;

        if ( PIR1bits.TMR1IF ) {        //      Timer1 int handler, for switch reading, LED  and X10 controls
                PIR1bits.TMR1IF = 0;    // clear int flag
                sample_intcount++;
                WriteTimer1 ( SAMPLEFREQ );
//                MPULED=!MPULED;                                       // flash onboard led (timer1)
....
}



in main ...

        /* interrupt priority ON */
        RCONbits.IPEN = 1;

                LED1=LEDON;                                     // light all switch leds
                LED2=LEDON;
                LED3=LEDON;
                LED4=LEDON;

                BELL=LEDOFF;
        MPULED=OFF;                                     // onboard led OFF

        OpenTimer0 ( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_64 );
        WriteTimer0 ( timer0_off );                                             //      start timer0 at 1 second ticks
        OpenTimer1 ( TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_1 & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF );
        WriteTimer1 ( SAMPLEFREQ );                                             // about 250hz

        /*      work int thread setup */
        INTCONbits.TMR0IE=1;                    // enable int
                INTCON2bits.TMR0IP=1;                   // make it high level
        PIE1bits.TMR1IE = 1;            // enable int
        IPR1bits.TMR1IP = 1;            // make it high level
        /* Enable all high priority interrupts */
        INTCONbits.GIEH = 1;
 
Last edited:
Why is the tm_handler called from
Code:
#pragma code tm_interrupt = 0x8
void tm_int (void)
{
        _asm goto tm_handler _endasm
}
#pragma code

Cant the interrupt just be in there?
 
Why is the tm_handler called from
Code:
#pragma code tm_interrupt = 0x8
void tm_int (void)
{
        _asm goto tm_handler _endasm
}
#pragma code

Cant the interrupt just be in there?

See above (edited) reply.
 
this doesnt work because
Code:
Clean: Deleted file "C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.mcs".
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\mplabc18\v3.40\bin\mcc18.exe" -p=18F2550 "Main.c" -fo="Main.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:87:Warning [2058] call of function without prototype
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:88:Warning [2058] call of function without prototype
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:102:Warning [2058] call of function without prototype
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:108:Warning [2058] call of function without prototype
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:118:Warning [2068] obsolete use of implicit 'int' detected
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:141:Error [1111] undefined label 'tm_handler' in 'tm_int'
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:207:Warning [2058] call of function without prototype
C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.c:208:Warning [2058] call of function without prototype
Halting build on first failure as requested.
----------------------------------------------------------------------
Debug build of project `C:\Users\Kyle\Desktop\MPASM\COMPOSTER 18f\Main.mcp' failed.
Language tool versions: mpasmwin.exe v5.42, mplink.exe v4.40, mcc18.exe v3.40, mplib.exe v4.40
Preprocessor symbol `__DEBUG' is defined.
Fri Jan 20 11:32:14 2012
----------------------------------------------------------------------
BUILD FAILED
 
Add the prototype under the last #include statement.

#include <xxxx.h>
void tm_handler (void);
 
Last edited:
Compiles and written to the PIC. Doesnt work. Maybe is it my timer setup?
Code:
 OpenTimer0( TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_EDGE_RISE & T0_PS_1_4 );
 
INTCON bits are ok. Your original code is using the T0CKI pin external clock instead of the Internal instruction cycle clock.
 
Last edited:
I have got it working! Here is the code:
Code:
#pragma interrupt foo
void foo(void)
{
         INTERRUPTCODE!
}


#pragma code highvector=0x08
void highvector(void)
{

_asm goto foo _endasm
}
#pragma code


And to setup the timer0 plus interrupts
Code:
RCONbits.IPEN = 1; /* Set Priorities */
INTCONbits.GIEL = 0; /* disable low priority interrupts */
INTCONbits.GIEH = 1; /* enable high priority interrupts */
T1CONbits.RD16 = 1; /* Enable 16bit read/write of timer. */
T1CONbits.T1CKPS1 = 0;
T1CONbits.T1CKPS0 = 1;															//INTERRUPT SETUP TIMER0
T1CONbits.TMR1CS = 0; /* Increment every instructrion cycle */
IPR1bits.TMR1IP = 1; /* Make high priority interrupt */
T1CONbits.TMR1ON = 1; /* Enable the timer */
PIE1bits.TMR1IE = 1; /* Enable timer1 interrupt */ 
TRISAbits.RA1=1;
TRISAbits.RA2=1;
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top