728x90

Showing posts with label Graphical LCD. Show all posts
Showing posts with label Graphical LCD. Show all posts

Sunday, February 8, 2026

ATMega32 TWI and SH1106 128x64 OLED Example

The SH1106 is a 132 X 64 Dot Matrix OLED/PLED Segment/Common Driver with Controller manufactured by SINO WEALTH. This chip is applicable for many low cost display. A low cost monochrome OLED display for Arduino is very popular among student and electronic hobbyists. It cost around 2USD. This chip has many communication interface depend on the display manufacturers, 8-bit 6800-series parallel interface, 8-bit 8080-series parallel interface, 3-wire & 4-wire serial peripheral interface, 400KHz fast I2C bus interface. However an SPI or an I2C OLED display module is common due complexity of wiring. An SPI display yield a high speed data transmission and reception compares to the I2C communication interface.

ATMega32 TWI and SH1106 128x64 OLED Example 

 

 ATMega32 TWI and SH1106 128x64 OLED Example

This display is easy to control via an 8-bit micro-controller especially the Arduino. The SSD1306 is its equivalent display controller manufactured by solomon-systech. It contains command and data similar to the old KS0108 display controller.

ATMega32 TWI and SH1106 128x64 OLED Example 


I bought a cheap SH1106 1.3" OLED display from a local electronics component store. It works fine at lower I2C frequency around 100kHz. At higher data rate it become halted. I already tested it with Arduino and PIC16F887 micro-controller. For more detail about configuration and display data sending to this display module please visit this post.

In this example I use my ATMega32 to display text on the SH1106 display. At this time I have problem with the ATMega644P TWI. So I use this smaller memory micro-controller.

Source Code:

  1. /*
  2. * 10-twi_sh1106.c
  3. *
  4. * Created: 2/7/2026 5:21:04 PM
  5. * Author : Admin
  6. */

  7. #define F_CPU 16000000UL
  8. #include <avr/io.h>
  9. #include <util/delay.h>

  10. void show_text(void){
  11. display_xy(0,0);
  12. display_text("ATMega32 SH1106");
  13. display_xy(0,1);
  14. display_text("TWI Programming");
  15. display_xy(0,2);
  16. display_text("Microchip Studio");
  17. display_xy(0,3);
  18. display_text("v.7.0.2542");
  19. display_xy(0,4);
  20. display_text("1.3 I2C OLED ");
  21. display_xy(0,5);
  22. display_text("Display Module");
  23. display_xy(0,6);
  24. display_text("AKI-Technical");
  25. display_xy(0,7);
  26. display_text("2026/02/08 Sun");
  27. }

  28. int main(void)
  29. {
  30. /* Replace with your application code */
  31. _delay_ms(1000);
  32. display_init();
  33. display_clear(0);
  34. show_text();
  35. _delay_ms(5000);
  36. display_clear(0);
  37. while (1)
  38. {
  39. display_clear(0);
  40. show_text();
  41. _delay_ms(2500);
  42. display_clear(0);
  43. _delay_ms(2500);
  44. display_clear(0xFF);
  45. _delay_ms(2500);
  46. display_clear(0);
  47. show_text();
  48. _delay_ms(2500);
  49. display_clear(0xAA);
  50. _delay_ms(2500);
  51. }
  52. }


I place its twi.c and oled.c libraries in different files. Click here to download its source file.

ATMega32 TWI and SH1106 128x64 OLED Example
Schematic and Simulation

 The ATMega32 run very well at 16MHz and high SCL frequency.

ATMega32 TWI and SH1106 128x64 OLED Example
ATMega32 AVR Prototype Board

 

This PCB was offered by PCBWay (pcbway.com).

I have been using PCBWay for many years now. PCBWay fabricate PCBs at low cost, fast processing time for only 24 hours, and fast delivery time using any carrier options. This double side 10cmx10cm can be fabricate at only 5USD for 5 to 10pcs by PCBWay. It's a standard PCB with silk screen and solder mask.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
10 PCBs for only 5USD
 

