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

IF statement executes even when condition is not met

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



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

IF statement executes even when condition is not met
PostPosted: Thu Jun 25, 2009 12:27 pm     Reply with quote

Good evening, I'm having this weird problem with CCS 4.088 in a PIC16F876A.
I have an interrupt that executes when some character is received from the serial port. This interrupt writes the ASCII value received in a variable called Keypress. In the main loop there's a routine that executes only when Keypress!=0 and it sets it back to 0. This has always worked fine for me.
Now I added another IF statement in the main loop. It encloses a simple section of code that was there before and worked fine. It doesn't involve Keypress at all.
Now the keypress routine executes even when Keypress=0.

Let me show the relevant code:

Code:

#include <16f876a.h>
#fuses NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=20000000)
#use standard_io(b)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)

int Keypress=0x00;
int ready=0;

#int_rda     //SERIAL PORT INTERRUPT
void rda_isr() {
  Keypress=0x00;
   if(kbhit()){
    Keypress=getc();
  }
}

#int_TIMER1
void TIMER(){
ready=1;
}

void main() {
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
  enable_interrupts(int_rda);
  enable_interrupts(global);
  enable_interrupts(INT_TIMER1);
  set_TIMER1(0);

do {

//THIS IS THE BUGGY STATEMENT. PRINTF SAYS KEYPRESS=0 WHEN IT SHOULDNT PRINT AT ALL.

if(Keypress!=0)      //
  {
    printf("%d",Keypress);
    Keypress=0;
  }
   

//THIS IS THE STATEMENT THAT CREATES THE PROBLEM. THE CODE INSIDE WAS ALREADY THERE, BUT IF I ADD THE "if(ready==1)", THEN THE PREVIOUS IF JUMPS IN FOR NO REASON.
  if (ready==1)
  {
   
     if (angl>6.28)
        {
        angl=0;
      }
    angl+=0.01;
    tservo0=2000*sin(angl)+3800;
    tservo1=2000*cos(angl)+3800;
    ready=0;
  }
}
while (TRUE);
}


So when I add the condition "if (ready==1)" to the last section of code (it worked properly before, I just want to limit how many times it executes), the if(keypress!=0) statement stops doing its function and the code inside executes even when keypress==0. Its really weird to see that right after evaluating the condition, printf says "0".
I know that the serial port interrupt (INT_RDA) is behaving properly, not executing unless a key is pressed on the computer, so that interrupt is not modifying keypress at all. its the IF statement that's not working properly.
If I delete "if(ready==1)" then the "if(keypress!=0)" works properly and only prints the ASCII code when its different than 0. If I add it again, the other one misbehaves again.
I've tried declaring ready and keypress as volatile, but it doesn't help.
Also I've tried creating a second variable, "copy" of keypress, (let's call it key), so if I do "if(keypress!=0 && key!=0)" everything works fine.

Any idea of why this is happening?? thank you in advance for your help!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 12:59 pm     Reply with quote

How are you testing this ? Are you testing this with real hardware
or a simulator ? If a simulator, which one ?

Are you using a debugger with breakpoints ? Or, are you just running
the program in standalone mode on a board.

I need to know this so I can duplicate your testing environment.
Guest








PostPosted: Thu Jun 25, 2009 1:54 pm     Reply with quote

The program is running in standalone mode on the board itself (SkyPIC with PIC16f876A) and I use printf's to see what's going on.
When executed on MPLAB SIM it works propperly.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 2:01 pm     Reply with quote

The program is not compilable. When compile it, I get these missing
variable declarations:
Quote:
*** Error 12 "pcm_test.c" Line 45(10,14): Undefined identifier angl
*** Error 12 "pcm_test.c" Line 47(9,13): Undefined identifier angl
*** Error 12 "pcm_test.c" Line 49(5,9): Undefined identifier angl
*** Error 12 "pcm_test.c" Line 50(5,12): Undefined identifier tservo0
*** Error 12 "pcm_test.c" Line 51(5,12): Undefined identifier tservo1

Please edit your code and add the variable declarations so it compiles.

Also, test the program that you post. Make sure it shows the failure.
jcobreros



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 2:13 pm     Reply with quote

Sorry, let me post the complete code (its not much longer, but I was trying to go to the point).

Code:

#include <16f876a.h>
#include <math.h>

#fuses NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=20000000)
#use standard_io(b)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_C7)

volatile int Keypress=0;
int servoswitch=0;
volatile int key=0;
float angl=0;
long int tservo0=1900;
long int tservo1=1900;
long int temp0=1900;
long int temp1=1900;
volatile int ready=0;

#int_rda
void rda_isr() {
  Keypress=0;
   if(kbhit()){
    Keypress=getc();
     }
}

#int_TIMER1
void TIMER(){
switch(servoswitch)
   {
      case 0:
         {
         set_TIMER1(65535-tservo0);
         output_bit(PIN_B0,1);
         servoswitch++;
         break;
         }
      case 1:
         {
         set_TIMER1(65535-tservo1);
         output_bit(PIN_B0,0);
         output_bit(PIN_B1,1);
         servoswitch++;
         break;
         }
      case 2:
         {
         set_TIMER1(15535+tservo1+tservo0);
         output_bit(PIN_B1,0);
         servoswitch=0;
         ready=1;
         break;
         }
   }
}

