This short video will explain how to write software to drive an LCD.
There are two major types of LCDs:
segment LCD, and dot matrix LCD.
A segment LCD can only display English alphabet, Arabic numbers, and a few simple symbols.
A dot matrix LCD has pixels arranged in rows and columns.
Dot matrix LCDs are more flexible and can display more characters than segment LCDs.
However, segment LCDs are cheaper.
In this tutorial, we use segment LCDs as examples to illustrate how to develop software to control LCDs.
The key ideas are also applicable to dot matrix LCD.
An LCD module has four major components: LCD glass, LCD hardware signal generator, LCD
display memory, and software driver.
The hardware signal generator uses a special hardware technology, called a multiplexed
drive, to reduce the number of pins required to drive a LCD glass.
Refer to the book for details.
The LCD controller can be built in an external LCD module or in a microprocessor chip.
If the LCD controller is external to the processor, the processor uses some serial communication
interface to send a string to the controller.
If the LCD controller is on-chip, the microprocessor can directly drive an LCD glass, without any
extra hardware.
STM32L processors have on-chip LCD controller.
An external LCD controller has two major advantages over an on-chip controller.
First, an external controller typically requires much less processor pins.
Second, software to interface an external LCD is relatively simpler.
The advantage of having an on-chip LCD controller is that, the system can be made smaller and cheaper.
However, it uses many processor pins and requires complex software to drive the LCD.
In this tutorial, we focus on the on-chip LCD controller.
Let's focus on how to write software to drive the on-chip LCD controller on STM32L4
microprocessors.
The software driver takes two inputs: first, an Alphanumeric character, and second, the
target display position.
For example, we want to display the letter A, at the first position on the LCD
On computers, the letter A is represented by its ASCII value.
Software looks up the font library based on the ASCII value and finds the font of the Letter A.
Then, software modifies the LCD display memory, based on the font and the display position.
Specifically, software will set the bits to 1 in the display memory that controls the
on or off of the following segments: 1A, 1B, 1C, 1F, 1E, 1G, and 1M.
In summary, the LCD software driver has three tasks.
Task 1, define the font for alphabet letters and Arabic numbers.
Task 2, for a given character to be displayed, find its font by looking the font library
defined in Task 1.
Task 3, decode the font and modify the LCD display memory.
The font library is only needed to be defined once.
All characters share the same font library.
On the STM32L4 discovery kit, the LCD glass can display, six characters.
Each character has 16 segments, such as segment A, segment B, segment C, and etc.
Suppose we use 1 bit to represent the ON or OFF setting of each segment, we need a total
16 bits to encode all segment of a character.
Let's assume that we encode the segment in this order: G, B, M, E, F, A, C, D, Q, K,
and etc.
You may ask why we encode the binary ON or OFF information of these segments in this
specific order.
In fact, you can use any order you want, as long as you use the same order when you decode
the font.
Let's use the letter A as an example to show how to encode a letter
or a number.
In order to display the letter A, we need to turn on the following 7 segments:
A, B, C, F, E, G, and M. For each segment that needs to be turned on,
we set the corresponding bit to 1.
Otherwise, we clear the corresponding bit to 0.
This table shows the ON or OFF setting of all 16 segments.
If we convert the 16-bit binary encoding to hex, we will obtain FE00 in hex.
Therefore, the letter A is encoded as FE00.
We call this encoding as the font for letter A.
In the previous example, we encode the font of letter A as FE00 in hex.
Similarly, we can find the font for the remaining capital letters.
We put the fonts into an array.
We call this array as the font library.
Similarly, we can also find the fonts for numbers, as well as a few special symbols
that can be displayed on the 16-segment LCD, such as question mark, star, dash, and percentage
sign.
In the second task, we will explain how to find the font of a letter or a number by looking
up the corresponding array.
All strings are stored as an array of ASCII values in memory.
For a capital letter, the index of its font in the array of Letters is the difference
between the ASCII values of this letter and letter A.
For a lower-case letter, we simply convert it to the capital case, and find the corresponding font.
For a number, the index of its font in the array of Numbers is the difference between
the ASCII values of this number and number 0.
In task 3, the software driver needs to modify the display memory.
The first question we need to understand is that, to turn on a specific segment, which
bit should be set to 1 in the display memory.
Before we answer this question, let's take a look at the LCD glass.
The LCD glass has a total of 28 pins, including 24 segment pins and 4 com pins.
This table shows how each segment is controlled by the LCDs pins.
For example, Segment 2D, which means segment D at the 2nd display position is controlled
by LCD pin 3 and LCD pin 15.
LCD pin 3 is also called pin segment 2.
LCD Pin 15 is also called COM 1.
Now, let's take a look at the processor pins.
The STM32L4 processor on the discovery kit has a total of 100 pins.
Among these 100 pins, 49 pins are capable of driving an external LCD glass.
These pins can function from LCD SEG 0 to LCD SEG 43 or from LCD COM 0 to LCD COM 7.
The processor has an internal display memory.
Each bit in the display memory can turn on or turn off a LCD segment.
For example, bit 6 of LCD_RAM[1] controls the segment, which is connected to the processor's
pin segment 38 and COM 0.
The STM32L4 processor has 49 LCD pins, which have the alternate function of LCD.
The LCD glass has only 28 pins.
Therefore, when we design a circuit board, we need to think about which processor pins
should be used to drive the LCD.
The decision should be made carefully based on the overall needs of the whole systems,
because a processor pin can only perform a limited number of pre-defined alternate functions.
At the system design stage, we need to think about the overall pin assignment.
For example, we need to consider: how many serial ports we need, how many I2C ports we
need, how many GPIO pins we need, how many timer outputs or inputs we need, and etc.
System designer determines, which processor pins are selected to connect the LCD, and
what is the connection order between processor pins and LCD pins.
Once the hardware connection is made, software cannot change it.
On the STM32L4 discovery kit, the circuit designers have implemented the connections
as shown in this table.
For example, the processor pin PA 7 is connected to the LCD pin 1.
The processor pin PA 7 has the alternate function of LCD SEG 4.
This table presents put two pieces of information together.
The first piece is the connection between the processor pins and the LCD glass pins.
The second piece is the LCD's internal relationship between LCD pins and LCD segments.
Let's use LCD segment D on the second display position as example.
We call this segment 2D.
Here is the segment 2D.
This table shows that, in the LCD internal circuit, segment 2D is driven by two LCD pins:
LCD Pin 3, and LCD pin 15.
The table also shows that LCD's pin 3 is connected to the processor's pin PB1,
and LCD's pin 15 is connected to the processor's pin PA9.
This figure shows the connection diagram.
Pin 3 is connected to PA9.
Pin 15 is connected to PB1.
If we look at the reference manual of STM32L4 processors, we can find that the LCD alternate
function of the processor's pin PB1, is SEG 6. and the LCD alternate function of
the processor's pin PA9 is COM 1.
Therefore, we conclude that, LCD segment 2D is controlled by the bit for, SEG 6 of COM 1
in the display memory.
In the previous slide, we have found that LCD segment 2D is controlled by the bit for
SEG 6 of COM 1 in the display memory.
Now, let's take a look at the display memory again.
We can locate the bit in the display memory.
This display memory table is given in the STM32L4 reference manual.
Here, we locate the bit for SEG 6 of COM 1, which is bit 6 of LCD_RAM[2].
Therefore, LCD segment 2D is controlled by bit 6 of LCD_RAM[2].
In the previous slide, we locate the bit in the display memory, which controls LCD segment 2D.
Following the same procedure, we can find all bits in the processor's display memory,
which control all segments of the LCD.
Next, we will show you an example: how to write software program to show letter A
at the first position on the LCD.
In this table, we mark all bits that controls the segments of the first display position
in color.
To show letter A at the first position on the LCD, we need to turn on the
following 7 segments, including segment 1A, 1B, 1C, 1F, 1E, 1G, and, 1M, and turn off
all remaining segments of the first display position.
Therefore, we need to set all bits marked in red to 1, and reset all bits marked in blue to zero.
Here is the software code.
First, the code clears all bits that belongs to the first display position.
Then, software sets all bits marked in red in the display memory, including 1G, 1E, 1B,
1M, 1F, 1A, and 1C.
Here is the key idea of LCD driver.
Suppose the font is stored in the array C[4].
This example controls the display at the first position based on the font.
For a given font, we turn on or turn off each LCD segment based on the encoded on or off
information in the font.
Please read the book for details.
Now, let me show you one debug trick.
Suppose we want to display letter A at the first display position.
However, segment 1F is off by mistake.
How to quickly find the problem?
Let's take a look at the connection table.
We locate segment 1F in the table first.
Here is Segment 1F.
The table shows that segment 1F is controlled by processor's pin PA6 and PA9.
Therefore, the first to check the GPIO pin initialization has been performed correctly.
Specially, we need to make sure that the mode of pin PA 6 and PA 9 have been set to alternate
function, and their alternate function has been set to LCD.
Next, we need to check the display memory.
We need to check whether bit 3 of LCD_RAM[2] has been set to 1.
We can check this bit in the Keil debug IDE.
Please visit the book website for more tutorials, example code, and project templates.