Tag Archive for LCD display

Using Digole 12864ZW LCD with PIC18F

PIC18F interface with digole 12864ZW PIC18Fとグラフィック ディスプレイのインターフェイス facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Hello, こんにちは,


PIC18Fとグラフィック ディスプレイのインターフェイス

Digole 12864ZW is a 128×64 pixels graphic LCD that can be found at attractive prices and this is why it started appearing in projects across the web. It is based on ST7920 chip which is not so well known and to me it wasn’t the easiest to work with.



The documentation for this display can be found here. You can find a couple of examples on how to use this display and some attempts on making a library and most of this information is for interfacing with arduino. For PIC interfacing i couldn’t find much info.

The module has a 20 pin connection, each described below. Vout i havent used and left it unconnected. For contrast you can use V0 (pin 3) by connecting it to Vdd through a 10k variable resistor. However to get it to work you will need to enable jumper J1 from the back of the module as in figure 1.

Pin # Function
1 Vss
2 Vdd
3 V0
4 RS
5 RW
6 EN
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 PSB
16 NC
17 RST
19 BLA
20 BLK
Digole 12864ZW PIC18F contrast

Figure 1

As per the datasheet the display can be used in many ways and this is a strong feature. I used it the traditional way 8 bits parallel. For this, PSB pin must be connected to Vdd, i also connected RST pin to Vdd as i will reset the display in software. The rest of the connections are the same as with any 16×2 alphanumeric displays.


Microchip XLCD library is a great starting point to using the Digole 12864ZW with a PIC microcontroller. I used Application Maestro to set up the library. As mentioned we will use 8 bits interface in delay mode. Set the ports and pins and the rest doesn’t really matter.


Application Maestro XLCD

Figure 2

Once done pressing Ctrl+G will generate the library files to be included in your project. You will need the XLCD.h, XLCD.c and XLCD.def. Now this Digole display can run in text mode with this library with major issues.To get to each line though you will need to go to specific addresses.

To use the LCD in graphic mode we will need to change the XLCDinit function in XLCD.c file. You can comment the one you have now and then copy paste the function below:


void XLCDInit(void)

XLCD_RSPIN_TRIS =0;                         
XLCD_RSPIN  =0;                             
XLCD_DATAPORT   = 0b00110000;   
XLCD_DATAPORT   = 0b00110000;   


The other two functions we will use from the XLCD library are XLCDCommand and XLCDPut, which are used to pass a command to the display and a value respectively. Using these functions you don’t have to worry about controlling RS , RW and EN.

After calling the XLCDinit() function in main() you have now setup the display in graphic mode. To start drawing you need first 2 XLCDCommand instructions that set the pixel address and then 2 XLCDPut instructions to draw the pixels.

In figure 3 you can see the address map of Digole 12864ZW in the operating mode described above. It can be observed the horizontally you cannot address pixels individually but in groups of 16 and values you can write in groups of 8. The 1st byte represents the byte in the first XLCDPut instruction and the 2nd byte the value in the 2nd instruction. You cannot make 1 byte to start at the middle of the address location. We have 8 addresses of 16 pixels each horizontally 8×16=128 pixels and 64 lines =>128×64 resolution.


Digole 12864 Address Map アドレスマップ

Figure 3


/* In figure 3 there are 4 red pixels. To set the pixel we need the following instructions:

Note that we are in region where x=0 => */

XLCDCommand(0b10010010); // 1st instruction

XLCDCommand(0b10000001); // 2nd instruction

XLCDPut(0b00110001); // 1st byte, red pixels are 1 in value

XLCDPut(0b00000010); // 2nd byte, red pixel is 1 in value

/* As you can see the position of the pixels in the two bytes are the positions of 1 in the XLCDPut values */

So to draw a horizontal line of a specific length you will need to take in consideration the fact that you will always set all 16 bits in one of the 8 horizontal addresses.

//Example: Draw line from pixel 41 to end of screen at line 10

/* x = 41/16 = 2; x_r = 41%16 = 9; This means we will start the line from the 2nd byte of horizontal address 010. y = 10 => H_ADDRESS = 0b10000010 */

// lets draw the first part of line 

int index_x, index_y, i;

index_y = 10;

index_x = 41/16;

XLCDCommand(0x80 | index_y); // V_ADDRESS

XLCDCommand(0x80 | index_x); //H_ADDRESS

XLCDPut(0x00); //1st byte is zero

XLCDPut(0x7F); //x_r%8 = 1 => values is 0xFF >> 1 meaning 0b01111111

//now draw to end of screen



XLCDCommand(0x80 | index_y);

XLCDCommand(0x80 | i);




Another good reason to use graphic mode is to create your own fonts for text. In its own text mode the display’s characters are very large and can only fit 4 lines. I have created my own set of characters of 7×7 pixels. I have used the fact that each horizontal address has two bytes so that i can fit a character’s width in one byte and leave 1 empty pixel as space. In Figure 4 you can see the W character and its pixel representation. It uses 1 byte on 7 lines so 7 bytes.


Character map DIgole 12864 display

Figure 4

This way each character can be represented as a vector of 7 bytes:

int chW[7]={ 146, 146, 146, 146, 146, 170, 68 };

To display a string i separate each character and based on its value i fill a matrix of [7][8] dimension representing a text line on the display. To use it easily the matrix is declared as follows:

union writebyte
char LowByte;
char HighByte;


This way you can easily call XLCDPut functions with LowByte or HighByte as arguments. Here is the case for W within the character switch function:

case ‘w':
if(k%2 == 0)

where j is the line number and k is the character number. Below you can see how it looks like:

 PIC18Fとグラフィック ディスプレイのインターフェイス

 PIC18Fとグラフィック ディスプレイのインターフェイス interfacing PIC18F with Digole 12864ZW

 PIC18Fとグラフィック ディスプレイのインターフェイス interfacing PIC18F with Digole 12864ZW


In the zip archive below you can find the font.h containing definitions for characters seen above and an example code for PIC18F4620 that displays the message stored in msg[] variable.

I will add more characters and functions with time but i hope this was helpful for anyone trying to interface Digole 12864ZW LCD to a PIC18F.


Digole 12864W sample code for PIC18F4620

Thank you for visiting,


Using Software SPI with TFT Touchscreen

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather


In the previous article i wrote how you could implement a software SPI communication. These days i tried this solution with a TFT touchscreen using TSC2046 driver. This will also work for ADS7843 driver.

Basically you will need to call the Get_Value_SSPI function described in the previous article. As argument if we look in datasheet of TSC2046 or ADS7843 we see we need 0xD0 for x values and 0x90 for y values.


UINT16 TS_X, TS_y;

int x,y;

TS_X = Get_Value_SSPI(0xD0);

TS_Y = Get_Value_SSPI(0x90);

/* TS_X, TS_Y hold the ADC values from the touchscreen driver we need to convert them to coordinates. I cut last two digits as i dont need high precision and then scaled the values to correspond to a 800×480 TFT */



I recorded a video of how it works, hope you enjoy it:

Thank you for visiting.