For different size of PCB we can instantly quote on PCBWay website using a zip PCB Gerber file without account.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
PCBWay Instant Quote

 Now I create a bigger fonts function to make displaying text more visible.

  1. void display_char_8x16(unsigned char x, unsigned char y, char ch){
  2. y=y*2;
  3. display_xy(x,y);
  4. uint16_t temp;
  5. ch=ch-32;
  6. temp=ch*16;
  7. char i=0;
  8. for(i=0;i<8;i++) display_data(font_8x16[temp+i]);
  9. display_xy(x,y+1);
  10. for(i=8;i<16;i++) display_data(font_8x16[temp+i]);
  11. }

  12. void display_text_8x16(unsigned char x, unsigned char y, char *txt){
  13. while(*txt){ display_char_8x16(x,y,*txt++); x=x+8;}
  14. }

This example the SH1106 will display ASCII characters and numbers.

Source Code: 

 

  1. /*
  2. * 10-i2c_sh1106_2.c
  3. *
  4. * Created: 2/8/2026 7:59:35 PM
  5. * Author : Admin
  6. */

  7. #include <avr/io.h>
  8. #include <util/delay.h>
  9. #define F_CPU 16000000UL

  10. int main(void)
  11. {
  12. /* Replace with your application code */
  13. _delay_ms(1000);
  14. display_init();
  15. display_clear(0);
  16. display_text_8x16(0,0,"SH1106 I2C OLED");
  17. display_text_8x16(0,1,"And ATMega32");
  18. display_text_8x16(0,2,"Programming With");
  19. display_text_8x16(0,3,"Microchip Studio");
  20. _delay_ms(10000);
  21. display_clear(0x00);
  22. while (1)
  23. {
  24. display_text_8x16(0,0,"ATMega32 SH1106");
  25. _delay_ms(2500);
  26. uint8_t h=15;
  27. for(uint8_t i=0;i<10;i++) {
  28. display_char_8x16(h,1,'0'+i);
  29. h+=10;
  30. }
  31. _delay_ms(2500);
  32. h=0;
  33. for(uint8_t i=0;i<14;i++) {
  34. display_char_8x16(h,2,'A'+i);
  35. h+=10;
  36. }
  37. _delay_ms(2500);
  38. h=0;
  39. for(uint8_t i=0;i<14;i++) {
  40. display_char_8x16(h,3,'N'+i);
  41. h+=10;
  42. }
  43. _delay_ms(10000);
  44. display_clear(255);
  45. _delay_ms(10000);
  46. display_clear(0);
  47. _delay_ms(1000);
  48. }
  49. }


Click here to download this example. 

ATMega32 TWI and SH1106 128x64 OLED Example
Running Program on ATMega32 Prototype Board

The schematic is the same to previous example. 

There two on-board TWI devices, a ds1307 and a AT24L16B. So the MCU will read the RTC data from ds1307 and display it on the SH1106 OLED. Two ADC inputs, ADC0(PA0) connects to a POT, and ADC1(PA1) connects to the LM35 temperature sensor. However the LM35 was a fake TO-92 chip. Time to time it burned out due to heat dissipation.

ATMega32 TWI and SH1106 128x64 OLED Example 

Proteus has only a model for the SSD1306 that almost equivalent to the SH1106. However its simulation speed is very low compare to the parallel port base graphical LCD. But running this program using a real MCU and OLED it operate very well due to the high speed MCU  and SCL clock frequency.

To add any floating point value to a string we need to configure some parameters in the Microchip Studio IDE before compiling.

ATMega32 TWI and SH1106 128x64 OLED Example

ATMega32 TWI and SH1106 128x64 OLED Example 

ATMega32 TWI and SH1106 128x64 OLED Example 

The linker flag is  -lprintf_flt . Click save and close it before building the project.

Source Code:

  1. /*
  2. * twi.c
  3. *
  4. * Created: 2/4/2026 10:22:02 AM
  5. * Author: Admin
  6. */

  7. #define F_CPU 16000000UL

  8. #include <avr/io.h>
  9. #include <util/delay.h>

  10. void twi_init(void){
  11. TWSR|=0x01; //Prescaler Selection Bit
  12. TWBR=0x05; //Baud Rate Generator
  13. TWCR=(1<<TWEN); //Enable The TWI Module
  14. PORTC|=(1<<0);
  15. PORTC|=(1<<1);
  16. }

  17. void twi_start(void){
  18. TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
  19. while((TWCR&(1<<TWINT))==0);
  20. }

  21. void twi_write(unsigned char data){
  22. TWDR=data;
  23. TWCR=(1<<TWINT)|(1<<TWEN);
  24. while((TWCR&(1<<TWINT))==0);
  25. }

  26. unsigned char twi_read(char ACK){
  27. if(ACK==0)
  28. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  29. else
  30. TWCR=(1<<TWINT)|(1<<TWEN);
  31. while((TWCR&(1<<TWINT))==0);
  32. return TWDR;
  33. }

  34. void twi_stop(){
  35. TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
  36. //_delay_us(10);
  37. }

