Bascom and AVR, Using an LCD.


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.

Detailed info on controlling HD44780 LCD's is on Peter Ouwehand's web-site.

Bascom has default settings for connecting the LCD. Do Options/Compiler/LCD:



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.

First LCD program.
Start Bascom, do File/New and enter the following program:
lcd.bas
$regfile = "2313def.dat"
$crystal = 4000000
$sim

Dim Count as Integer
Count = 0

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:



Click on the Run button (F5) and observe the LCD.
The Cls command in the loop initialises and erases the display. The initialisation is important. Always have a Cls command in the start-up section of your Bascom program if you use an LCD. If you forget, you may find that you can only address the first line of a two-line display. Also, after a controller reset, the LCD will still be as it was before the reset which is undesirable.
Now you can try the program out on the 'real-thing'. Remove the "$sim" line from the program source, recompile and send the bin-file to the AT90S2313 controller.

LCD character set.
The standard LCD character set is shown in the following table:



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)

LCD cursor control.
Bascom has several cursor control commands. You can switch the cursor on or off, have a blinking cursor:
Cursor on, blink
Cursor on, noblink
Cursor off
You may specify the exact position where the cursor has to be:
Locate linenumber, characternumber
Locate 1, 6
Lcd "Count"
will locate the cursor on the sixth position on the first line. The value of Count will be written, starting at that position.
The Home command will set the cursor to the first character position on the first line. Home is equivalent to Locate 1, 1. Home upper is also equivalent to Locate 1, 1. Home lower is equivalent to Locate 2, 1 when using a two-line LCD.
Shiftcursor left/right will shift the cursor left or right one place from its current position. Shiftlcd left/right will shift the entire text on the display one place to the left or right. Try the following program in the simulator or in the real (without $sim):
shifttext.bas
$regfile = "2313def.dat"
$crystal = 4000000
$sim

Dim Pos As Byte

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)

Define your own LCD characters.
LCD's with the HD44780 controller have room for eight extra characters which you can define. You could use you own special characters to:

- make a bar display for an S-meter or VU-meter
- a bouncing ball to while away the user's time while the controller is doing something time-consuming
- a rotating object or jumping man to let the user know the controller is still running

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)




Specify an exact LCD text layout.
Suppose we have an integer variable called loglevel with a value that can vary between -90 and +10. How this value is formatted on the LCD depends on the value of loglevel:
Loglevel = -2
Lcd Loglevel

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