This tutorial shows you how to display string, color and dynamic value on LCD with STM32F4 development board
This tutorial shows you how to display string, color and dynamic value on LCD with STM32-Nucleo development board from ground up. It will also show you how to read the technical datasheet of LCD. If you are interested in more advance topic of RTOS from scratch, please go to Real-Time Operating Systems tutorial.
Let's first take a look what are we going to achieve after this tutorial.
1.1 Hardware
1.2 Documents
You are ready to go!!
A series of Youtube tutorial on STM32-Nucleo is a good start if you never use this link
You can think of it as a tiny and simplify PC without monitor(output), keyboard(input), and mouse(input). The LCD acts as output and the Potentiometer acts as input in our tutorial. There is a big problem, how can this tiny PC communicate with the outside world (such as monitor or keyboard)? Some use wired or wireless.
Wired/Wireless | Example |
---|---|
Wired | SPI, I2C, UART, Ethernet |
Wireless | Wi-Fi, Bluetooth, Cellular |
In this tutorial, we will use SPI (Serial Peripheral Interface) to communicate with the output device ~ LCD. We call our Nucleo board as master and the LCD as slave because we are sending order and command to the LCD. Sparkfun has a great tutorial website about SPI (link). The image in the following shows the relationship and connection between master and slave.(image from Sparkfun with some modification to fit our case)
Some basic term of SPI and their function are shown in the below table.
Terminology | Function |
---|---|
MOSI | Master out Slave in. Master sends command or data to Slave. |
MISO | Master in Slave out. Slave sends command or data to Master. We don't use this in our case. We don't need to get data from the LCD. (If you use touchscreen, you would need this function) |
SS (CS) | Slave select (or Chip select). If you have multiple slaves connectes to one master, you can use SS to communicate with the specified slave. Eventhough we only have one slave (LCD), we still need to use this Slave select to let the LCD knows we want to talk to him now. |
SCK (CLK) | Clock. Because SPI is synchronous, it requires clock for sampling. |
We want to display some string or color on the specific location of the LCD. We can achieve this by sending data to the specific address of RAM (Memory) in the LCD board. This is call Memory to Display Address Mapping. Take the image below for example. We want to make the top left corner of the LCD display a yellow square. First, you need to let the LCD knows at where of the RAM are you going to write the data to (using X_start, X_end, Y_start, Y_end value). Then you can start writing the data (color information) to those address of the RAM. Then, the specified portion of LCD will change it's color according to the value you wirte into the address in the RAM. (Please refer to the ST7735s datasheet page 59 ~ 72)
Let's take a look the back side of the LCD board in the following image. You only need to focus on the left side.
The following table shows each pinout of the LCD board and its function.
Pinout on LCD | Function |
---|---|
VCC | Power 3.3V ~ 5V |
GND | Connect to ground |
NC | No need to connect |
CLK | Clock. Also call SCK |
SDA | MOSI for receiving data from the master |
RS | Data/Command selection. (some LCD board calls it DC or D/C). When applying high voltage meaning sending data while applying low voltage meaning sending command. |
RST | Reset (reset at low level) |
CS | Chip selection (some LCD calls it SS) |
We will talk about how to connect these two devices by wires later. Let's see the protocol when communicating to the LCD board. First look at the graphic explanation below.
Connection Pin | Explanation |
---|---|
CS | Only at the falling edge on CS (voltage become low) enables the SPI and indicates the start of data or command transmission. When the CS is high (voltage is high), the clock is ignored. |
Data or Command | Data: You use the high voltage from the GPIO pin to tell the LCD board that you are transmitting the data. Command: You use the low voltage from the GPIO pin to tell the LCD board that you are transmitting the command. (Please refer to the ST7735s datasheet page 36 ~ 51) |
MOSI | While sending a command, it's not necessary to send data. How many data right after the command is defined by the command. (Please refer to the ST7735s datasheet page 104 ~ 186) In our code, our SPI transmit 8-bit data at a time, however, the color in our case is defined in 16-bit, so you need to transfer the first 8 bit of the color and then the rest 8 bit. (Please refer to the ST7735s datasheet page 44 ~ 58) |
Clock | MOSI data is sampled at the rising edge of clock |
In the following, we will first use CubeMX (link) to configure SPI and ADC (optional) on the STM32-Nucleo board and then generate code for keil µVision IDE v5 (link). Secondly, copy paste the code from the program we provided. Finally, we will test the code on the hardware.
Click File --> New Project --> In the search, key in your board model (STM32f411RE in our case) --> Click on the NUCLEO-F411RE --> Double click the item --> Click Yes to initialize all peripherals with their default Mode. --> Clear all Pinout.
Categories | Configure |
---|---|
SPI | On the left panel, click Connectivity --> SPI1 --> Select Mode : Transmit Only Master --> Prescaler(for Baud Rate): 32. On the Pinout view, we will change the pin. Click on PB5 --> Select SPI1_MOSI. Click on PB3 --> Select SPI1_SCK. |
ADC (Optional) | On the left panel, click Analog --> ADC1 --> Select Mode: IN4. |
GPIO | The following will set the pins in Pinout view to GPIO_Output CS: Click PB15 --> Select GPIO_Output --> Right click to enter user label: LCD_CS RS: Click PB14 --> Select GPIO_Output --> Right click to enter user label: LCD_RS RST: Click PB12 --> Select GPIO_Output --> Right click to enter user label: LCD_RST |
The configuration process and the result view will be the following. On the top of the panel, click on Project Manager.
You may wonder what pin of SPI should I use (you see we change the pin from the default PA5~7). Actually, ARM Cortex-M4 defined the combination of pins with SPI, I2C, UART. You can check the table from the STM32F411RE User Manual page 47 ~ 52. In the table, you can see we are using the combination of PB3/PB5, that combination also legit.
Before we get started, we need to configure the package. Make sure all the package are installed and up to date shown in the following image
Then, we will configure the dubgger. Nucleo-64 board uses ST-LINK (the upper part of the board which you connect the mini usb to).
Click Flash tab --> Configure flash tools
let's check whether the generated code are correct by clicking Project tab --> Rebuild all target files. It should be 0 Error and 0 Warning. In the Project, you should see all the file in the following image.
Now we add something in the main.c file so that we can use st7735.c and st7735.h for our project.
Please refer to the following image to connect those devices.
If everything is working good, we can keep going on.
void plotData(void)
{
ST7735_PlotPoint(sensorValue,ST7735_GREEN);
ST7735_PlotIncrement();
}
void drawInfoBar(void)
{
ST7735_DrawString(1, 0, "CPU =", ST7735_GREEN);
ST7735_DrawString(7, 0, "75%", ST7735_BLUE );
ST7735_DrawString(11, 0, "Temp =", ST7735_GREEN);
ST7735_DrawString(18, 0, "30", ST7735_BLUE );
}
void drawaxes(void){
ST7735_Drawaxes(AXISCOLOR, BGCOLOR, "Time", "ADC", LIGHTCOLOR, "", 0, YMAX, YMIN);
}
Add the three header on the top of the main.c file
void drawInfoBar(void);
void drawaxes(void);
void plotData(void);
int main(void)
{
HAL_Init();
//SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_SPI1_Init();
ST7735_Init();
ST7735_FillScreen(ST7735_BLACK);
drawaxes();
drawInfoBar();
while (1)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,1);
sensorValue = HAL_ADC_GetValue(&hadc1);
plotData();
}
}
Before starting to display anything on the LCD, we need to initialize and configure the LCD by sending some command and parameters (data) to the LCD board. This initialization only need to be processed once. After that, we can send data to the LCD with correct protocol.
Let's make the uper left corner of the LCD become green. In the following sending command as well as sending data, we all communicate via SPI. Remember that before sending data, we need to set the RS (Data or command) pin high. We set the RS pin low before sending command.
The reason of making this tutorial is that the code provided from instructor of the Udemy course is not working at all and the instructor didn't reply to any student at all. I start from knowing nothing about SPI no need to say the LCD board. After 5 days of research, reading documentation, and trial and error, I finally make it works. This tutorial is to guide those people who want to get a deep knowledge of making a driver to display on LCD.