I tested this firmware using the AMTega32 on my AVR Prototype Board. However it works on the ATMega16 or the ATMega644P with a proper software configurations. 

ATMega32 TWI and SH1106 128x64 OLED Example 


ATMega32 TWI and SH1106 128x64 OLED Example

 

Click here to download its source file




 

 


Thursday, January 29, 2026

ATMega644P Graphical LCD Interfacing

Interfacing a graphical LCD to a micro-controller is an interesting stuff beyond a character LCD or a LED matrix display. Most of graphical LCD has a built-in controller for example a well known KS0108 controller chip had been widely used for many years. A monochrome graphical LCD has various size and resolutions, 128x32, 128x64, 128x128, 128x160 and 240x128 etc.

TG12864A-04A 128x32 Dot-matrix and ATMega644P Interfacing 

 

ATMega644P Graphical LCD Interfacing
TG12864A-04A and ATMega644P Interfacing 

I bought an old graphical LCD TG12864A-04A that is a 128x32 dot-matrix display with its controller chips  SBN0064G (64-row x 64-column). So this 128x32 dot-matrix LCD needs two SBN0064G chip that will selecting via CS pin.

ATMega644P Graphical LCD Interfacing
TG12864A-04A LCM Module Spec
 

It controlling method is very similar to the KS0108 controller chip. I will not explain it here.

ATMega644P Graphical LCD Interfacing

ATMega644P Graphical LCD Interfacing

 I bought this LCD module nearly 20 years now since I was at high school writing code for the 8051 micro-controller.

This LCM  module use a parallel port interface, 8-bit data bus and a few control lines as shown in the picture above. It allow data read and write via R/W pin. Command and data is set by the D/I (Data/Instruction) pin. However for most text displaying application we just need to write data to this display.

The example below the ATMega644P send some texts to this LCM display.

