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 doesn't work..???
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

if statement doesn't work..???
PostPosted: Mon Oct 16, 2006 6:26 am     Reply with quote

Hallo,

When debugging I get to a point where the variable is set (string_ready=1) and the if statement just steps over it...

[code]
while(TRUE)
{
if(string_ready)
{
printf("Alive");
}
}
[/code]
[img]http://home.casema.nl/elselinde.wisman/Debugger.jpg[/img]

Thanks in advance,

Jody
SLo
Guest







PostPosted: Mon Oct 16, 2006 7:53 am     Reply with quote

The code in the If statement does nothing.
You're testing a variable that can never change within the infinite loop in main().
So the compiler is allowed to, and is more efficient to remove the code.
My guess is that if you look at the assembler listing of the output, that there will be no code generated for the If statement concerned.
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

if statement.....
PostPosted: Mon Oct 16, 2006 8:15 am     Reply with quote

In mine ISR routine is it possible to change the variable.. and in the main function I reset the variable..
[code]#int_rda
void serial_isr()
{
string[next_in]=getc();

output_toggle(ERROR);

if(string[next_in] == '\n') //Einde string
{
output_high(CTS); //Stop communication
string[next_in] = '\0';
output_toggle(HARTBEAT);
string_ready = TRUE;
}
}[/code]
Neckruin



Joined: 17 Jan 2006
Posts: 66

View user's profile Send private message

PostPosted: Mon Oct 16, 2006 9:11 am     Reply with quote

In your serial interrupt you dont manage your next_in counter. Anyway a don't think thats the problem.
Maybe the condition within the ISR is never TRUE. I mean, maybe, you never detect the end of the string '\n' for some reason.
I suggest you to force a clear_interrupt(INT_RDA); and try to add disable_interrupts(INT_RDA) at the beggining of your code and enable_interrupts(INT_RDA) at the end.
It may help but is not sure, I'm just suggesting things that you may have already tried.
Good Luck.

Juanma

PD. I hope someone else more skilled than me helps you as well.
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Mon Oct 16, 2006 9:18 am     Reply with quote

When I watch the variable with the ICD I can see that it is set. But it steps OVER the if statement. See the picture.....[img]http://home.casema.nl/elselinde.wisman/DEBUGGER2.jpg[/img]
Neckruin



Joined: 17 Jan 2006
Posts: 66

View user's profile Send private message

PostPosted: Mon Oct 16, 2006 9:42 am     Reply with quote

Unfortunately I'm not used to the debugger you are using. I can't help you if the problem is the debugging process.
Maybe the problem is in the next "if" statement, not in the first one.
Sorry for being so few helpful Sad

Good Luck,

Juanma
SLo
Guest







PostPosted: Mon Oct 16, 2006 9:47 am     Reply with quote

You didn't mention the ISR in the original post, so I was unaware of it.
As your code looks fairly short, please post your full code, the version of the compiler that you are using and the target PIC device.
If possible also post the assembly listing for the code.
When you post code into the forum remember to check the 'Disable HTML in this post' selection.
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Mon Oct 16, 2006 10:16 am     Reply with quote

Code:



#include "L:\DAC_HANS\DAC_HANS.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors, sample_early)

#include <string.h>
#include <stdlib.h>
#include <input.c>

#define  TRIGGER              PIN_D3
#define  A0                   PIN_C1
#define  A1                   PIN_C2
#define  HARTBEAT             PIN_D0
#define  ERROR                PIN_D7
#define  RTS                  PIN_B1
#define  CTS                  PIN_B2

#define  DATAFLUSH            01
#define  DATA                 02
#define  DATASAMPLE           03
#define  DATATRIGGER          04
#define  DATAFIRST            05
#define  DATALAST             06
#define  LISTMODECONT         07
#define  LISTMODESINGLE       08
#define  LISTSTART            09
#define  LISTSTOP             10
#define  POS                  11
#define  RESET                12
#define  TABEL_LENGTE         510
#priority rda, rb

int16 tabel[TABEL_LENGTE];
int16 delay_dac;
char string[16]         = "DATA 0,100";
int16 start            = 0;
int16 stop             = 0;
int16 firstdata        = 0;
int16 lastdata         = 499;
int16 trigger_mode     = 0;
int16 triggerdata      = 0;
int1 string_ready     = FALSE;
int klaar               =  0;
BYTE listmode_cont     = 0;
BYTE extern_trigger    = 0;
BYTE next_in           = 0;
BYTE next_out          = 0;



#int_rda
void serial_isr()
{
   string[next_in]=getc();

   if(string[next_in] == '\n')   //Einde string
   {
     string[next_in] = '\0';
     output_toggle(HARTBEAT);
     string_ready = TRUE;
   }

   output_toggle(ERROR);
   next_in=(next_in+1);
   stop = 1;
}




