128x64 ASCII Text Driver Design
This page shows the code required to display text characters on the 128×64 range of LCD modules. It consists of the driver part, which runs on the ATMega32 IC, and a Visual Basic program to generate the font data. The hardest thing here was to photograph the LCD module at an angle in the daylight.
The photograph above shows the kind of text clarity you can achieve with these types of displays. The contrast is quite good and it is very clear, but unfortunately, the camera has difficulty taking a picture of it due to the polariser layer that LCD panels usually have.
Project Files
The files for an ASCII text driver that enables one to display any text on the LCD can be found in the zip package below. I have made it as simple as possible for anyone to understand and follow.
Text Driver FilesDriver Code
1: /*-----------------------------------------
2:
3: My ASCII Character Driver
4: -------------------------
5: Reads the bitmap array of each character and
6: prints it to the LCD.
7:
8: Has End Of Line (EOL) feature.
9: This occurs when a character cannot fit at
10: the end of the line. It therefore prints to
11: the next line down.
12:
13:
14:
15: Functions:
16: setXY() to first set the position
17: where you want to print on the LCD.
18:
19:
20: Page and column variables are set
21: by setXY() and preserved for subsequent
22: calls by other functions.
23:
24: LIMITATION: Avoid printing a character that
25: overlaps column 64. However printing a space
26: there is ok. Most fonts normally manage to
27: avoid that line.
28:
29: --------------------------------------------*/
30:
31:
32: void lcd_writech(uint8_t ch) {
33:
34: // Make sure that the characters to print
35: // are within range as specified in the font
36: // bitmap file.If not then they are modified
37: // to the outermost limits.
38: if (ch < ASCIIL) ch = ASCIIL;
39: if (ch > ASCIIH) ch = ASCIIH;
40:
41:
42: // CHAR VALUE MUST BE AN INT AND NOT uint8_t
43: int base;
44:
45:
46:
47: uint8_t i, p, cmd;
48:
49: uint8_t tmppage=page;
50: // Temporary page counter.
51:
52: uint8_t tmpcol=column;
53: // This is to store the column value.
54:
55: uint8_t EOL;
56: EOL = column + CHAR_FW;
57:
58: // The array starts from 0 however the ASCII
59: // codes are specified by the user.
60:
61: // ASCIIL is specified by theuser through the
62: // Text to Data Array Converter Visual
63: // Basic program.
64: // This variable is defined when the font
65: // data is created.
66:
67: // CHAR_FW is the character width in bytes.
68:
69: // CHAR_PG is the number of pages
70: // the character occupies.This is the height
71: // of the character.
72:
73: // Base is the first byte of the
74: // character bitmap.
75: base = (ch - ASCIIL) * CHAR_PG * CHAR_FW;
76:
77: // Check the column position / space
78: // to make sure it can fit the whole
79: // character.
80: // If a whole character cannot be placed,
81: // then End Of Line (EOL) is called.
82:
83: if (EOL > 128){
84:
85: column = 0;
86: tmpcol = 0;
87:
88: cSelect(column);
89: // This selects the first half of
90: // the LCD and column 0.
91:
92: WriteCommand(SET_ADDRESS);
93: // This resets the column address.
94:
95: page = page + CHAR_PG;
96: // This increments to the next page.
97:
98: tmppage=page;
99: cmd = SET_PAGE | page;
100: WriteCommand(cmd);
101:
102: }
103:
104: for (p=0;p<CHAR_PG;p++){
105:
106: for(i = 0; i < CHAR_FW ;i++){
107:
108:
109: cSelect(tmpcol);
110: DataMode();
111: dPort = pgm_read_byte(&basicfont[base++]);
112: LocknLoad();
113:
114: tmpcol++;
115: }
116:
117: if(CHAR_PG>1){
118: // If the character occupies multiple
119: // pages then this part of the code
120: // comes into play.
121:
122: tmppage = tmppage + 1;
123:
124: cmd = SET_PAGE | tmppage;
125: // This sets the next page.
126: WriteCommand(cmd);
127:
128: cmd = SET_ADDRESS | column;
129: // This will reset the column number.
130:
131:
132: WriteCommand(cmd);
133: tmpcol = column;
134:
135: }
136:
137: }
Limitations
There is a slight limitation to this driver in that you cannot have a character overlap the 64th column; however, an empty space is fine.
Advantages
Most text drivers display text occupying a single page, which is a row of eight pixels. This means that your character is limited to eight pixels in height.
My Visual Basic extraction program will allow the creation of a font array for any height of text. It took ages to figure out how to do this and my solution is novel and unique. My driver can print characters that occupy multiple pages!
The parameter CHAR_PG lets the text driver know how many pages the text occupies, and the driver will behave accordingly to print the character. Please note that the ATMega32 has a limited memory capacity and will not be able to store the complete character set of a large font table. Adding expansion memory to the chip can easily solve this problem though.
This driver is also capable of working together with my setXY (x, y) function, to allow one to place text in any part of the screen.
This driver also has an End-of-Line (EOL) feature, so if you print a long string of text, which cannot fit at the end of the line, then the EOL functionality places the characters to the next logical row down from the first column.
Text to Data Array Converter
This program allows one to convert any windows system font to a data array compatible for display with the 128×64 displays. It generates the font data array and parameters for the text driver described above.
The Visual Basic extraction program generates font_data.h file, which also contains the defined variables used by the text driver program. Variables such as the ASCIIL and ASCIIH determine the range of the character set that the user has chosen for their project. To obtain the program please use the following link.
KS0108 Text to Array Converter Program
This Article Continues...
128x64 LCDProgramming the 128x64 LCD
KS0108 128x64 LCD Hardware Control
128x64 Timing and Modes
128x64 LCD Graphics Driver Design
128x64 ASCII Text Driver Design
128x64 Bar Graph