Have you read the XC8 user's guide? Section 5.9 deals with interrupts.
In there it states:
The function qualifier interrupt (or __interrupt) can be applied to a C function definition so that it will be executed once the interrupt occurs. The compiler will process the interrupt function differently to any other functions, generating code to save and restore any registers used and return using a special instruction.
and:
An interrupt function must be declared as type void interrupt and cannot have
parameters. This is the only function prototype that makes sense for an interrupt function since they are never directly called in the source code.
It then goes on to give an example:
int tick_count;
void interrupt tc_int(void)
{
if (TMR0IE && TMR0IF) {
TMR0IF=0;
++tick_count;
return;
}
// process other interrupt sources here, if required
}
The compiler itself handles inserting the code into the right location in the vector table to call the ISR.
By default it uses the high priority interrupt vector. To specify the low priority vector instead, insert the attribute low_priority
:
void interrupt low_priority tc_int()
Even if you use MPLab IDE, the code you are writing is still C.
xC8, xc16 and xc32
The XC8, XC16 and XC32 are compilers for the PIC processors by Microchip. XC8 are used for 8bit-MCUs, XC16 for 16bit-MCUs and XC32 for 32bit-MCUs. Here you will get a clear overview about the compilers
The C18 was an old compiler for 8bit MCUs. If you just start programming PICs use the XC-equivalent :-)
Pragma warnings
I already showed you the Migration guide.
For getting the warning on line 23 away write
void My_HiPrio_Int @ 0x0008 (void)
instead of
#pragma code My_HiPrio_Int=0x0008
void My_HiPrio_Int(void)
Have a clear look at page 34 for this!
The pragma
statement on line 36 is not neccessary anymore, when compiling with XC8 instead of C18.
To avoid the warning in line 30 you can write
void interrupt chk_isr(void)
instead of
#pragma interrupt chk_isr
void chk_isr(void)
Page 32 will help you with this ;-)
illegal pointer conversion
You try to send a const
-String with the strdis()
-function. Write
void strdis(unsigned char const *str)
to show the compiler that the pointer values won't be overwritten in the function (hope this works, i don't have XC8 compiler with we, sorry). Otherwise you can make a type conversion when calling strdis()
. For example:
strdis((unsigned char *)"Hello")
But i won't recommend this! Even if you know what you do!
Last in line 83 you write
F_byte=(F_byte * 0.5);
Instead write the following
F_byte=(F_byte / 2);
When calculating with float numbers the compiler will do a type conversion by himself. So he converts F_byte
to a float and then multiplies with 0.5
. float
-calculation is much slower than integer
-calculation, so avoid this whereever possible.
If you find something like F_byte=(F_byte >> 1);
anywhere in the www, you can be sure that every compiler, which is nearly up-to-date will do this code optimisation while compiling.
Complete Code
With XC8 v1.33 this code compiles without any error or warning:
#include<xc.h>
#define TRIG RB7
#define PD PORTD
#define RS RE0
#define RW RE1
#define E RE2
void cmdwrite(unsigned char);
void datawrite(unsigned char);
void strdis(unsigned char const *str);
void MSDelay(unsigned int itime);
void ms_delay();
void dis4digit(unsigned int var);
void CCP1_ISR(void);
void rising(void);
void falling(void);
void interrupt chk_isr();
unsigned char disp = 0;
unsigned char rf = 0;
void interrupt chk_isr(void) {
if (CCP1IF == 1)
CCP1_ISR();
}
void main() {
unsigned long int distance_in_cm;
unsigned long int distance_in_inches;
unsigned long int F_byte;
unsigned char H_byte, L_byte;
ADCON1 = 0x0F;
GIE = 1;
PEIE = 1;
CCP1IE = 1;
TRISD = 0;
TRISE = 0;
TRISB7 = 0;
TRISC2 = 1;
CCP1CON = 0x05;
T1CON = 0x00;
CCPR1L = 0x00;
CCPR1H = 0x00;
TRIG = 0;
E = 0;
cmdwrite(0x01);
cmdwrite(0x38);
cmdwrite(0x38);
cmdwrite(0x38);
cmdwrite(0x0C);
cmdwrite(0x83);
strdis("Ultrasonic");
cmdwrite(0xC0);
strdis("Distance Sensor");
MSDelay(2000);
while (1) {
H_byte = 0;
L_byte = 0;
F_byte = 0;
TRIG = 1;
TRIG = 0;
TMR1H = 0x00;
TMR1L = 0x00;
while (disp == 0);
disp = 0;
H_byte = CCPR1H;
L_byte = CCPR1L;
CCPR1L = 0x00;
CCPR1H = 0x00;
F_byte = (H_byte * 256);
F_byte = F_byte + L_byte;
F_byte = (F_byte / 2);
distance_in_cm = F_byte / 58;
distance_in_inches = F_byte / 148;
cmdwrite(0x01);
cmdwrite(0x80);
strdis("Dist.cm:");
cmdwrite(0x88);
dis4digit(distance_in_cm);
cmdwrite(0xC0);
strdis("Dist.in:");
cmdwrite(0xC8);
dis4digit(distance_in_inches);
MSDelay(6000);
cmdwrite(0x01);
}
}
void cmdwrite(unsigned char var1) {
PD = var1;
RS = 0;
RW = 0;
E = 1;
ms_delay();
E = 0;
}
void datawrite(unsigned char var2) {
PD = var2;
RS = 1;
RW = 0;
E = 1;
ms_delay();
E = 0;
}
void strdis(unsigned char const *str) {
while (*str != '\0') {
datawrite(*str);
str++;
}
}
void dis4digit(unsigned int var) {
unsigned char thp, hp, up, tp, w, x, y;
w = var / 10;
x = w / 10;
y = x / 10;
thp = y;
hp = x % 10;
tp = w % 10;
up = var % 10;
datawrite(thp + 48);
datawrite(hp + 48);
datawrite(tp + 48);
datawrite(up + 48);
}
void ms_delay() {
T1CON = 0x30;
TMR1H = 0xC2;
TMR1L = 0xF7;
TMR1ON = 1;
while (TMR1IF == 0);
TMR1ON = 0;
TMR1IF = 0;
}
void MSDelay(unsigned int itime) {
unsigned int i;
unsigned int j;
for (i = 0; i < itime; i++)
for (j = 0; j < 165; j++);
}
void CCP1_ISR() {
if (rf == 0) rising();
else falling();
}
void rising() {
TMR1ON = 1;
rf = 1;
CCP1M0 = 0;
CCP1IF = 0;
}
void falling() {
TMR1ON = 0;
disp = 1;
rf = 0;
CCP1CON = 0x00;
CCP1M0 = 1;
CCP1IF = 0;
}
Here's my build log:
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory `C:/Users/x.x/VirtualBox VMs/KT/test.X'
make -f nbproject/Makefile-default.mk dist/default/production/test.X.production.hex
make[2]: Entering directory `C:/Users/x.x/VirtualBox VMs/KT/test.X'
"C:\Program Files (x86)\Microchip\xc8\v1.33\bin\xc8.exe" --pass1 --chip=16F877A -Q -G --double=24 --float=24 --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,+osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%%f:%%l: error: (%%n) %%s" "--warnformat=%%f:%%l: warning: (%%n) %%s" "--msgformat=%%f:%%l: advisory: (%%n) %%s" -obuild/default/production/main.p1 main.c
"C:\Program Files (x86)\Microchip\xc8\v1.33\bin\xc8.exe" --chip=16F877A -G -mdist/default/production/test.X.production.map --double=24 --float=24 --opt=default,+asm,+asmfile,-speed,+space,-debug --addrqual=ignore --mode=free -P -N255 --warn=0 --asmlist --summary=default,-psect,-class,+mem,-hex,-file --output=default,-inhx032 --runtime=default,+clear,+init,-keep,-no_startup,+osccal,-resetbits,-download,-stackcall,+clib --output=-mcof,+elf:multilocs --stack=compiled:auto:auto "--errformat=%%f:%%l: error: %%s" "--warnformat=%%f:%%l: warning: (%%n) %%s" "--msgformat=%%f:%%l: advisory: (%%n) %%s" -odist/default/production/test.X.production.elf build/default/production/main.p1
Microchip MPLAB XC8 C Compiler (Free Mode) V1.33
Part Support Version: 1.33 (A)
Copyright (C) 2014 Microchip Technology Inc.
License type: Node Configuration
:: warning: (1273) Omniscient Code Generation not available in Free mode
Memory Summary:
Program space used 46Ch ( 1132) of 2000h words ( 13.8%)
Data space used 33h ( 51) of 170h bytes ( 13.9%)
EEPROM space used 0h ( 0) of 100h bytes ( 0.0%)
Data stack space used 0h ( 0) of 60h bytes ( 0.0%)
Configuration bits used 0h ( 0) of 1h word ( 0.0%)
ID Location space used 0h ( 0) of 4h bytes ( 0.0%)
Running this compiler in PRO mode, with Omniscient Code Generation enabled,
produces code which is typically 40% smaller than in Free mode.
The MPLAB XC8 PRO compiler output for this code could be 432 words smaller.
See http://microchip.com for more information.
make[2]: Leaving directory `C:/Users/x.x/VirtualBox VMs/KT/test.X'
make[1]: Leaving directory `C:/Users/x.x/VirtualBox VMs/KT/test.X'
BUILD SUCCESSFUL (total time: 1s)
Loading code from C:/Users/x.x/VirtualBox VMs/KT/test.X/dist/default/production/test.X.production.hex...
Loading symbols from C:/Users/x.x/VirtualBox VMs/KT/test.X/dist/default/production/test.X.production.elf...
Loading completed
The errors and warnings you get are not MPLab specific... Consider reading a GOOD book about C programming (for example K&R) and google the errors at first.
Best Answer
intentry
The solution is called
intentry
, and is the name of a compiler-generated section. The manual reads:This does not sound very inviting, and it is not obvious that you can place your own code in that section. However, if you do, the linker is already set up to place it at the right address, and most importantly, it knows that it must not place other code there.
To use it, write your code like this:
Simple! The linker takes care of the rest. With or without the Backup reset condition flags option, the startup code now avoids the custom handler:
I'm not sure this is the right solution, nor that it is the only solution, but it is one solution.