# ADC 0.6 output is not displayed in LCD For ARM LPC2148

#### PonDinesh006

##### Newbie
I Have used ARM NXP LPC2148 for ADC Operation.
The code is used is run KEIL Software debug option. But, It doesn't show the output value in LCD screen in Proteus Simulation.

I hereby attaching my code and Simulation Files.

can anyone help this for error...

#### Attachments

60.4 KB · Views: 2

Solution
Hello!

I forgot an important aspect of using timers:
- You don't need the processor to work in an empty loop, and you will save power.
- You will have this processing power for other tasks.
Addendum (maybe the most important one):
- Using a timer is the only way to make an accurate timing.

One example: suppose that in your program, you have a loop (like in any average
arduino stuff). Suppose you want to create a watch (you need accurate timing).
You might think you can do (pseudo-code)

Code:
loop() {
write_time_on_lcd();
delay(d);
}

As the time it takes to write the LCD is constant, if you tune the d parameter carefully,
you might make a clock that has roughly the accuracy of its crystal (50 ppm in most...

#### doraemon

##### Super Moderator
Staff member
Hello!

Then some remarks:
1. Your code is unreadable. For instance, cmd(0x38)-> What does it do?
You could consider (assuming it's a plain character display)
#define CLEAR 0x01
#define HOME 0x02
and similar definitions for all your commands. And never hard-code commands
like cmd(0x38), but rather cmd(SET_LINE | CURSOR_OFF);

2. You have made a .h file which contains implementation. A h file should
never contain any implementation. Well, inline function can be in a header file,
but that's something else.
In other words, you should have one lcd.h where you have all your function
prototypes. In your case, lcd.h would be:
Code:
void lcd_init(void);
void cmd(unsigned char a);
void dat(unsigned char b);
void show(unsigned char *s);
void lcd_delay(void);
And lcd.c which would have the implementation (the definition of each function).

So if you could write your code in a better way, I'm sure it would be easier
to help.

Dora.

Last edited:

#### PonDinesh006

##### Newbie

I will correct my mistakes and update the changes.

I have Wrongly did the LCD program, But is ADC function,

"sprintf(volt, "Voltage=%.2f V ", voltage);"

is not working for float value in KEIL Version 4 ,

What can do for this, I didn't receive any error for this, But not printing in LCD only Blank and program is not running after this line.

#### PonDinesh006

##### Newbie
I have Updated my code for LCD.

I have used 4 bit LCD. This code work fines with the LCD for Printing Character and string.

In my ADC Code, This condition is not working for AND operation

"while ( !(AD0DR1 & 0x80000000) );"

but in KEIL debug method it works fine,

But, In Simulation it doesn't satisfy the condition and not displaying the value.

I hereby attaching my new code with simulation file also. Anyone Clear my doubt..

#### Attachments

131.1 KB · Views: 2

#### doraemon

##### Super Moderator
Staff member
Hello!

But, In Simulation it doesn't satisfy the condition and not displaying the value.

It depends on what your simulator does, but from my experience, especially for low cost
processors, the simulator is often a very simple program that allows to simulate the processor core.
As it has no peripheral like an ADC, there is no way to get either an interrupt or a flag and it will
wait forever. So your program is possibly fine and it's better to work with the real processor.

Beside this, a general remark: you should learn about interruptions.
You have written a function waiting for n milliseconds. But if you go through a function like
this, your processor will just spend power pedaling for nothing. That wouldn't be a problem if
it didn't prevent the processor from doing anything else. Instead of this, you should consider programming
a timer and use this timer interrupt.
- You don't need the processor to work in an empty loop, and you will save power.
- You will have this processing power for other tasks.

Next. I adviced to make a lcd.h and lcd.c files. But you have written everything in the main file.
The result is a risk that you modify a lcd function that already works. If you keep the lcd in a separate
file.h file.c pair, then there is low risk of breaking what works.

Another point. Your code is better than last time becaust it has comments. However it's still full
of obscure and cryptic functions.
Example:
Code:
    IO1SET |= 0x00400000; /* EN = 1 */
IO1CLR |= 0x01800000; /* RS = 0, RW = 0 */

Why wouldn't you use #defines instead of these hard-coded numbers?
In your lcd.h, you would write:
#define LCD_ENABLE 0x04000000
#define LCD_RS 0x01000000
#define LCD_RW 0x00800000

NB: I haven't checked which is RW and which is RS. Please check the documentation,
it might be inverted.

And then your code would become:
Code:
    IO1SET |= LCD_ENABLE;
IO1CLR |= LCD_RS | LCD_RW;

- The code is self explanatory, you don't even need to explain what you do.
- If you have to reuse the code on another hardware, you can just modify the #define.

Dora

Last edited:

#### KlausST

##### Super Moderator
Staff member
Hi,

I fully agree with Dora.

You need to do programming in small steps:
Write a little piece of code, then test it. Correct it if necessary. Comment it.
Then write the next little piece of code.

Don´t try to write a whole application at once and hope that it will run from the beginning.

Klaus

#### doraemon

##### Super Moderator
Staff member
Hello!

I forgot an important aspect of using timers:
- You don't need the processor to work in an empty loop, and you will save power.
- You will have this processing power for other tasks.
Addendum (maybe the most important one):
- Using a timer is the only way to make an accurate timing.

One example: suppose that in your program, you have a loop (like in any average
arduino stuff). Suppose you want to create a watch (you need accurate timing).
You might think you can do (pseudo-code)

Code:
loop() {
write_time_on_lcd();
delay(d);
}

As the time it takes to write the LCD is constant, if you tune the d parameter carefully,
you might make a clock that has roughly the accuracy of its crystal (50 ppm in most of
the low cost crystals).
Now suppose that you have a 4 lines LCD, and you want to make some calendar
functionality with alarm 10 minutes before, with a beep, one one information line on the
LCD, etc...
In this case, the code will look like this:

Code:
loop() {
write_time_on_lcd();
calendar();
beep_if_needed();
delay(d);
}

The problem: calendar will do nothing most of the time. You could of course set d as a
variable with one value when it has nothing else to do and another when it does.

But the really efficient and close to no effort code would be this:

Code:
setup() {
set_timer_interrupt(100ms);
}

loop() {
// The loop does nothing
}

interrupt_routine {
write_time_on_lcd();
calendar();
beep_if_needed();
}

Doing this way, you will have an accurate timing whatever you do in the processing part.

Remarks:
- You can setup any value for the timer interval. 100 ms is more than enough
for a clock, 1 second or even 1 minute is also fine, depending on what you want to do.
On the low timer side, you have to make sure that you can do all your process within
this time.
- Writing all the code in the interrupt routing is also bad practice, but for simple
projects it would still be better than a spinning delay.

Dora.

Last edited:

#### PonDinesh006

##### Newbie
Thank you Dora Mam,

I will change coding file for better understanding.

#### PonDinesh006

##### Newbie
For my code,
It doesn't run in Proteus 8.12
But it works in Proteus 7.5

Can I know the difference about it's functions.
Please enlighten why it is not working for 8.12 whereas it works for 7.5 .

#### doraemon

##### Super Moderator
Staff member
Hello!

But it works in Proteus 7.5

Why not using 7.5 then? Are there features in 8.12 that you absolutely need?
If you absolutely need to use some latest advanced features, that makes sense,
but I have the impression it's not the case.
It might make sense if you are working together with people who all use 8.12.
In this case, ask your colleagues how they managed to install it.

Regards,

Dora.