main.c

  1. /*
  2. * 8-TG12832A-04A _Text.c
  3. *
  4. * Created: 1/29/2026 5:51:25 PM
  5. * Author : Admin
  6. */
  7. #include <avr/io.h>
  8. #include <avr/pgmspace.h>
  9. #include "font5x8.h"

  10. #include <util/delay.h>
  11. #define F_CPU 16000000UL

  12. #define LCD_DATA PORTB
  13. #define LCD_CONT PORTD

  14. #define LCD_EN 0
  15. #define LCD_DI 1
  16. #define LCD_CS 2
  17. #define LCD_RET 3


  18. unsigned char dotCount=0;

  19. /*
  20. cs = 1 left screen area is selected
  21. cs = 0 right screen area is selected
  22. */
  23. void lcdCommand(unsigned char cmd,char cs){
  24. if(cs==1) LCD_CONT|=(1<<LCD_CS);
  25. else LCD_CONT&=~(1<<LCD_CS);
  26. LCD_CONT&=~(1<<LCD_DI);
  27. LCD_DATA=cmd;
  28. LCD_CONT|=(1<<LCD_EN);
  29. _delay_us(10);
  30. LCD_CONT&=~(1<<LCD_EN);
  31. //if(cs==1) LCD_CONT&=~(1<<LCD_CS);
  32. //else LCD_CONT&=~(1<<LCD_CS);
  33. }

  34. void lcdData(char data,char cs){
  35. if(cs==1) LCD_CONT|=(1<<LCD_CS);
  36. else LCD_CONT&=~(1<<LCD_CS);
  37. LCD_CONT|=(1<<LCD_DI);
  38. LCD_DATA=data;
  39. LCD_CONT|=(1<<LCD_EN);
  40. _delay_us(10);
  41. LCD_CONT&=~(1<<LCD_EN);
  42. //if(cs==1) LCD_CONT&=~(1<<LCD_CS1);
  43. //else if (cs==2) LCD_CONT&=~(1<<LCD_CS2);
  44. }

  45. void lcdHorizontal(unsigned char horizontal){
  46. lcdCommand(0x40+horizontal,1);
  47. lcdCommand(0x40+horizontal,0);
  48. }

  49. void lcdVerticalLine(unsigned char line){
  50. lcdCommand(0xB8+line,1);
  51. lcdCommand(0xB8+line,0);
  52. dotCount=0;
  53. }

  54. void lcdSetZ(unsigned char zAxis){
  55. lcdCommand(0xC0+zAxis,1);
  56. lcdCommand(0xC0+zAxis,0);
  57. }

  58. void lcdXy(unsigned char x,unsigned char y){
  59. if(x<64){
  60. lcdCommand(0x40+x,1);
  61. lcdCommand(0x40+0,0);
  62. }
  63. else{
  64. lcdCommand(0x40+0,1);
  65. lcdCommand(0x40+x-63,0);
  66. }
  67. lcdCommand(0xB8+y,1);
  68. lcdCommand(0xB8+y,0);
  69. dotCount=x;
  70. }

  71. void writeChar(unsigned char aph){
  72. for (int i=0;i<5;i++)
  73. {
  74. char font = pgm_read_byte(&font5x8[((aph-32)*5)+i]);
  75. if(dotCount<64) lcdData(font,1);
  76. else lcdData(font,0);
  77. dotCount++;
  78. }
  79. lcdData(0,(dotCount<64)?1:0);
  80. dotCount++;
  81. if (dotCount>127)
  82. {
  83. dotCount=0;
  84. }
  85. }

  86. void writeCharDelay(unsigned char aph,unsigned int dT){
  87. for (int i=0;i<5;i++)
  88. {
  89. char RomReader = pgm_read_byte(&font5x8[((aph-32)*5)+i]);
  90. if(dotCount<64) lcdData(RomReader,1);
  91. else lcdData(RomReader,0);
  92. if(dT!=0) for(int i=0;i<dT;i++) _delay_us(1000);
  93. dotCount++;
  94. }
  95. lcdData(0,(dotCount<64)?1:0);
  96. dotCount++;
  97. if (dotCount>127)
  98. {
  99. dotCount=0;
  100. }
  101. }

  102. void lcdString(char *str){
  103. while(*str)
  104. writeChar(*str++);
  105. if (dotCount>=127)
  106. {
  107. dotCount=0;
  108. }
  109. }

  110. void writeStringDelay(char *str,unsigned int dT){
  111. while(*str){
  112. if(dT!=0) writeCharDelay(*str++,dT);
  113. else writeChar(*str++);
  114. }
  115. }

  116. void lcdInit(void){
  117. DDRB=0xFF;
  118. DDRD=0xFF;
  119. /*Display On*/
  120. lcdCommand(0x3F,1);
  121. lcdCommand(0x3F,0);
  122. dotCount = 0;
  123. }

  124. void lcdClearScreen(){
  125. for (int i=0;i<4;i++)
  126. {
  127. lcdXy(0,i);
  128. for(int j=0;j<127;j++){
  129. lcdData(0,1);
  130. lcdData(0,0);
  131. }
  132. }
  133. dotCount=0;
  134. lcdXy(0,0);
  135. }

  136. void lcdClearSection(unsigned char x,unsigned char y,unsigned char dot){
  137. lcdXy(x,y);
  138. dotCount=x;
  139. for (int i=0;i<dot;i++)
  140. {
  141. if(dotCount<64) lcdData(0,1);
  142. else lcdData(0,0);
  143. dotCount++;
  144. }

  145. if (dotCount>128)
  146. {
  147. dotCount=0;
  148. }
  149. }



  150. int main(void)
  151. {
  152. //_delay_ms(500);
  153. lcdInit();
  154. lcdClearScreen();
  155. lcdString("ATMega644P AVR GLCD");
  156. lcdXy(0,1);
  157. lcdString("TG12864A-04A 128x32");
  158. lcdXy(0,2);
  159. lcdString("Programming With C in");
  160. lcdXy(0,3);
  161. lcdString("Microchip Studio IDE");
  162. while (1)
  163. {
  164. }
  165. }


