Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

MPLAB simulator skips instructions when single stepping

Status
Not open for further replies.

simonbramble

Active Member
Long story short... I have picked up my PIC development kit after 10 years. I downloaded MPLAB X and installed it. It keeps crashing on startup, so I uninstalled it and reinstalled MPLAB V8.46. Code compiles, using Hi Tech PICC compiler

However, when single stepping through my code, it jumps over one line of code. See below

Code:
void lcd_initialise(void)                /* initialise LCD */
{
    unsigned char n, data;

    setbit(global, 1);                    /* indicate 1x 4 bit transfer*/

    for(n=0; n<10; n++)
    {
        delay_10ms();                    /* wait for power to stabilise*/
    }

    for (n=0; n<3; n++)
    {
        data = 0b00110000;          // it ignores this line and skips straight to the lcd_write()
        lcd_write(data);
    }

It comes out of the delay_10ms() routine, then immediately steps to the lcd_write() routine, bypassing the 'data = ' line thus loading garbage into the lcd_write() routine and not initialising the LCD

What am I doing wrong? It simulated well in MPLABx, but this takes 1.5 hours to install and crashes on startup.

I'm all ears (and heart)

Thanks - Simon
 
Have you compiled the code? If you're stepping through old code then it can do strange things like that.

Mike.
Compiled = recompiled.
 
Have you compiled the code? If you're stepping through old code then it can do strange things like that.

Yes I have compiled the code. It worked perfectly when I used MPLab years ago, but not now. OK my laptop and OS have changed since then. I have compiled and recompiled plenty of times in the last few days.

Anyone have a URL where I can download MPLAB 8.92...? although I think it is the compiler that is at fault and not MPLAB
 
You can get all old versions from this page https://www.microchip.com/development-tools/pic-and-dspic-downloads-archive
I think you have to have a microchip account now... I don't think there's a direct link anymore.

If you think it's just the compiler then open a disassembly window and see if there's code at that line.
Also, try setting a breakpoint on that line. If the instruction isn't there you shouldn't be able to.

The compiler may have rearranged/optimized that code since there's no reason for that statement to be in the loop.
 
Yep.. Pretty normal.
If I insert a nop, the program works. I guess I was being stubborn and saying 'this darn thing should work without me needing to bodge my code'

If you think it's just the compiler then open a disassembly window and see if there's code at that line.
Also, try setting a breakpoint on that line. If the instruction isn't there you shouldn't be able to.

I opened the disassembly window and there is no code at that point, so it looks like that line has been 'optimised out'. Any ideas as to how to 'optimise it back in' again?
 
What is the value of "data" in the LCD_write("data") command?
The compiler May have optimized out the data= 0b00110000; because it is a constant. Is LCD_write(0b00110000);?
 
if the compiler did optimise it, the code for setting 'data' should be before the loop executes,
assuming it's still using 'data' as gophert points out.
 
What is the value of "data" in the LCD_write("data") command?
The compiler May have optimized out the data= 0b00110000; because it is a constant. Is LCD_write(0b00110000);?
Jings…. Missed that.... Even the crappiest optimiser would see that one...
 
Code:
    for (n=0; n<3; n++)
    {
        data = 0b00110000;          // it ignores this line and skips straight to the lcd_write()
        lcd_write(data);
    }

and

What is the value of "data" in the LCD_write("data") command?
The compiler May have optimized out the data= 0b00110000; because it is a constant. Is LCD_write(0b00110000);?

OK for the slow ones at the back (me) what have I missed? I am assigning the value of 0b00110000 to 'data' then reading it into the LCD using lcd_write.

If I assign that value to data inside or outside of the for() loop, what difference does it make?

This exact code works perfectly well in MPLAB X (that I have now got working without crashing on startup)

What have I done wrong?

Jings…. Missed that.... Even the crappiest optimiser would see that one...

This comment makes me feel like I am really missing something obvious. Don't be afraid to use monosyllables and talk me through it slowly please...
 
It also ignores the 'data = ...' lines in the following code too - and these have no for() loops

Should I be defining the data variable with Volatile or some such other keyword?

Code:
    /* function set */
    data = 0b00100000;
    lcd_write(data);
  
    clearbit(global, 1);                /* indicate 2x 4 bit transfer */

    lcd_write(data);
    data = 0b00101000;                    /* N= 1; F=0 */
    lcd_write(data);
    /* display off */
    data = 0b00001000;
    lcd_write(data);
    /* display clear */
    data = 0b00000001;
    lcd_write(data);
    /* entry mode set */
    data = 0b00000110;                    /* I/D = 1 S = 1 */
    lcd_write(data);
    /* display on */
    data = 0b00001100;
    lcd_write(data);
 
There is no point in assigning the data to a variable (data in your case) so the compiler optomises out that line and substitutes lcd_write(0b00101000); as it's more efficient.
The adding a NOP works because the compiler can't know what the assembly instruction did so it can't optimise.

Mike.
 
Since two instructions are next to each other, you are saying
Data = 35;
LCDWrite(data);

That is like giving your brother 35 cents so he can hand it to the cashier. Just give the cashier 35 cents. That is, save yourself one line of code
LCDWrite(35);

Your compiler can see that you are just going to use the "data" variable one time at the current value so it doesn't bother setting the variable, it just passes the value.

When you put the nop() in between, your are fooling the optimizer in the compiler (at least the optimizer in the free compiler). The nop() is like putting a curtain between you and the cashier so she doesn't know you handed money to your brother.
 
Pommie gophert : Thanks for your inputs. I would not have thought it made any difference, but obviously the compiler is clevererer than I thought. Now I see the error of my ways and I really appreciate the help, as always.

Code is going better now.

Finally, I dont have a brother and if I did, I would not give him my pocket money.

I've got short arms and deep pockets

Stay safe - Simon
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top