void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16|SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);
   enable_interrupts(int_rda);
   enable_interrupts(global);



   while(TRUE)
   {
   printf(".");

      if(string_ready)
      {
         string_ready = 0;
         printf("ready");

     }

   }
}


and the include file:

Code:

#include <18F8722.h>
//#device ICD=TRUE
#device  HIGH_INTS=TRUE
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //Debug mode for ICD
#FUSES LVP                    //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES MCU                      //Microcontroller Mode

#use delay(clock=10000000)
Ttelmah
Guest







PostPosted: Mon Oct 16, 2006 10:24 am     Reply with quote

Some debuggers have problems stopping on certain lines, and handling logic on bit fields. It may be that yours is one that shows this behaviour. Look at the .lst (assembler) file. The if statement, certainly should exist, but probably as a BTFSC, or BTFSS instruction, which will 'skip' the next line depending on the test.
It is relatively easy to find the code, since the compiler inserts the C code as comments into the file.
If you don't understand the assembler, or it does not make sense, post the 'snippet' covering this line. (one line in front, and a little after).

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Mon Oct 16, 2006 12:38 pm     Reply with quote

Code:

.................... 
....................       if(string_ready == TRUE)
011AA:  BTFSS  x3A.0
011AC:  BRA    1434
....................       {
.................... 


I beleive that this is the part you mean???

I am not sure how to read this....
SLo
Guest







PostPosted: Mon Oct 16, 2006 2:00 pm     Reply with quote

The code appears OK at a glance, your compiler is a later version than mine so I can't try it as mine does not support this PIC.
The assembler extract is indeed the correct one, though this does not match exactly the code you posted as the assembler is
if(string_ready == TRUE)
and the code is
if(string_ready)
But, the assembler means Bit Test in File, Skip if Set (BTFSS)
so if the bit in position zero is set then the next instruction will be skipped.
From this we can deduce that the compiler is using Bit 0 of memory address x3A as the int1 (boolean) variable string_ready.
If this is true (set, or =1) then the code will continue to run into the next instruction after the BRA 1434, but if the bit is not set, the next instruction is not skipped, so the BRAnch to address 1434 is executed.

This apart, Ttelmah may be correct in that the instruction is really a sort of 2 instructions in 1 - test the bit & skip if required. This may make it impossible to stop the debugger - the 2 parts can't be seperated.

So, if you run the code without the debugger does it work, if not what do you see on the serial port - I guess that you quickly fill your terminal with '.' characters, you might consider removing this.

Also you are in danger of writing into memory that you did not intend in the serial receive interrupt as you don't test that you've reached the end of string[] and copy the received character into string[next_in] even if next_in is larger than the size of string[].
'C' will happily assume that you know what you are doing and will glibly write over whatever happens to be really in the memory - we've all done it and some of still do it!
Ttelmah
Guest







PostPosted: Mon Oct 16, 2006 2:39 pm     Reply with quote

You may find that if you insert the debugger stop on the assembler line, rather than the C line, it'll then work. The code required for the 'if', is there.

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 17, 2006 1:29 am     Reply with quote

I have run the program without the debugger... The result is the same...
It doesn't go into the if statemant... I printed out the value over the serial port.. so I know for sure the variable has the value = 1.

I think the problem is in the interrupt routine... And I am happy to rewrite the serial routine, but I don't know what you mean about it and what I must do....

When I use a variable (in the if) that is not comming from the interrupt routine it is working like it should be...
But then again, what I have done should work....???? I think
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Oct 17, 2006 2:32 am     Reply with quote

Strange that your code is working when you use a variable that's not inside the interrupt routine. In your interrupt routine I spot two errors that might have to do with the strange behaviour:

1) You are storing data in the string array but you are not testing for exceeding the array limits. When receiving more than 16 characters you will be overwriting other data (variables) in RAM with unknown behaviour as a result.
2) You never reset the next_in variable. Same result as 1.

And...which compiler version are you using?
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 17, 2006 2:35 am     Reply with quote

Jody,

You do have one potential problem...

the string buffer 'string[]' is allocated as a 16 char array, but the index you use to write to it is never checked to ensure that it only has a value between 0(zero) and 15 !!! (the bounds of this array).

You could be overwriting the array buffer and corrupting the string_ready flag and other variables in memory that are allocated after the string[] array.

Edit : ckielstra ... you beat me to it ! Smile
_________________
Regards,
Simon.


Last edited by sjbaxter on Tue Oct 17, 2006 4:47 am; edited 2 times in total
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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