void main() {


  setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);
  enable_interrupts(int_rda);
  enable_interrupts(global);
  enable_interrupts(INT_TIMER1);
  set_TIMER1(0);



       
do {
   

// CONTROL DESDE LA RS-232
   if(keypress!=0){
       printf("%d",keypress);
      switch(Keypress)
      {
         case 49:
         {
            tservo0=1900;
            tservo1=1900;
            break;
         }
         case 50:
         {
            tservo0=5800;
            tservo1=5800;
            break;
         }
      }         
      key=0;
      Keypress=0;
    }
 
  if (ready==1)
  {
    ready=0;
     if (angl>=6.28)
        {
        angl=0;
      }
    angl+=0.1;
    tservo0=2000*sin(angl)+3800;
    tservo1=2000*sin(angl)+3800;
   
  }

while (TRUE);
}

FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 2:15 pm     Reply with quote

To be sure, that the content of keypress doesn't change between the if(!keypress) and the printf() statement, you must either disable interrupts or copy the value to a shadow variable, that can't be changed during an interrupt event.

Before you try to identify other possible causes for the problem, you should exclude the obvious ones.
jcobreros



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 2:24 pm     Reply with quote

@FvM: im afraid I dont know how to do that. I see how an interrupt can happen between the IF and the PRINTF, but I assumed its value wouldn't change as the variable is not used by anything else. How do I create a shadow variable?
thank you in advance!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 2:32 pm     Reply with quote

It's clear that you didn't test this program, because it has no oscillator
fuse (should be HS). If you don't specify the fuse, the compiler defaults
to "RC" mode. I just downloaded your program to my board and it
doesn't run. I don't want to work on this any more.
jcobreros



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 3:00 pm     Reply with quote

@PCM programmer: I didnt know I had to add an oscillator fuse, all the programs I've done run on my board (SkyPIC with a PIC16F876A).
All I can tell you is that the program compiles on MPLAB with CCS 4.088 and runs on my PIC (with bootloader). I have 2 hobby servos connected to it and they move with the sine and cosine values.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 3:01 pm     Reply with quote

Code:
save_keypress = keypress;
if(save_keypress!=0){
    printf("%d",save_keypress);
jcobreros



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

PostPosted: Thu Jun 25, 2009 3:13 pm     Reply with quote

@FvM: I had already tried something similar (the redundancy variable "key"), but the result was the same.
Now I did it exactly your way (assigning the value right before the evaluation) and the result is even worse and I dont understand it.
Now i get a bunch of 0's and some random -128's and 8's...

Hey, thank you all, i've never had people answering me so fast.
ttelmah
Guest







PostPosted: Thu Jun 25, 2009 3:47 pm     Reply with quote

I suspect your problem is hardware.

The big 'difference', between the working, and faulty code, is that you are adding code that presumably controls a motor or something similar.
What you are describing is realistically a fairly 'classic' description of a processor experiencing noise on it's supply, or RF noise on some of the I/O pins.

Try the test code, with the extra lines, but _without the motor hardware attached_. I suspect you will find it is working fine.

It then comes down to properly decoupling and overshoot clamping the motors. One classic problem is forgeting that a motor, when switched off, is both a freewheeling inductor, and a generator, and the power from this, _has_ to go somewhere. transistors will often route a lot of the energy back to their base connections, and back ito the processor driving them, if the energy is not clamped elsewhere....

Best Wishes
jcobreros



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 12:38 pm     Reply with quote

@ttelmah: I have unplugged the servos and the result is the same. I still have to try with a different power source (battery pack?) and in a different PIC. Noise seems like a reasonable cause.
I will keep working on this and post any change. Thank you for your help!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 1:20 pm     Reply with quote

I didn't realize you were using a bootloader for the 16F876A. That
means the fuses are preset in the bootloader code. Make sure the
bootloader code has the NOLVP fuse in it.

I don't have vs. 4.088. I only have 4.087 and 4.089. I believe that vs.
4.088 was an in-between version, where CCS discovered a problem with
the installation and quickly came out with vs. 4.089. Here's their note
from the versions page:
Quote:
4.089 A duplicate filename error on install is fixed


So I installed vs. 4.089 and ran it. Your case statements check for
a keypress of '1' or '2'. I pressed those repeatedly, and it displayed
the following result:
Quote:
495049504950495049504950495049

If I don't press any keys, it doesn't display anything. So I think it's
working properly for me. This was tested on a PicDem2-Plus board.
There are no motors connected to the board.

The code that I tested was your full program, from post #5.
jcobreros



Joined: 25 Jun 2009
Posts: 7

View user's profile Send private message

PostPosted: Fri Jun 26, 2009 1:32 pm     Reply with quote

@PCM programmer: hey thanks for taking the time. I guess this narrows it to my hardware. I'll try it on another PIC when I get home and if the result is the same I will just add a redundant variable so the IF statement checks for both of them.
Again thanks for the help. This is a great forum
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