1
\$\begingroup\$

I have set myself up with on a breadbord with a simple PI16F1825. I am using MPLAB x with XC8 V2.45 i have a led that turn on/off every second using the simple delay function. i would just like to have a variable which increments every time it blinks. To check the increment of the variable I halt the target (I use picKit3) and check that the variable has incremented a sufficient number of times Vs how many times it has blinked. here is the code. easy enough

#include <xc.h>
#define _XTAL_FREQ 500000
#define PUSH RC2
#define LED LATC3

void main(void)
{
    volatile int my_var;
    my_var=0;
    ANSELC=0;             //select PORT C as GPIO
    TRISC=0b11110111;    //RC2 is input (Push) RC3 is output (LED)
    OPTION_REG=0b01111111; //allow internal pull ups

    while(1)
    {
        __delay_ms(500);
        LED=1;

       __delay_ms(500);
        LED=0;
        my_var=my_var+1;

    }
}

the problematic line seems to be:

my_var=0;

this is just supposed to initialize the counter variable.

  • when the line is absent, and I put a breakpoint on line LED=1; I can see my_var incrementing 1 by one indefinitely. Of course it starts off at any random number as the variable has not been initialized, but clearly it increments with each blink.

  • when the line my_var=0 is present, on the same breakpoint, my_var will start at '0' and then toggle between 1 and 0. as if for some strange reason it went over the my_var=0 line at one point.

I tried with other values too. if I put my_var=5; the value will toggle between 5 and 6, again as if the code goes over the my_var=5 initialization line at each loop.

in fact if I put a breakpoiny on the my_var=0 line i can see that the codes actualy goes there at every blink! how is that possible? (i tried changing while(1) with for(;;)... same behaviour)

I've been doing a lot of Python lately, so maybe it is a nose in the middle of the face sort of mistake I made because I forgot C. If so I am very sorry, and greatfull at anyone who can point it out. I am a bit blocked in my project if i cannot even increment a counter!

oherwise i really don't see what i can do except check the generated assembly... wherever that is (if it even exists!)

\$\endgroup\$
6
  • 3
    \$\begingroup\$ What are your config fuse settings? This is the sort of behaviour you could expect to see if the watchdog timer is causing a reset. Although that doesn't explain what happens when the initialisation is left out. \$\endgroup\$
    – user85471
    Commented Sep 25, 2023 at 22:31
  • \$\begingroup\$ You should be able to check the assembly from WIndow>Debugging>Output>Disassembly Listing File. You might be prompted to change the 'load symbols' setting and you may need to recompile to update the output. \$\endgroup\$
    – user85471
    Commented Sep 25, 2023 at 22:32
  • 1
    \$\begingroup\$ @user85471 Your explanation doesn't conflict with the observations. So I think you are right. Without the initializer, the local variable is still allocated in the function prologue. Likely to the same memory location in the stack. Since the memory will still have the old value, observation is consistent with restarting. The watchdog is a good call. But I also don't know what's in the c compiler's crt0 code which then calls main. \$\endgroup\$ Commented Sep 26, 2023 at 3:27
  • \$\begingroup\$ You should never expect your c debugger to land on the c line where you think you set a breakpoint. The actual break is implemented at a hardware break point, which may not be where you think it is in machine code, which may not be where you think it is in c, which certainly won't exactly match line-by-line what it in your processor. \$\endgroup\$
    – david
    Commented Sep 26, 2023 at 4:50
  • \$\begingroup\$ I like to insert an asm("NOP") and break on those to avoid the exact-line issue. \$\endgroup\$
    – rdtsc
    Commented Sep 26, 2023 at 13:35

1 Answer 1

0
\$\begingroup\$

OK thank you all for your help. user85471 was right: it is caused by the watchdog timer. my CONFIG1 bits were set with WDT enabled.

this caused the following behaviour:

Without the init: the variable increments, when the WDT kicks in the loop starts back up from "Main", but the variable is not reset. Therefore it continues incrementing. So you have the impression everything is working fine when in fact it is reseting all the time.

With the init: same behaviour but every time the reset happens the variable is set to 0 with the init line. Revealing the faulty behaviour that existed from the start.

I fixed the WDT, it now runs smoothly... didn't think While(1) would be any trouble :-p

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.