Skip to main content

128 x 64 Graphics LCD Display Interfacing with ATMEGA32 Library from Scratch



            Yes I am diving little into traditional stuff, still its interesting to try something from scratch. While working on some hi-tech stuff where we mostly don't care about writing something from scratch as its time consuming. Now a days platforms like arduino are concentrating on Application, they are not meant to use to understand the hardware peripheral. In fact I never tried it though ;). I know there are lots of example available online regarding this graphics LCD. This LCD I selected is HDG128x64F, which is more or less what is conventionally used, but I found some differences as in column addressing method. I got datasheet about HDG128x64F here, where I can only find some commands which are more or less similar to that of 16x2 LCD except RAM addressing method. To start working on this I preferred using Proteus Simulation software to make it more flexible in terms of Hardware.

Note - This software I tried with Proteus not on actual hardware. Put comment below if you find it difficult on actual hardware.

Hardware - 

Following is the circuit you can try in proteus


To interface this Graphics LCD I used ATMEGA32 as many people love to do hobby stuff on AVR and me too :D. Few problems I encountered while displaying any sort of character on display. One is that the addressing for column e.g. 0 starts from top right corner rather than left top corner. Second, I found that whenever I was writing the RAM address was auto increment from right to left than left to right, which is kind of weird operation.To make it work I made changes in software. If anyone of you have encountered/ or know solution on this you are welcome to comment. Following are the command codes for display



Software - 

       In the current software version I have only concentrated on displaying fonts. Before character I had decided to display image but anyway that is not a hard job as only I have to fill  RAM buffer with image pixel data, hence I worked on displaying characters. Thanks to Andy Gock's font header file here. I used this fonts file directly in order to display it on GLCD.


