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.
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
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.
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);?
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...
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.
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.
Pommiegophert : 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.