I am using NEX Robotics board for LPC2148. I find very strange problem with below lines of code.
//Prototypes void diaplayInRow1WithPosition(unsigned char* data, unsigned char position); void diaplayInRow2WithPosition(unsigned char* data, unsigned char position); unsigned char convertHigherNibbleToASCIIValue(unsigned char data); unsigned char convertLowerNibbleToASCIIValue(unsigned char data); int main (void) { unsigned char temp2; unsigned int PLLStatus; initializeAll(); PLLStatus = PLL0STAT; temp2 = convertLowerNibbleToASCIIValue(PLLStatus); diaplayInRow1WithPosition(&temp2,15); temp2 = convertHigherNibbleToASCIIValue(PLLStatus); diaplayInRow1WithPosition(&temp2,14); temp2 = PLLStatus>>8; temp2 = convertLowerNibbleToASCIIValue(PLLStatus); diaplayInRow1WithPosition(&temp2,13); return(0); } When this code is executed, I see a blank display. I noticed that the problem is with last convertLowerNibbleToASCIIValue function call. It should have been:
temp2 = convertLowerNibbleToASCIIValue(temp2 ); But because of this one line error, why entire display is blank? Only last function diaplayInRow1WithPosition should have given trouble right? Even after changing with above line, I am getting blank display. So I replaced that line containing last convertLowerNibbleToASCIIValue as
temp2 = convertLowerNibbleToASCIIValue(PLLStatus>>8); And finally I got correct display.
Unable to digest the problem. Anyone can help? Main answer I need is if at all there is a problem in one line, why previous lines are not getting executed correctly? I am using Keil compiler and any compiler dependencies? There is no compilation error. If there is a problem with types etc, will entire program get corrupted? Also I noticed that adding extra dummy line such as temp=10; changes the behavior even though temp variable is not utilized.
Thanks for the responses. I did not give entire code because the behavior changes just by adding even one line of extra code which does nothing. This extra line can be added anywhere and need not be in this function. For example: adding a statement something like temp2=1; may enable LCD display if it was not turning ON.
I am suspecting Keil and may be it is optimzing the code and causing some problem. I kept optimizing level at zero, but still it gives trouble. I am not using any debugger, hence I cannot verify what is happening. My observation is that if display does not turn ON, by increasing or decreasing code size (just by adding or removing few dummy statements) will turn ON the display without really doing anything else in display related functions.
What I am trying to display is the value of PLL0STAT register to check the PLL status.
Here are few other functions through they may not be needed. These functions are tested and working fine. If there is a provision to attach the workspace here, I could have sent the entire source. But there are many functions and I am not sure if you people really want them.
void diaplayInRow1WithPosition(unsigned char* data, unsigned char position) { // The position cannot be more than 15. Display is 16 characters (0-15). if(position>15) { position = 15; } sendLCDCommand(0x80|position); // Change the DDRAM address to first line by // keeping D7 high and setting address to 0 onwards displayLCDString(data); }
void diaplayInRow2WithPosition(unsigned char* data, unsigned char position) { // The position cannot be more than 15. Display is 16 characters (0-15). if(position>15) { position = 15; } sendLCDCommand(0xC0|position); // Change the DDRAM address to second line by //keeping Bit D7 high and setting address at 0x40 onwards displayLCDString(data); }
Few more functions: // Function to convert lower nibble to ASCII Value //Only lower nibble of the input is considered and higher nibble is lost
unsigned char convertLowerNibbleToASCIIValue(unsigned char data) { data&=0x0F; if(data<=9) { return(data+0x30); } else // There is no chance for getting more than 0x0F in the lowerNibble Parameter) { return(data+0x37); } }
// Function to convert Higher nibble to ASCII Value //Only higher nibble of the input is considered and lower nibble is lost unsigned char convertHigherNibbleToASCIIValue(unsigned char data) { data>>=4; if(data<=9) { return(data+0x30); } else // There is no chance for getting more than 0x0F in the lowerNibble Parameter) { return(data+0x37); } }
You haven't responded to the note that you should not exit main().
There are no operating system that will return you to a command line prompt or to a GUI if the program exits. Exiting main() in an embedded device like this results in undefined behaviour. The program may restart again, and again, and again. Or it may find some random instructions to run. And the current state of the processor registers, or the size of the program, or contents from the previous version of the program may affect what will happen. That's the "nice" thing about something being undefined - you can't be expected to know what will happen. So you just should not exit main() but add an infinite loop at the end.
By the way - why do you use magic constants like 0x30 and 0x37?
Isn't it much better to add '0' if you want to get the ASCII value for 0..9? And you can add 'A'-10, if you want upper-case characters A..F or 'a'-10 to get lower-case characters.
Did you notice one more thing - you still haven't picked up on how to post source code, making it look like:
void mul_by_two(int a) { return a*2; }
The information is clearly there, if you just take the time to look.
Thanks for feedback on posting the code. Yeah, I did not notice
and <\pre>. I tried removing return from main. Even then behavior is not consistent.
Exiting main(), yes bad idea there, where do you think that goes?
int main(void) { //....your code while(1); //infinite loop for not existing main }