font5x8.h

  1. //#ifdef __AVR__
  2. //#include <avr/pgmspace.h>
  3. //static const char PROGMEM font5x8[] = {
  4. //#else
  5. const char font5x8[] PROGMEM= {
  6. //#endif
  7. 0x00, 0x00, 0x00, 0x00, 0x00,// (spacja)
  8. 0x00, 0x00, 0x5F, 0x00, 0x00,// !
  9. 0x00, 0x07, 0x00, 0x07, 0x00,// "
  10. 0x14, 0x7F, 0x14, 0x7F, 0x14,// #
  11. 0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
  12. 0x23, 0x13, 0x08, 0x64, 0x62,// %
  13. 0x36, 0x49, 0x55, 0x22, 0x50,// &
  14. 0x00, 0x05, 0x03, 0x00, 0x00,// '
  15. 0x00, 0x1C, 0x22, 0x41, 0x00,// (
  16. 0x00, 0x41, 0x22, 0x1C, 0x00,// )
  17. 0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
  18. 0x08, 0x08, 0x3E, 0x08, 0x08,// +
  19. 0x00, 0x50, 0x30, 0x00, 0x00,// ,
  20. 0x08, 0x08, 0x08, 0x08, 0x08,// -
  21. 0x00, 0x30, 0x30, 0x00, 0x00,// .
  22. 0x20, 0x10, 0x08, 0x04, 0x02,// /
  23. 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
  24. 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
  25. 0x42, 0x61, 0x51, 0x49, 0x46,// 2
  26. 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
  27. 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
  28. 0x27, 0x45, 0x45, 0x45, 0x39,// 5
  29. 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
  30. 0x01, 0x71, 0x09, 0x05, 0x03,// 7
  31. 0x36, 0x49, 0x49, 0x49, 0x36,// 8
  32. 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
  33. 0x00, 0x36, 0x36, 0x00, 0x00,// :
  34. 0x00, 0x56, 0x36, 0x00, 0x00,// ;
  35. 0x00, 0x08, 0x14, 0x22, 0x41,// <
  36. 0x14, 0x14, 0x14, 0x14, 0x14,// =
  37. 0x41, 0x22, 0x14, 0x08, 0x00,// >
  38. 0x02, 0x01, 0x51, 0x09, 0x06,// ?
  39. 0x32, 0x49, 0x79, 0x41, 0x3E,// @
  40. 0x7E, 0x11, 0x11, 0x11, 0x7E,// A
  41. 0x7F, 0x49, 0x49, 0x49, 0x36,// B
  42. 0x3E, 0x41, 0x41, 0x41, 0x22,// C
  43. 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
  44. 0x7F, 0x49, 0x49, 0x49, 0x41,// E
  45. 0x7F, 0x09, 0x09, 0x01, 0x01,// F
  46. 0x3E, 0x41, 0x41, 0x51, 0x32,// G
  47. 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
  48. 0x00, 0x41, 0x7F, 0x41, 0x00,// I
  49. 0x20, 0x40, 0x41, 0x3F, 0x01,// J
  50. 0x7F, 0x08, 0x14, 0x22, 0x41,// K
  51. 0x7F, 0x40, 0x40, 0x40, 0x40,// L
  52. 0x7F, 0x02, 0x04, 0x02, 0x7F,// M
  53. 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
  54. 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
  55. 0x7F, 0x09, 0x09, 0x09, 0x06,// P
  56. 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
  57. 0x7F, 0x09, 0x19, 0x29, 0x46,// R
  58. 0x46, 0x49, 0x49, 0x49, 0x31,// S
  59. 0x01, 0x01, 0x7F, 0x01, 0x01,// T
  60. 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
  61. 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
  62. 0x7F, 0x20, 0x18, 0x20, 0x7F,// W
  63. 0x63, 0x14, 0x08, 0x14, 0x63,// X
  64. 0x03, 0x04, 0x78, 0x04, 0x03,// Y
  65. 0x61, 0x51, 0x49, 0x45, 0x43,// Z
  66. 0x00, 0x00, 0x7F, 0x41, 0x41,// [
  67. 0x02, 0x04, 0x08, 0x10, 0x20,// "\"
  68. 0x41, 0x41, 0x7F, 0x00, 0x00,// ]
  69. 0x04, 0x02, 0x01, 0x02, 0x04,// ^
  70. 0x40, 0x40, 0x40, 0x40, 0x40,// _
  71. 0x00, 0x01, 0x02, 0x04, 0x00,// `
  72. 0x20, 0x54, 0x54, 0x54, 0x78,// a
  73. 0x7F, 0x48, 0x44, 0x44, 0x38,// b
  74. 0x38, 0x44, 0x44, 0x44, 0x20,// c
  75. 0x38, 0x44, 0x44, 0x48, 0x7F,// d
  76. 0x38, 0x54, 0x54, 0x54, 0x18,// e
  77. 0x08, 0x7E, 0x09, 0x01, 0x02,// f
  78. 0x08, 0x14, 0x54, 0x54, 0x3C,// g
  79. 0x7F, 0x08, 0x04, 0x04, 0x78,// h
  80. 0x00, 0x44, 0x7D, 0x40, 0x00,// i
  81. 0x20, 0x40, 0x44, 0x3D, 0x00,// j
  82. 0x00, 0x7F, 0x10, 0x28, 0x44,// k
  83. 0x00, 0x41, 0x7F, 0x40, 0x00,// l
  84. 0x7C, 0x04, 0x18, 0x04, 0x78,// m
  85. 0x7C, 0x08, 0x04, 0x04, 0x78,// n
  86. 0x38, 0x44, 0x44, 0x44, 0x38,// o
  87. 0x7C, 0x14, 0x14, 0x14, 0x08,// p
  88. 0x08, 0x14, 0x14, 0x18, 0x7C,// q
  89. 0x7C, 0x08, 0x04, 0x04, 0x08,// r
  90. 0x48, 0x54, 0x54, 0x54, 0x20,// s
  91. 0x04, 0x3F, 0x44, 0x40, 0x20,// t
  92. 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
  93. 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
  94. 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
  95. 0x44, 0x28, 0x10, 0x28, 0x44,// x
  96. 0x0C, 0x50, 0x50, 0x50, 0x3C,// y
  97. 0x44, 0x64, 0x54, 0x4C, 0x44,// z
  98. 0x00, 0x08, 0x36, 0x41, 0x00,// {
  99. 0x00, 0x00, 0x7F, 0x00, 0x00,// |
  100. 0x00, 0x41, 0x36, 0x08, 0x00,// }
  101. 0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
  102. 0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
  103. };
  104. //

