Menu

a-ads Ad Unit #2456538

Ad Unit #2456555

Navbar

a-ads Ad Unit #2456538

Friday, January 30, 2026

ATMega644P Analog to Digital Converter (ADC) Example

Overview

The Analog to Digital Converter (ADC) convert analog voltage value to a digital representation that the micro-processor could understand. Most of modern micro-controller has at least one built-in ADC module that can be use by software configuration. The most common ADC resolution is between 8-bit and 12-bit with an acceptable conversion rate.

ATMega644P Analog to Digital Converter (ADC) Example

 

The resolution give more precise digital data for the micro-controller. However its reference voltage and lower clock also effect the precision of the analog input value. Some 32-bit micro-controller especially the STM32 micro-controller series has an ADC module with the resolution of 12-bit with the conversion rate up to 2MSPS. Some 16-bit dsPIC micro-controller series has an ADC module with the resolution of 10-bit and 1~2MSPS conversion rate.

Commonly we use the ADC to read temperature value, flex sensor and strain gauge etc.

ATMega644P ADC Programming Example

The ADC of the ATMega644P has a 10-bit analog to digital converter with the maximum conversion rate up to 15kSPS. It has up to 8 analog input channel (ADC7:ADC0) via PortA. The conversion triggers by user software (set ADC to start) or by any interrupt sources.

ATMega644P Analog to Digital Converter (ADC) Example
Analog-to-digital Converter Block Schematic

 

The software configuration of the ADC module of AVR micro-controller is simpler than other micro-controllers. It has a few registers to configure. 

I don't write its detail here since the ADC process of the ATMega644P is very similar to the ATMega32. 

ADC and LED Example 1

In this introductory example the ATMega644P read the analog input from ADC0(PA0). The 10-bit ADC result will converts to 8-bit by shifting right that will display on PORTB.

C Source Code:

  1. /*
  2. * 9-ADC_LED.c
  3. *
  4. * Created: 1/30/2026 3:28:06 PM
  5. * Author : Admin
  6. */

  7. #include <avr/io.h>

  8. int main(void)
  9. {
  10. DDRB=0xFF;
  11. //PA0 or ADC0 as an analog input
  12. DDRA=0;
  13. //Turn on the ADC module
  14. ADCSRA=(1<<ADEN);
  15. uint16_t temp;
  16. while (1)
  17. {
  18. //Start the conversion
  19. ADCSRA|=(1<<ADSC);
  20. //Wait for the completion
  21. while((ADCSRA&(1<<ADSC))==1);
  22. //Read the result
  23. temp=ADCL+(ADCH<<8);
  24. PORTB=temp>>2;
  25. }
  26. }
  27.  

Proteus Simulation:

ATMega644P Analog to Digital Converter (ADC) Example
Proteus Simulation #1

AVR Prototype Board Test:

ATMega644P Analog to Digital Converter (ADC) Example

ATMega644P Analog to Digital Converter (ADC) Example

 

ADC and LED Example 2

I use this prototype board's LED and POT to make a LED shifting using the ADC voltage level. It's very similar to a ring counter. However I need to convert between ADC value counter value.

Source Code:

  1. /*
  2. * 9-ADC_BarGraph.c
  3. *
  4. * Created: 1/30/2026 4:21:13 PM
  5. * Author : Admin
  6. */

  7. #include <avr/io.h>

  8. int main(void)
  9. {
  10. DDRB=0xFF;
  11. //PA0 or ADC0 as an analog input
  12. DDRA=0;
  13. //Turn on the ADC module
  14. ADCSRA=(1<<ADEN);
  15. long temp,div;
  16. while (1)
  17. {
  18. //Start the conversion
  19. ADCSRA|=(1<<ADSC);
  20. //Wait for the completion
  21. while((ADCSRA&(1<<ADSC))==1);
  22. //Read the result
  23. temp=ADCL+(ADCH<<8);
  24. div=(temp*8)/1024;
  25. PORTB=(1<<div);
  26. }
  27. }


Proteus Schematic and Simulation:

ATMega644P Analog to Digital Converter (ADC) Example
Proteus Schematic and Simulation

AVR Prototype Board Test: 

ATMega644P Analog to Digital Converter (ADC) Example

ATMega644P Analog to Digital Converter (ADC) Example

 

ADC and LED Example 2

There are two on-board ADC inputs, POT and LM35 temperature sensor. The LCD will display the analog input from POT(ADC0) and LM35(ADC1). The LM35 temperature (in degree Celsius) is equivalent to 10mV that's 2 in digital value (+5.0VDC voltage reference).

ATMega32 Interfaces To LM35 And 16x2 Character LCD
LM35DZ in TO-92 Package

 

Source Code:

  1. /*
  2. * 9-ADC_LCD.c
  3. *
  4. * Created: 1/30/2026 4:47:25 PM
  5. * Author : Admin
  6. */

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

  11. void adc_init(void){
  12. /*Set PA0 and PA1 to input*/
  13. DDRA&=~(1<<0);
  14. DDRA&=~(1<<1);
  15. ADCSRA=(1<<ADEN);
  16. /*Select AD0*/
  17. ADMUX=0x03;
  18. }

  19. unsigned int read_adc(char channel){
  20. //Select Channel
  21. ADMUX=channel;
  22. //Start Convsersion
  23. ADCSRA|=(1<<ADSC);
  24. //Wait for Completion
  25. while(ADCSRA&(1<<ADSC));
  26. //Get the 10-bit values
  27. return (ADCL+(ADCH<<8));
  28. }
  29. int main(void)
  30. {
  31. /* Replace with your application code */
  32. lcd_init();
  33. lcd_text("ATMega644P ADC");
  34. lcd_xy(1,2);
  35. lcd_text("POT AND LM35");
  36. adc_init();
  37. _delay_ms(1000);
  38. lcd_clear();
  39. unsigned int temp;
  40. float voltage;
  41. char msg[16];
  42. lcd_command(0x0C);
  43. while (1)
  44. {
  45. //Read POT
  46. temp=read_adc(0);
  47. //Convert To Voltage
  48. voltage=temp*5.0/1023;
  49. sprintf(msg,"ADC0: %4d %.2fV",temp,voltage);
  50. lcd_xy(1,1); lcd_text(msg);
  51. //Read LM35
  52. temp=read_adc(1);
  53. voltage=temp*5.0/1023;
  54. voltage*=100;
  55. sprintf(msg,"Temp: %0.1f%cC",voltage,223);
  56. lcd_xy(1,2); lcd_text(msg);
  57. _delay_ms(1000);
  58. }
  59. }

Proteus Schematic:

ATMega644P Analog to Digital Converter (ADC) Example
Proteus Schematic

AVR Prototype Board: 

ATMega644P Analog to Digital Converter (ADC) Example
Program Tested on my AVR Prototype Board

Unfortunately I bough some fake LM35DZ due to their local availability and low cost, around 0.50USD. The original LM35DZ(TO92) temperature chip costs around 1USD. However some online store also sell this chip in bulk price at very low cost.

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

 


 

 

 

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. 

 


Ad Unit #2456555

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) AVR PCB (2) 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 (76) Interrupt (22) IoT PCB (1) 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) Module PCB (1) 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) PIC16 (105) 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) PICMicro PCB (4) 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)