/*
* font5x7.h
*
* Created: 28/03/2012 1:52:20 AM
* Author: andy
*/
// Title : Graphic LCD Font (Ascii Charaters)
// Author : Pascal Stang
#ifndef FONT5X7_H_
#define FONT5X7_H_
#include <avr/pgmspace.h>
// standard ascii 5x7 font
// defines ascii characters 0x20-0x7F (32-127)
const char Font5x7[] = {
0x00, 0x00, 0x00, 0x00, 0x00,// (space)
0x00, 0x00, 0x5F, 0x00, 0x00,// !
0x00, 0x07, 0x00, 0x07, 0x00,// "
0x14, 0x7F, 0x14, 0x7F, 0x14,// #
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
0x23, 0x13, 0x08, 0x64, 0x62,// %
0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x1C, 0x22, 0x41, 0x00,// (
0x00, 0x41, 0x22, 0x1C, 0x00,// )
0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x50, 0x30, 0x00, 0x00,// ,
0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x60, 0x60, 0x00, 0x00,// .
0x20, 0x10, 0x08, 0x04, 0x02,// /
0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41,// <
0x14, 0x14, 0x14, 0x14, 0x14,// =
0x41, 0x22, 0x14, 0x08, 0x00,// >
0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x32, 0x49, 0x79, 0x41, 0x3E,// @
0x7E, 0x11, 0x11, 0x11, 0x7E,// A
0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x7F, 0x09, 0x09, 0x01, 0x01,// F
0x3E, 0x41, 0x41, 0x51, 0x32,// G
0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x7F, 0x02, 0x04, 0x02, 0x7F,// M
0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x46, 0x49, 0x49, 0x49, 0x31,// S
0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x7F, 0x20, 0x18, 0x20, 0x7F,// W
0x63, 0x14, 0x08, 0x14, 0x63,// X
0x03, 0x04, 0x78, 0x04, 0x03,// Y
0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41,// [
0x02, 0x04, 0x08, 0x10, 0x20,// "\"
0x41, 0x41, 0x7F, 0x00, 0x00,// ]
0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x01, 0x02, 0x04, 0x00,// `
0x20, 0x54, 0x54, 0x54, 0x78,// a
0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x38, 0x44, 0x44, 0x44, 0x20,// c
0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x38, 0x54, 0x54, 0x54, 0x18,// e
0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x08, 0x14, 0x54, 0x54, 0x3C,// g
0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x20, 0x40, 0x44, 0x3D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44,// k
0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x38, 0x44, 0x44, 0x44, 0x38,// o
0x7C, 0x14, 0x14, 0x14, 0x08,// p
0x08, 0x14, 0x14, 0x18, 0x7C,// q
0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x48, 0x54, 0x54, 0x54, 0x20,// s
0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x44, 0x28, 0x10, 0x28, 0x44,// x
0x0C, 0x50, 0x50, 0x50, 0x3C,// y
0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x00, 0x08, 0x36, 0x41, 0x00,// {
0x00, 0x00, 0x7F, 0x00, 0x00,// |
0x00, 0x41, 0x36, 0x08, 0x00,// }
0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
};
#endif /* FONT5X7_H_ */
view raw Fonts.h hosted with ❤ by GitHub
/*
Project - Interfacing 128*64 Graphics LCD to ATMEGA32
Author: Shrenik Shikhare
Email: engineershrenik@gmail.com
date: 25/9/2014
homepage: embeddlinux.blogspot.in
compiler: avr-gcc
Copyright (C) <2014> <embeddlinux.blogspot.in>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "HDG12864FLcd.h"
#include "Fonts.h"
#include <string.h>
//Initializes Graphics LCD
void initLCD( void)
{
//writeCmd(0xA5); //Set All Points
writeCmd(0xAF); //Display ON
//writeCmd(0x40); //Display RAM start address 0b000000 | 0b01
//writeCmd(0x0F);
writeCmd(0xA6); //Normal Display
//writeCmd(0xA0);
//writeCmd(0xC8);
}
//This function writes single character from fonts and a white space of single column
void writeChar(uint8_t uChar)
{
int i;
for ( i = 4; i >= 0; i--)
{
writeData(Font5x7[ ((uChar - 32)*5)+i]); //Get Correspondent Hex Values needed to represent ASCII char from Fonts
//writeCmd(0xE0);
}
writeData(0x00); //Space after each character print
}
//This function writes string on display on specified x (Column), y address(Row)
void writeString(uint8_t x, uint8_t y,uint8_t *uString)
{
setRow(y);
uString = strrev(uString);
setColumn(x);
while(*uString)
{
writeChar(*uString++);
}
}
//This function sets RAM address to specified ROW number.
void setRow( uint8_t uRowAddr)
{
uRowAddr = uRowAddr | 0xB0;
writeCmd( uRowAddr);
}
//This function sets column address from 128 columns
void setColumn( uint8_t uColumnAddr)
{
uint8_t uLowAddr, uHighAddr;
uHighAddr = 0x10 | (( uColumnAddr &0xF0) >> 4);
uLowAddr = ( uColumnAddr & 0x0F);
//writeCmd(0xE1);
writeCmd( uHighAddr);
writeCmd( uLowAddr);
}
//Write Command to LCD
void writeCmd( uint8_t uCmd)
{
LCD_DATA_PORT = uCmd;
CMD_WRITE_EN();
_delay_ms(1);
CMD_WRITE_DS();
//_delay_ms(50); //Need to enable in real setup for simulation it adds more delay
}
//Write Data to LCD
void writeData( uint8_t uData)
{
LCD_DATA_PORT = uData;
DATA_WRITE_EN();
_delay_ms(1);
DATA_WRITE_DS();
//_delay_ms(50); //Need to enable in real setup for simulation it adds more delay
}
view raw HDG12864FLcd.c hosted with ❤ by GitHub
#ifndef _HDG12864_H_
#define _HDG12864_H_
#endif
/*
LCD DATA port----PORT B
CTRL port------PORT C
RS-------PC1
RW-------PC0
EN-------PC2
*/
#ifdef _HDG12864_H_
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
//Macros
#define RW PC0 //Read/Write Select 0-Write to display, 1-Read from display
#define RS PC1 //Register Select 0 - Command Register Select, 1 - Data register Select
#define EN PC2 //Enable Display Signal
#define LCD_CMD_PORT PORTC
#define LCD_DATA_PORT PORTB
//#define WRITE_DISPLAY() ( PORTC &=~ ( 1 << RW))
#define CMD_WRITE_EN() ( LCD_CMD_PORT = ( 0 << RS) | ( 0 << RW) | ( 1 << EN) )
#define DATA_WRITE_EN() ( LCD_CMD_PORT = ( 1 << RS) | ( 0 << RW) | ( 1 << EN) )
#define CMD_WRITE_DS() ( LCD_CMD_PORT = ( 0 << RS) | ( 0 << RW) | ( 0 << EN) )
#define DATA_WRITE_DS() ( LCD_CMD_PORT = ( 1 << RS) | ( 0 << RW) | ( 0 << EN) )
void initLCD( void);
void writeCmd( uint8_t uCmd);
void writeData( uint8_t uData);
void setRow( uint8_t uRowAddr);
void setColumn( uint8_t uColumnAddr);
void writeChar(uint8_t uChar);
void writeString(uint8_t x, uint8_t y,uint8_t *uString);
#endif //_HDG12864_H_
view raw HDG12864FLcd.h hosted with ❤ by GitHub
/*
Project - Interfacing 128*64 Graphics LCD to ATMEGA32
Author: Shrenik Shikhare
Email: engineershrenik@gmail.com
date: 25/9/2014
homepage: embeddlinux.blogspot.in
compiler: avr-gcc
Copyright (C) <2014> <embeddlinux.blogspot.in>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <inttypes.h>
//#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
//#include <util/delay.h>
#include "HDG12864FLcd.h"
//uint8_t
int main()
{
// Write your code here
DDRB |= 0xFF;
DDRC |= 0xFF;
initLCD();
writeString(40,3,"SHRENIK's");
writeString(20,4,"LCD DISPLAY LIB");
while (1)
{
//PORTB ^= 0xFF;
//_delay_ms();
}
return 0;
}
view raw main.c hosted with ❤ by GitHub
You can find this lib on my github repository. Download code
Comment below if any suggestions/ help.

Regards,
Shrenik.


Comments

  1. Contrast pin 3 should be connected through middle pin of 10k POT and two ends of POT should be connected with pin18 (i.e. -10V) and VCC (5V).

    ReplyDelete
  2. Is the codes works on the LCD display?.Thank you for sharing the circuit images and the hardware used for this experiment.The Embedded Software Development Services are really looking forward to generate new devices with the help of embedded software engineers.The work you had shared here is really appreciable.

    ReplyDelete

Post a Comment

Popular posts from this blog

Interfacing M45PE16 SPI Flash to ATMEGA32

       As many people need some sort of storage in their embedded project, they prefer to use SPI flash. Hence I decided to try this interfacing with ATMEGA32 microcontroller. This SPI flash is 16Mb flash, works on SPI interface. You can reuse below code if you want to integrate this flash to your project. I tested this code using proteus simulation, you can also test and comment. Features of M45PE16- 16Mb of page-erasable Flash memory Page size: 256 bytes Sector erase: 512Kb 75 MHz clock frequency (MAX) In current interfacing I only did Page Write/ Read API's. The SPI needs to configure in Mode 0, and Master at Microcontroller side as given in code below. The result or Page read bytes are displayed over terminal using UART. Code- M45PE16.c /*  *  *  *  Created on: Apr 18, 2014  *      Author: Shrenik Shikhare  *      File: M45PE16.c  *      Discription: Interfaci...

How to interface USB modem to ARM board (for android or linux)

How to interface 3G usb modem to any ARM (Android / linux ported) Board.  Hi I am now going to provide quick steps to interface the 3G usb modem to linux/ Android SBC which i have tried during my try which is successful one . More and more USB devices when plugged in for the first time they act like a flash storage and start installing the driver from there. After installation (and on every consecutive plugging) the driver switches the mode internally, the storage device vanishes (in most cases), and a new device (like an USB modem) shows up.       Few modems (Huawie) most of time they do not need to switch from mass storage to usb modem mode. When you connect that modem to USB port then it will be detected as ttyUSB (3 ttyUSB ports are detected). Otherwise you need to switch the mode of usb modem by using usb_modeswitch utility (I am giving examples of idea modem / reliance modem which are from Huawei and a dlink 3G modem which requires usb modesw...