Schematic:

ATMega644P Graphical LCD Interfacing
Schematic 


AVR Prototype Board Test:

  

ATMega644P Graphical LCD Interfacing
AVR Prototype Board Test

This PCB was offered from PCBWay. 

I have been using PCBWay for many years now. PCBWay fabricate PCBs at low cost, fast processing time for only 24 hours, and fast delivery time using any carrier options. This double side 10cmx10cm can be fabricate at only 5USD for 5 to 10pcs by PCBWay. It's a standard PCB with silk screen and solder mask.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
10 PCBs for only 5USD
 

For different size of PCB we can instantly quote on PCBWay website using a zip PCB Gerber file without account.

A DIY dsPIC30F2010 and dsPIC30F1010 Prototype Board with Programmer
PCBWay Instant Quote


RT12864J-1 KS0108 128x64 Dot-matrix and ATMega644P Interfacing 

The KS0108 is a popular dot matrix display driver many years now. Currently there are a lot of low power, low cost display driver controllers that are equivalent to this chip. They have many interfaces beyond the parallel port such as SPI and I2C that implements only a few wires.

ATMega644P Graphical LCD Interfacing
RT12864J-1 KS0108 128x64 Dot-matrix - TOP
ATMega644P Graphical LCD Interfacing
RT12864J-1 KS0108 128x64 Dot-matrix - BOTTOM

 

I have an RT12864J-1 128x64 Graphical Display I bought I from Ebay many years now. But it has some defect due to aging.

ATMega644P Graphical LCD Interfacing
A Tested Program Using ATMega32
ATMega644P Graphical LCD Interfacing
A Tested Program Using ATMega32

 

ATMega644P Graphical LCD Interfacing 

However this large display use an 8-bit parallel port with some control pins that is very boring for newer electronic hobbyists. There are some wiring issue when installing this display on breadboard that needed to make sure all wires connection. 

To display a graphic we need to create a 128x64 monochrome bitmap image using a PC software for example Adobe Photoshop. Then save it a a monochrome bitmap file. 

ATMega644P Graphical LCD Interfacing
LCD Assistance

 

The LCDAssistant.exe tool convert any monochrome bitmap image to a C graphical data that works with any C compilers.

