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

Help with IF statement??????

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



Joined: 20 Mar 2010
Posts: 9

View user's profile Send private message

Help with IF statement??????
PostPosted: Fri Oct 29, 2010 10:01 am     Reply with quote

Hello,
I am using Ver 4.114 of the PCD compiler. I am trying to make a simple IF compare statement. Basically, I take an A/D sample and put it in an Float array. I then want to compare that element to a limit. If true set a bit, if false unset the bit. I know the inter value is 1.6. when I go into the if statement it always comes up with a false(else) answer. Could this be a compiler issue. The program originally worked with version 4.087.

Any suggestion would be appreciated.

Code is below.
Thanks : Crying or Very sad
Code:

for (x=0;x<=12;x++)            // get normal sweep
   {
   mux_control(x);
   delay_ms(200);
   run_volts_start[x]=get_voltage();  // from ad
   mux_control(15);
   delay_ms(50);
//printf("30 second sweep    %u            %f\n\r",x,run_volts_start[x]);
   }                                 // end of get voltages

//enable_interrupts(int_timer1);

restart_WDT();
float upper_limit=1.3;              // upper limit
 float Inter =0;   
     
     for (x=0;x<=12;x++)            // check status     
        {
       
         inter=run_volts_start[x];    // inter was created to try transfer to
                                            // a variable
         IF(inter(1.6) > (1.3)upper_limit )                         
         {
         bit_set(running,x);
         }
         ELSE
         {
         bit_clear(running,x);          // always jumps here
          }
      }
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 12:02 pm     Reply with quote

I would start by forcing 'inter' to the value you think you know it is.
My guess is it is not what you assume it to be.
Either way, it will give you a better idea of what is broken.

Something like:
Code:

inter=run_volts_start[x];    // inter was created to try transfer to
                                            // a variable

to
Code:

inter = 1.6;

just to see it execute every time.

Then maybe depending on the result, assign values to your run_volts_start[x] array and see if the bits change as expected.
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 12:07 pm     Reply with quote

I have had a lot of issues with the PCD, so it could very well be a compiler bug.

My general suggestion is don't do anything fancy in your code. Keep it as simple and basic as possible.

I've looked at the assembly mneumonics for the 30F chips I was working with and don't blame CCS for having trouble with the compiler. It's hugely more complex than the old 18F world.
armondo_522



Joined: 20 Mar 2010
Posts: 9

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 1:19 pm     Reply with quote

Thank you for the response.

It is correct, I can only get it to work when I hard code in
IF(1.6>1.3) this works every time. Its only when I pass variables to the IF statement it doesnt work. I am sure of what the variables are. I have them in a watch window. And The code does work with Version 4.087 with no problem. I suspect the compiler to be at fault. I am no to proficent is assembler at this time.

Thanks again,
pmuldoon



Joined: 26 Sep 2003
Posts: 218
Location: Northern Indiana

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 1:27 pm     Reply with quote

You might want to consider converting your limit to an int16 and doing everything with int16's instead of floats. You only have the resolution of the 10 or 12 bit (not sure of your chip) AD converter anyway.
I'm sure integers would compare properly. And the code will run faster as well.
armondo_522



Joined: 20 Mar 2010
Posts: 9

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 1:46 pm     Reply with quote

Thanks,
I was thinking of trying that. It will mean changing quite a bit of code coming out of AD routine, Which I change to volts so other functions can massage the data in volts..

Regards,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 1:46 pm     Reply with quote

Quote:
I am using Ver 4.114 of the PCD compiler

What PIC are you using ?
armondo_522



Joined: 20 Mar 2010
Posts: 9

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 2:04 pm     Reply with quote

DSPIC30F6015.

Works great except for this bug..
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Oct 29, 2010 2:14 pm     Reply with quote

I checked the arithmetic operation with the below code extracted from your example, and it works correctly in PCD V4.112 and V4.114. Please try to make a short complete example that reproduces the problem for further tests. Otherwise I assume, that the problem is either located in a part of the code not shown yet, e.g. loading the array, or it only occurs under specific conditions.

Code:
int16 running;
int16 x;
float upper_limit=1.3;
float Inter =0;
float run_volts_start[12] = {3.2,0.4,0.6,0.8,1.0,1.2,1.4,1.6,1.8,2.0,22,-12};   
     for (x=0;x<=12;x++)            // check status     
        {
         inter=run_volts_start[x];    // inter was created to try transfer to
         IF(inter > upper_limit )                         
         {
         bit_set(running,x);
         }
         ELSE
         {
         bit_clear(running,x);          // not always jumps here
          }
      }
armondo_522



Joined: 20 Mar 2010
Posts: 9

View user's profile Send private message

PostPosted: Sun Oct 31, 2010 7:27 am     Reply with quote

Thanks FVM,

The only thing not shown, is the loading of the array, which comes from an A/D capture routine. The float #'s are more like 1.336464784 etc. The other puzzling part is that it works perfectly with compiler version 4.087. Another interesting thing, is the listing for both routines is substantually different. Another interesting glitch I found is:

#define FALSE 0
#define TRUE 1

#define BYTE unsigned int8
#define BOOLEAN int1


byte x;
Byte samples =130;

For(x=0,x<=samples,x++)
//do something

