Bascom and AVR, Using An LCD.: Peter Ouwehand's
Bascom and AVR, Using An LCD.: Peter Ouwehand's
Bascom can handle the two main types of liquid-crystal displays: alphanumeric and graphic.
For the time being we will concern ourselves with the most common alphanumeric type. This
type of LCD can display characters, numbers and special characters. The most common type
of alphanumeric LCD uses a Hitachi HD44780 as display controller. When you are uncertain
about what type of display you are holding in your hands, simply look at the chip
designations on the back. If one of these says HD44780 you're safe.
Fortunately, the default is set to LCD type 16*2. This is the most common LCD with two
lines and 16 characters per line.
HD44780 type LCD's have eight datalines, but they can be controlled in a more economical
way by using the four 'upper' lines. This saves four i/o pins on your controller. This is the
default (4-bit bus mode) in the options window. Sending data in the 4-bit bus mode of course
takes two writes for each 8-bits to send. If you really need the LCD to be as fast as possible
(and you seldom do) you will have to choose the 8-bit bus mode.
Data mode is default 'pin'. This means that individual pins can be selected for each LCD pin.
This option gives the most flexibility in choosing the i/o configuration of your controller. The
'bus' option can be used in the classic microprocessor bus setup where a lot of i/o is attached
to one bus and address decoding must be used to address each separate device on the bus. The
LCD-address and RS-address items can be used if you use the 'bus' option.
In the 'pin' option, you can specify how the six LCD pins are connected to your controller.
The Enable pin is used by the LCD to see if it has to read/write data on the four i/o pins. As
long as the Enable pin is low, the LCD will not 'listen' to any changes on the four data pins
(so they can also be used for other purposes; on the AT90S2313 they are also used for the
MOSI, MISO and CLK). Data on the four data pins is read when RS goes from high to low.
The RS pin is used to let the LCD know if the data that is on the four data pins has to do with
a character to display or with a command such as a display reset or a cursor change.
The LCD has a seventh pin called R/W to tell the LCD if we want to Read data from or Write
data to the LCD. Bascom assumes that this pin is permanently connected to Ground, so that
the LCD is always in Read mode. However, to see if the LCD is ready to receive data, we
should read the 'busy' flag. This would involve sending a 'give busy flag' command, switching
the LCD to write mode, reading the byte value of the busy flag register, and determining the
value of the busy bit. As we cannot do that, Bascom must use wait loops after each write. The
wait loops are determined by the clock speed. That is amongst other things why the
specification of the clock speed in the Options/Compiler/Communication window or with the
$crystal keyword is important. Note that if you specified a 4MHz clock and later change the
crystal into a 10MHz model, the controller will run 2.5 times as fast, but the LCD wait loops
are probably too short. This may result in the LCD not working at all or 'acting strange'.
As with the specification of the controller type and crystal, the LCD pin connections can be
specified in the Bascom source instead of using Options/Compiler/LCD:
Config lcd = 16*2
Config lcdpin = PIN, DB4 =
PORTB.4,DB5=PORTB.5,DB6=PORTB.6,DB7=PORTB.7,E=PORTB.3,RS=PORTB.2
Config lcdmode = PORT
The LCD is connected to the controller as follows:
The standard alphanumeric LCD has 14 pins. Pin number 1 is Ground. Pin number 5 is R/W
and is also connected to Ground. Pin number 2 is Vcc, goes to +5V. Some LCD's will not
tolerate a power-supply with a slow rising output voltage. If in doubt, check the LCD
datasheet.
Pin number 3 is for LCD contrast. With most displays you can connect the contrast pin to
Ground. For optimum contrast on some displays you need a slightly positive voltage on this
pin. Using a potentiometer between +5V and Ground should give an optimum setting for
most displays. I have encountered displays that need a >>negative<< voltage on the contrast
pin. In that case connect the potentiometer between Ground and a negative, say -10V, voltage
source.
I recently bought a so-called PLED LCD display. This type of display is based on an entirely
different principle. It uses a layer of light-emitting polymer so it does not need a backlight. A
such, it has lower power consumption and much better contrast. The PLED display I used
was completely compatible with a HD44780 LCD, but pin 3 needed a voltage between 1.8
and 5 Volts to regulate the LED brightness. Read more on PLED's at the inventor's web-site.
The pin numbers 4 (RS), 6 (E) and 11, 12, 13 and 14 are connected to the controller as shown
in the schematic. Pin numbers 7, 8, 9 and 10 can be left unconnected. Note that D5, D6 and
D7 are shared with MOSI, MISO and SCK.
If you have an LCD with LED-backlight you may have a 16-pin header on the LCD PCB.
Pins 15 and 16 are for the backlight. If these pins have no further indications, try a +5V
supply with a current-limiting resistor of a few hundred ohms to find out what the cathode
and anode pins are. Sometimes the LED-backlight has a connector separate from the other 14
pins.
Do
Cls
Lcd "Hello! " ; Count
Count = Count + 1
Wait 1
Loop
End
Do Compile and Simulate (F2). (Read more on the Simulator first, if you need to) Click on
the first variable cell and enter: "Count". Click on the LCD button to show the hardware
simulation window. Click on the "Step into Code" (F8) to step through the loop. After the line
"Lcd "Hello! " ; Count", the LCD should show:
The 'special characters in this table can be sent to the display by using the decimal
charactercode. For example, use:
Lcd Chr(228)
to send the symbol. (1110.0100 binary is 228 decimal)
Do
Cls
Upperline
Lcd "012345678901john"
Lowerline
Lcd "0123456789012ike"
For Pos = 0 To 16 Step 1
Waitms 500
Shiftlcd Left
Next Pos
Loop
End
If you run this example in the simulator you will notice how the text on both lines will scroll
to the left. (it would be nice if Bascom could scroll the text from the lower line to the upper
line as well)
You can make your own characters in Bascom in Tools/LCD Designer. Do File/New and
enter the following program text:
$regfile = "2313def.dat"
$crystal = 4000000
$sim
Config Portd = Output
Dim Star As Byte
Cursor Off
Cls
Do
For Star = 0 To 5 Step 1
Portd = 255
Waitms 100
Portd = 0
Waitms 100
Locate 1 , 16
Lcd Chr(star)
Next Star
Loop
End
Place the text editor cursor on the second empty line after "Cursor Off". Start Tools/LCD
Designer:
Clink one on a square to make it black, click on a black square to make it white again. Make
a cross symbol:
Click on OK. In the Bascom program source window, at the cursor position the following text
line appears:
Deflcdchar ?,32,4,4,31,4,4,32,32' replace ? with number (0-7)
Change the '?' into the number '0' and remove the comment after the "'" character":
Deflcdchar 0,32,4,4,31,4,4,32,32
Move the text cursor to the next empty line, redo Tools/LCD Designer an make the following
drawing:
Click on Ok, the text line:
Deflcdchar ?,32,4,4,31,4,4,32,32' replace ? with number (0-7)
appears. Change the '?' into the number 1 and remove the comment:
Deflcdchar 1,32,4,4,31,4,4,32,32
Repeat this process another four times (use your imagination) until your program looks like
this:
star.bas
$regfile = "2313def.dat"
$crystal = 4000000
$sim
Config Portd = Output
Dim Star As Byte
Cursor Off
Deflcdchar 0 , 32 , 4 , 4 , 31 , 4 , 4 , 32 , 32
Deflcdchar 1 , 32 , 2 , 20 , 14 , 5 , 8 , 32 , 32
Deflcdchar 2 , 32 , 2 , 26 , 4 , 11 , 8 , 32 , 32
Deflcdchar 3 , 32 , 17 , 10 , 4 , 10 , 17 , 32 , 32
Deflcdchar 4 , 32 , 8 , 11 , 4 , 26 , 2 , 32 , 32
Deflcdchar 5 , 32 , 8 , 5 , 14 , 20 , 2 , 32 , 32
Cls
Do
For Star = 0 To 5 Step 1
Portd = 255
Waitms 100
Portd = 0
Waitms 100
Locate 1 , 16
Lcd Chr(star)
Next Star
Loop
End
Compile and Simulate. The result is a fast rotating star in the rightmost position of the first
LCD line:
Another variant is a jumping man, which uses only two images:
(jman.bas)
or a moving bar:
(mbar.bas)
Loglevel = 34
Lcd Loglevel
Loglevel = 7
Lcd Loglevel
If the value of Loglevel varies, the position of the corresponding number on the LCD may
also vary. This may make reading the LCD more difficult. A solution would be to reserve a
fixed amount of character positions on the LCD for the display of the Loglevel value using
the Format command:
lcdformat.bas
$regfile = "2313def.dat"
$crystal = 4000000
$sim
Dim Loglevel As Integer
Dim Loglevelstr As String * 5
Dim Loglevelstrformat As String * 5
Cls
Loglevel = -2
Loglevelstr = Str(loglevel)
Loglevelstrformat = Format(loglevelstr , "+00")
Lcd Loglevelstrformat ; " dBm"
End
TOC