Source Code:

  1. /*
  2. * 8-RT12864J-1.c
  3. *
  4. * Created: 1/30/2026 9:13:54 AM
  5. * Author : Admin
  6. */

  7. #include <avr/io.h>
  8. #include "font5x8.h"
  9. #include "diy-logo.h"

  10. #include <util/delay.h>
  11. #define F_CPU 16000000UL

  12. #define LCD_DATA PORTB
  13. #define LCD_CONT PORTD

  14. #define LCD_EN 0
  15. #define LCD_RS 1
  16. #define LCD_CS1 3
  17. #define LCD_CS2 2
  18. #define LCD_RST 4

  19. unsigned char dotCount=0;

  20. void lcdCommand(unsigned char cmd,char cs){
  21. if(cs==1) LCD_CONT|=(1<<LCD_CS1);
  22. else if(cs==2) LCD_CONT|=(1<<LCD_CS2);
  23. LCD_CONT&=~(1<<LCD_RS);
  24. LCD_CONT|=(1<<LCD_EN);
  25. LCD_DATA=cmd;
  26. LCD_CONT&=~(1<<LCD_EN);
  27. _delay_us(10);
  28. if(cs==1) LCD_CONT&=~(1<<LCD_CS1);
  29. else if(cs==2) LCD_CONT&=~(1<<LCD_CS2);
  30. }

  31. void lcdData(char data,char cs){
  32. if(cs==1) LCD_CONT|=(1<<LCD_CS1);
  33. else if(cs==2) LCD_CONT|=(1<<LCD_CS2);
  34. LCD_CONT|=(1<<LCD_RS);
  35. LCD_CONT|=(1<<LCD_EN);
  36. LCD_DATA=data;
  37. LCD_CONT&=~(1<<LCD_EN);
  38. _delay_us(10);
  39. if(cs==1) LCD_CONT&=~(1<<LCD_CS1);
  40. else if (cs==2) LCD_CONT&=~(1<<LCD_CS2);
  41. }

  42. void lcdHorizontal(unsigned char horizontal){
  43. lcdCommand(0x40+horizontal,1);
  44. lcdCommand(0x40+horizontal,2);
  45. }

  46. void lcdVerticalLine(unsigned char line){
  47. lcdCommand(0xB8+line,1);
  48. lcdCommand(0xB8+line,2);
  49. dotCount=0;
  50. }

  51. void lcdSetZ(unsigned char zAxis){
  52. lcdCommand(0xC0+zAxis,1);
  53. lcdCommand(0xC0+zAxis,2);
  54. }

  55. void lcdXy(unsigned char x,unsigned char y){
  56. if(x<64){
  57. lcdCommand(0x40+x,1);
  58. lcdCommand(0x40+0,2);
  59. }
  60. else{
  61. lcdCommand(0x40+0,1);
  62. lcdCommand(0x40+x-63,2);
  63. }
  64. lcdCommand(0xB8+y,1);
  65. lcdCommand(0xB8+y,2);
  66. dotCount=x;
  67. }

  68. void writeChar(unsigned char aph){
  69. for (int i=0;i<5;i++)
  70. {
  71. if(dotCount<64) lcdData(font5x8[((aph-32)*5)+i],1);
  72. else lcdData(font5x8[((aph-32)*5)+i],2);
  73. dotCount++;
  74. }
  75. lcdData(0,(dotCount<64)?1:2);
  76. dotCount++;
  77. if (dotCount>127)
  78. {
  79. dotCount=0;
  80. }
  81. }

  82. void writeCharDelay(unsigned char aph,unsigned int dT){
  83. for (int i=0;i<5;i++)
  84. {
  85. if(dotCount<64) lcdData(font5x8[((aph-32)*5)+i],1);
  86. else lcdData(font5x8[((aph-32)*5)+i],2);
  87. if(dT!=0) for(int i=0;i<dT;i++) _delay_us(1000);
  88. dotCount++;
  89. }
  90. lcdData(0,(dotCount<64)?1:2);
  91. dotCount++;
  92. if (dotCount>127)
  93. {
  94. dotCount=0;
  95. }
  96. }

  97. void lcdString(char *str){
  98. while(*str)
  99. writeChar(*str++);
  100. }

  101. void writeStringDelay(char *str,unsigned int dT){
  102. while(*str){
  103. if(dT!=0) writeCharDelay(*str++,dT);
  104. else writeChar(*str++);
  105. }
  106. }

  107. void lcdInit(void){
  108. DDRB=0xFF;
  109. DDRD=0xFF;
  110. /*Display On*/
  111. lcdCommand(0x3F,1);
  112. lcdCommand(0x3F,2);
  113. dotCount = 0;
  114. }

  115. void lcdClearScreen(){
  116. for (int i=0;i<8;i++)
  117. {
  118. lcdXy(0,i);
  119. for(int j=0;j<128;j++){
  120. lcdData(0,1);
  121. lcdData(0,2);
  122. }
  123. }
  124. dotCount=0;
  125. lcdXy(0,0);
  126. }

  127. void lcdClearSection(unsigned char x,unsigned char y,unsigned char dot){
  128. lcdXy(x,y);
  129. dotCount=x;
  130. for (int i=0;i<dot;i++)
  131. {
  132. if(dotCount<64) lcdData(0,1);
  133. else lcdData(0,2);
  134. dotCount++;
  135. }

  136. if (dotCount>127)
  137. {
  138. dotCount=0;
  139. }
  140. }

  141. void showGraphic(void){
  142. unsigned int kCount=0;
  143. for (int i=0;i<8;i++)
  144. {
  145. dotCount=0;
  146. lcdXy(0,i);
  147. for (int j=kCount;j<kCount+128;j++)
  148. {
  149. if(dotCount<64) lcdData(logo[j],1);
  150. else lcdData(logo[j],2);
  151. dotCount++;
  152. }
  153. kCount+=128;
  154. }
  155. }

  156. int main(void)
  157. {
  158. _delay_ms(100);
  159. lcdInit();
  160. lcdClearScreen();
  161. while (1)
  162. {
  163. lcdXy(25,0);
  164. lcdString("HELLO WORLD!");
  165. lcdXy(0,1);
  166. lcdString("ATMEGA644P Graphic");
  167. lcdXy(0,2);
  168. lcdString("Programming in C With");
  169. lcdXy(0,3);
  170. lcdString("Microchip Studio");
  171. lcdXy(0,4);
  172. lcdString("DIY-Instruments");
  173. lcdXy(0,5);
  174. lcdString("KS0108 LCD Controller");
  175. lcdXy(0,6);
  176. lcdString("RT12864J-1 128x64");
  177. lcdXy(0,7);
  178. lcdString("Graphical LCD Module");
  179. _delay_ms(5000);
  180. lcdClearScreen();
  181. lcdXy(0,0);
  182. showGraphic();
  183. _delay_ms(5000);
  184. lcdClearScreen();
  185. }
  186. }



 

