CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PCM 3.124 - 16F876 not returning from function call?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Leo



Joined: 22 Feb 2005
Posts: 5

View user's profile Send private message

PCM 3.124 - 16F876 not returning from function call?
PostPosted: Tue Feb 22, 2005 6:56 am     Reply with quote

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

View user's profile Send private message

Re: PCM 3.124 - 16F876 not returning from function call?
PostPosted: Tue Feb 22, 2005 8:20 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 22, 2005 10:55 am     Reply with quote

Hi -

Thanks for the speedy reply.

Quote:
post your code.


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... Smile

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

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 7:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 1:35 pm     Reply with quote

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








PostPosted: Fri Feb 25, 2005 6:31 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 25, 2005 12:56 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Feb 26, 2005 1:54 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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