Saturday 6 May 2017

First steps with stm32l152. SPI handling with LCD 5110 display.


One of the most interesting parts of embedded programming is a work with graphic displays. Some of them are easy to manage, others require special tricks. The objective of this post is to show how to use the simplest and famous display – Nokia 5110 LCD. Also, it will be demonstrated how to use SPI in an unidirectional master mode.

Nokia 5110 LCD Display.


The display is based on PCD8544 low-power CMOS LCD controller-driver, which allows to drive a graphic display of 48 rows and 84 columns. It communicates with a microcontroller via a serial bus interface.
Our displays has the following pins:
1. VCC – is an applied voltage, should be less than 7 V. In this example it will be 3 V.
2. GND – ground pin, goes to Groung pin of our board.
3. SCE is a low active signal (low values of a signal treated as logic 1) which enables serial interface.
4. RST – reset pin. Resets the device and must be applied to properly initialize the chip.
5. D/C – data/command pin. When D/C is high, signal on MOSI treated as data, in other case – as a command.
6. DN (MOSI) – SPI data bus (Master In Slave Out). Through vis bus we should send commans and data to out display.
7. SCLK – input for the clock signal, should be between 0 and 4 Mbits/s.
8. LED – led input. Voltage should be less than 10 V, and the current - no more than 20 mA. We won't use it in our example, but in order to use it 330R resistor should be placed before the input to protect the leds.

It is worth to mention here that spi works in Mode 3 (and probably Mode 0)  - CPOL=1 and CPHA=1, SCLK is active low (high when inactive). MSB first mode.


Initialization.


In order to work properly the display should be initialized.  I have used the following consequence of steps:
1. First of all, Reset impulse should be sent. Its width should me more than 100 ns;
2. Chip enable via setting SCE to zero;
3. Switch to the command mode D/C => 0;
4. Send 0x21 to switch to the Command Set in addition mode;
5. Set up a Bias System via sending 0x15 value (it can vary);
6. Set up a Temperature Coefficient, I send 0x07;
7. Set up a Voltage VOP, I use 0xB8 value;
8. Send 0x20 to set a Command Set in Basic mode;
9. Send 0x0C for setting LCD to display results in the Normal Mode.
After that we can switch to the data mode via setting D/C to 1.

Sending commands and data.


The most frequently used command is a "set position" command. To set position we should:
1. Switch to the command mode;
1a (optional) Switch to preferred addresing mode;
2. Send position X and Y bytes;
3. Switch to the data mode.
There are two addressing modes: vertical and horizontal. I use a horizontal addressing mode, thus, I have 84 columns and 6 rows (each row is eight bit in height). In order to set position we should send byteX = 0x80 + x and byteY = 0x40 + y.

To send the data we should:
1. Switch to data mode;
2. Send a byte of data.
The byte represents eight pixels in a column (or in a row if you use a vertical addressing mode). Thus, if you want to display 'a' symbol, you should send the following sequence: 
0x00, 0x20, 0x54, 0x54, 0x54, 0x78 and it would be transformed into:



Connecting to the board.


To establish connection with the board we should generate a proper code. For this purpose I configured my board in this way:



Please, make sure that you have configured SPI with the right mode and speed (it should be lower than 4 Mbits/s).


After that, I connect my board to the display in the following way:
1. VCC ---> EXT_V3
2. GND --->GND
3. SCE ---> PA12
4. RST ---> PA10
5. D/C ---> PA11
6. DN (MOSI) ---> PC12
7. SCLK ---> PC10
8. LED ---x

To work with the chip a have written a small library: 
lcd5110_library
In order to utilize it we should fill the display structure:

  display_5110 disp = {
      .buf = NULL,
      .hspi = &hspi3,
      .RESET_BASE = GPIOA,
      .RESET_PIN = GPIO_PIN_10,
      .COM_DAT_BASE = GPIOA,
      .COM_DAT_PIN = GPIO_PIN_11,
      .SCE_BASE = GPIOA,
      .SCE_PIN = GPIO_PIN_12
  };

and use it with all library functions:

    init_display(&disp);
    clear_display(&disp);
    uint8_t byte;
    set_position(&disp, 0, 1);
    print_string(&disp, "Hello World!", 12);
    set_position(&disp, 10, 2);
    print_string(&disp, "From", 4);
    set_position(&disp, 0, 3);
    print_string(&disp, "Embedded Den", 12);

after this code is ran we have the following picture:

Thus, in this blog entry we have figured out how to deal with the famous LCD 5110 display form stm32l152-discovery board via SPI.

References:
LCD 5110 First manual
ETT Nokia LCD 5110

No comments:

Post a Comment