Schematic and Simulation: 

ATMega644P Graphical LCD Interfacing
Simulation Using Proteus 

 

ATMega644P Graphical LCD Interfacing
Simulation Using Proteus 

 

In software it worked fine. But in hardware experiment it has problem due to device defect. I need to fix it later.

For more detail about using this display please see this post. CCS PICC also has a C driver of this LCD. It's very easy to use. This example the PIC16F877A interfaces with a 128x64 KS0108 graphical display.

Click here to download this example. 

 


Search This Blog

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (34) Analog Comparator (1) Arduino (16) ARM (13) AT89C52 (7) ATMega32 (58) ATMega644P (27) AVR (87) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (4) Display (133) Distance Sensor (3) ds1307 (10) DS18B20 (5) ds3231 (1) ds3232 (2) dsPIC (5) dsPIC30F1010 (3) dsPIC30F2010 (5) EEPROM (5) Environment Sensor (5) ESP32 (1) esp8266 (1) Graphical LCD (2) I2C (38) ILI9341 (1) Input/Output (75) Interrupt (22) Keil (5) Keypad (16) KS0108 (2) LCD (75) LM35 (3) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (10) PIC (108) PIC12F (3) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) Pin Change Interrupt (1) PWM (12) RTC (12) SBN0064G (1) Sensor (13) SH1106 (3) Shift Register (13) Shift Registers (10) Software TWI (2) SPI (39) ST7735 (1) STM32 (11) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (5) STM32CubeIDE (13) STM32F103C8T6 (9) STM32F401CCU6 (1) SysTick (4) temperature sensor (13) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (8) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)