the interesting part is that samples comes up as -126 and the loop never runs. by changing samples to long the routine works correctly. I thought a byte was unsigned and the max was 255.It appears that byte is a signed number even when defined as unsigned.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Oct 31, 2010 8:29 am     Reply with quote

I didn't want to doubt, that you observed a bug related to V4.114. It won't be the first newly introduced one. But I couldn't reproduce it under the reported circumstances. To avoid guessing and possible misunderstandings, I think, it would be reasonable to provide a short complete example application, that allows to reproduce the bug.

I could not reproduce the other issue. By the BRA NC instruction, the compiler is performing an unsigned compare. But accessing a byte variable on an odd memory location by a shift operation seems to be a new kind of PCD confusion. (not using MOV.B 923 W4L)
Code:
....................    for(x=0;x<=samples;x++) y++;     
*
00B9C:  CLR.B   922
00B9E:  MOV.B   922,W0L
00BA0:  MOV     922,W4
00BA2:  LSR     W4,#8,W4
00BA4:  CP.B    W4L,W0L
00BA6:  BRA     NC,BB0
00BA8:  INC     0820
00BAA:  INC.B   0922
00BAC:  GOTO    B9E


P.S.: I realized, that the strange kind of byte access has been present since V4.087 before. As a general hint, as long as you don't run absolutely short of RAM, use int16 rather than int8 for indexes and similar purposes.

Code:
....................    for(ix=0;ix<=isamples;ix++) y++;     
*
00B80:  CLR     924
00B82:  MOV     924,W0
00B84:  MOV     926,W4
00B86:  CP      W4,W0
00B88:  BRA     NC,B92
00B8A:  INC     0820
00B8C:  INC     0924
00B8E:  GOTO    B82


P.P.S.: Seeing the BYTE value as -126 simply means using a wrong format when watching the variable.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Oct 31, 2010 10:33 am     Reply with quote

There can be confusion about floats. The coder enters values in base ten notation specifically in this example 1.6. The floating point is also notational but the base is binary and it is further normalized ( an implied 0.bbbbb...bbb). Now when the floating pt notation is 64 bit binary ( as on most PC's) the differences in notation base 10 to base two are less noticeable except in compares ( if x==y )where a single bit difference in bit 63 matters.
Frankly it is often better just to use floating pt in multiplications and or divisions that result in a very broad range of results. For compares a cast after scaling to an integer produces a more certain result. Some coders throw in fudge factors that they call rounding but it's really just notational issues. The good news is that the notation of integers is compatible ( loss less) for all bases. The compiler can have bugs but remember 0.1 in decimal can't be notated in binary loss lessly just as 1/3 can't be notated as 0.33333....333 in base ten losslessly.
There is no mathematical error or compiler error here it is just we use notation to represent numbers and changes in notation like translations from different spoken languages introduce variances.
armondo_522



Joined: 20 Mar 2010
Posts: 9

View user's profile Send private message

Thanks.
PostPosted: Mon Nov 01, 2010 7:03 am     Reply with quote

Thanks to everyone who responded. I changed all the float arrays to INT16 and the program is now working. I can't explain why the floats didn't work, but I will not use floats unless absolutely necessary in the future.

Regards to All.
Laughing
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Mon Nov 01, 2010 10:55 am     Reply with quote

Quote:
I changed all the float arrays to INT16 and the program is now working.

A number of PCD bugs has been (and apparently is still) related to float and int32 operations. A general reason is that PCD (respectively it's programmers at CCS) get often confused with the large amount of PIC24 working registers. There seem to be a long way until these issues are completely overcome.

I just noticed another newly introduced PCD bug, with a construct, that has been working correctly since long until V4.012, but now fails in V4.014.

Here's a complete example.
Code:
#include   <24FJ128GA106.h>
#use delay(clock=8000000)
#use RS232(baud=1200, UART1)

void main()
{
   signed x,y,z;
   x=1000;
   y=0;
   z = x + (((signed int32)x*y) >> 16);   
   printf("%i %i %i\r\n",x,y,z);
   while(1);
}


With the present values, the code gives z = 0 although it should be 1000. The assembly listing reveals, that an intermediate result is overwritten due to working register confusion.

I have reset my working PCD version to V4.012.

Code:
....................    z = x + (((signed int32)x*y) >> 16);   
0035C:  MOV     802,W5
0035E:  CLR     W6
00360:  BTSC    W5.F
00362:  SETM    W6
00364:  MOV     804,W0
00366:  CLR     W1
00368:  BTSC    W0.F
0036A:  SETM    W1
0036C:  MOV     W0,W2
0036E:  MOV     W1,W3
00370:  MOV     W5,W0
00372:  MOV     W6,W1
00374:  CALL    200
00378:  MOV     802,W5
0037A:  CLR     W6
0037C:  BTSC    W5.F
0037E:  SETM    W6
00380:  MOV     W0,W5   // PREVIOUS VALUES ARE OVERWRITTEN!
00382:  MOV     W1,W6   // PREVIOUS VALUES ARE OVERWRITTEN!
00384:  MOV     W6,W0
00386:  MOV     #0,W1
00388:  ADD     W0,W5,W0
0038A:  ADDC    W1,W6,W1
0038C:  MOV     W0,806
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