|
|
View previous topic :: View next topic |
Author |
Message |
Leo
Joined: 22 Feb 2005 Posts: 5
|
PCM 3.124 - 16F876 not returning from function call? |
Posted: Tue Feb 22, 2005 6:56 am |
|
|
Hi -
I'm having trouble with a program I'm writing for a 16F876.
I have a function that should return a float, but the program seems not to return from the fuction, but instead to 'fall through', and start executing the next section of code in memory.
This problem function is the last section of code on a page - there is a chunk of unused memory (ANDLW 0xff) before a page boundary, and then the code that it falls through to.
Looking at the program memory (in MPLAB), the PCLATH bits are being set correctly, but it's almost as if the compiler forgot to add the GOTO opcode to return to the calling function. Adding this line manually seems to fix the problem.
Can anyone suggest what I might have done wrong?
I have optimisation set at zero, the crystal is 20Mhz, 5V, and I'm not using any interrupts (yet!)
Thanks
Leo |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
Re: PCM 3.124 - 16F876 not returning from function call? |
Posted: Tue Feb 22, 2005 8:20 am |
|
|
Leo wrote: |
I'm having trouble with a program I'm writing for a 16F876.
Can anyone suggest what I might have done wrong?
|
post your code.
jds-pic |
|
|
Leo
Joined: 22 Feb 2005 Posts: 5
|
|
Posted: Tue Feb 22, 2005 10:55 am |
|
|
Hi -
Thanks for the speedy reply.
Ok. Sorry it's so long and unreadable. It used to span several files, but i've stuck it all together in this one file to post. Still displays same behaviour.
(It's supposed to read values from an ADXL accelerometer, and attempt to integrate them over time to calculate displacement. It's not very accurate...
When compiled, I reckon address 0x07D0, which is the last instruction of the get_dx() function should be GOTO 0x4b8 (0x2CB8) and not ADDLW 0xb8 (0x3FB8)., which is what's there when I compile it.
Thanks.
Leo
Code: | #include <16F876.h>
#fuses HS, NOWDT, NOBROWNOUT, NOPROTECT, NOLVP
#device *=16 ADC=10
#use delay(clock=20000000)
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7)
#define DEBUG true
#define XOUT PIN_C1
#define YOUT PIN_C2
#define CAL_COUNT 200
#define G 9.8
float DT, DTZ, T2, XCAL, YCAL;
float XNOISEMAX, XNOISEMIN;
float YNOISEMAX, YNOISEMIN;
float UX, UY;
void initAccn();
float get_dx();
float get_dy();
float get_ax();
float get_ay();
void main() {
float x,y;
int i;
x = 0.0;
y = 0.0;
printf("Restart: %X\n", restart_cause());
#ifdef DEBUG
printf("main: Initialising..\n");
#endif
initAccn();
#ifdef DEBUG
printf("main: Initialised.\n");
#endif
delay_ms(1000);
#ifdef DEBUG
printf("main: starting main loop\n");
#endif
while(TRUE) {
for (i=0; i<255; i++) {
x += get_dx();
y += get_dy();
}
printf("\rX: %1.2f Y: %1.2f", x,y);
}
}
void initAccn() {
float x,y;
int i;
T2 = 0.0;
DT = 0.0;
XCAL = 0.0;
YCAL = 0.0;
XNOISEMIN = 0.0;
XNOISEMAX = 0.0;
YNOISEMIN = 0.0;
YNOISEMAX = 0.0;
UX = 0.0;
UY = 0.0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
#use fast_io(c)
set_tris_c(0x06);
output_c(0x00);
delay_ms(100);
for (i = 0; i<CAL_COUNT; i++) {
while (input(XOUT)){}
while (!input(XOUT)){}
set_timer1(0);
while (input(XOUT)){}
while (!input(XOUT)) {}
T2 += get_timer1();
}
T2 /= CAL_COUNT;
DT = T2 * 0.0000002;
DTZ = 0.5 * DT * DT;
#ifdef DEBUG
printf("initAccn: T2 = %1.2fms\n", (T2 * 0.0002));
printf("initAccn: DT = %1.2fs\n", DT);
#endif
for (i = 0; i<CAL_COUNT; i++) {
while (input(XOUT)){}
while (!input(XOUT)){}
set_timer1(0);
while (input(XOUT)){}
XCAL += (get_timer1() / T2);
}
XCAL /= CAL_COUNT;
#ifdef DEBUG
printf("initAccn: XCAL = %1.2f\n", XCAL);
#endif
for (i = 0; i<CAL_COUNT; i++) {
while (input(YOUT)){}
while (!input(YOUT)){}
set_timer1(0);
while (input(YOUT)){}
YCAL += (get_timer1() / T2);
}
YCAL /= CAL_COUNT;
#ifdef DEBUG
printf("initAccn: YCAL = %1.2f\n", YCAL);
#endif
for (i = 0; i<CAL_COUNT; i++) {
x = get_ax();
y = get_ay();
if (x > XNOISEMAX) {
XNOISEMAX = x;
}
if (x < XNOISEMIN) {
XNOISEMIN = x;
}
if (y > YNOISEMAX) {
YNOISEMAX = y;
}
if (y < YNOISEMIN) {
YNOISEMIN = y;
}
}
#ifdef DEBUG
printf("initAccn: X deadband: %1.3f - %1.3f \n", XNOISEMIN, XNOISEMAX);
printf("initAccn: Y deadband: %1.3f - %1.3f \n", YNOISEMIN, YNOISEMAX);
#endif
return;
}
float get_dx() {
float disp, accel;
accel = get_ax();
if (accel > XNOISEMIN &&
accel < XNOISEMAX) {
accel = 0.0;
}
disp = (UX * DT) + (accel * DTZ);
UX += (DT * accel);
return disp;
}
float get_dy() {
float disp, accel;
accel = get_ay();
if (accel > YNOISEMIN &&
accel < YNOISEMAX) {
accel = 0.0;
}
disp = (UY * DT) + (accel * DTZ);
UY += (DT * accel);
return disp;
}
float get_ax() {
float t1, accel;
while (input(XOUT)) {}
while (!input(XOUT)){}
set_timer1(0);
while (input(XOUT)) {}
t1 = get_timer1();
accel = ((t1 / T2) - XCAL) * 8 * G;
return accel;
}
float get_ay() {
float t1, accel;
while (input(YOUT)) {}
while (!input(YOUT)){}
set_timer1(0);
while (input(YOUT)) {}
t1 = get_timer1();
accel = ((t1 / T2) - YCAL) * 8 * G;
return accel;
}
|
|
|
|
Leo
Joined: 22 Feb 2005 Posts: 5
|
|
Posted: Thu Feb 24, 2005 7:05 am |
|
|
Is this a compiler bug, or have I done something obviously wrong? I'd appreciate any suggestions.
Thanks
Leo |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 24, 2005 1:35 pm |
|
|
I installed PCM vs. 3.124 and I copied and pasted your code into MPLAB
vs. 5.70.40. I couldn't duplicate your problem. At address 0x7D0 it
jumps to 7E2 which is the exit point for the routine.
Are you sure you're using 3.124 ? Check the top of the .LST file
to confirm your version number.
Code: | 07CC 02E7 00999 SUBWF 67,F
07CD 1903 01000 BTFSC 03.2
07CE 2FD5 01001 GOTO 7D5
07CF 1FE6 01002 BTFSS 66.7
07D0 2FE2 01003 GOTO 7E2 // This jumps to a RETLW statement
07D1 0803 01004 MOVF 03,W
07D2 3A01 01005 XORLW 01
07D3 0083 01006 MOVWF 03
07D4 2FE2 01007 GOTO 7E2
07D5 0865 01008 MOVF 65,W
07D6 00E7 01009 MOVWF 67
07D7 0861 01010 MOVF 61,W
07D8 02E7 01011 SUBWF 67,F
07D9 1903 01012 BTFSC 03.2
07DA 2FE1 01013 GOTO 7E1
07DB 1FE6 01014 BTFSS 66.7
07DC 2FE2 01015 GOTO 7E2
07DD 0803 01016 MOVF 03,W
07DE 3A01 01017 XORLW 01
07DF 0083 01018 MOVWF 03
07E0 2FE2 01019 GOTO 7E2
07E1 1003 01020 BCF 03.0
07E2 3400 01021 RETLW 00 |
|
|
|
Guest
|
|
Posted: Fri Feb 25, 2005 6:31 am |
|
|
Hi -
Thanks for taking the time to look at this.
I do have PCM 3.124, but I have a different version of MPLAB (6.60).
Perhaps this is whats causing my problem?
Having a closer look at the LST file, the correct jump is visible. It's only when I look at the program memory within MPLAB that the statement is wrong.
Here's the LST file:
Code: | 07CB: MOVWF 79
07CC: MOVF 58,W
07CD: MOVWF 7A
07CE: BSF 0A.3
07CF: BCF 0A.4
07D0: GOTO 4B8 (RETURN) |
and here's the program memory in MPLAB (which is what gets burned into the pic):
Code: | 07CB 00F9 MOVWF 0x79
07CC 0858 MOVF ??32767, W
07CD 00FA MOVWF 0x7a
07CE 158A BSF PCLATH, 0x3
07CF 120A BCF PCLATH, 0x4
07D0 3FB8 ADDLW 0xb8
07D1 3FFF ADDLW 0xff |
Why would they be different?
Leo |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 25, 2005 12:56 pm |
|
|
The .LST file and the Program Memory window have the same
code, on my system. I tested this with MPLAB vs. 7.01 and your
version of the compiler.
I suspect that you're looking at a .LST file which may have the same
name as your test program, but it could be in a different directory.
Or, when MPLAB displays a dialog and says the .LST file has changed,
and do you want to update it, you may be selecting "No". That could
also account for the difference.
Or, you may be using a network drive, and somehow things don't get
updated.
I think it's got to be one of those.
--------
On edit: Deleted my rant about the useless MRU list in MPLAB. |
|
|
Leo
Joined: 22 Feb 2005 Posts: 5
|
|
Posted: Sat Feb 26, 2005 1:54 pm |
|
|
PCM -
I'm almost certain it's none of the above! Certainly, I'm not using a network drive and I'm not clicking 'No' to anything.
Anyway, I went back to the verion of MPLAB thats on the CCS CD (5.4 or something!) and the problem disappeared, so I can safely say that the compiler is not at fault.
I'm going to download MPLAB 7 now and see what happens with that.
Thanks very much for spending so much time on this silly problem.
Leo |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|