View previous topic :: View next topic |
Author |
Message |
Jody
Joined: 08 Sep 2006 Posts: 182
|
if statement doesn't work..??? |
Posted: Mon Oct 16, 2006 6:26 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 7:53 am |
|
|
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
|
if statement..... |
Posted: Mon Oct 16, 2006 8:15 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 9:11 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 9:18 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 9:42 am |
|
|
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
Good Luck,
Juanma |
|
|
SLo Guest
|
|
Posted: Mon Oct 16, 2006 9:47 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 10:16 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 10:24 am |
|
|
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
|
|
Posted: Mon Oct 16, 2006 12:38 pm |
|
|
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
|
|
Posted: Mon Oct 16, 2006 2:00 pm |
|
|
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
|
|
Posted: Mon Oct 16, 2006 2:39 pm |
|
|
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
|
|
Posted: Tue Oct 17, 2006 1:29 am |
|
|
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
|
|
Posted: Tue Oct 17, 2006 2:32 am |
|
|
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
|
|
Posted: Tue Oct 17, 2006 2:35 am |
|
|
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 ! _________________ Regards,
Simon.
Last edited by sjbaxter on Tue Oct 17, 2006 4:47 am; edited 2 times in total |
|
|
|