Interfacing 128x64 LCD display with ATmega8

Discussion in 'Embedded Systems and Microcontrollers' started by LinardsSmeiksts, Jun 10, 2016.

  1. LinardsSmeiksts

    Thread Starter New Member

    May 12, 2016
    4
    0
    Hello!
    I have recently got 128x64 grafical LCD display 12864ZW from kamami.com. I found datasheet on the Internet for the display and started to program it. I was able to initialize it and display text using various fonts. But my aim was to display grafical objects for example sinus curve. I explored all the datasheet and tried many ways, but I couldn't draw anything using individual pixels. I use ATmega 8 micrcontroller. I'm sure that my circuit is okay, because I can display characters. I hope that someone might help me. Here is also my code:

    Code (C):
    1.  
    2. [I]#define F_CPU 1000000UL  // 1 MHz
    3. #include <avr/io.h>
    4. #include <util/delay.h>
    5.  
    6. #define ControlREG         DDRB
    7. #define RS                 0
    8. #define RW                 1
    9. #define E                 2
    10.  
    11. #define DataREG            DDRD
    12.  
    13. void Strobe(void);
    14. void CheckBusyFlag(void);
    15. void SendCommand(unsigned char command);
    16. void SendChar(unsigned char character);
    17. void SendChinese(unsigned int chinesechar);
    18.  
    19.  
    20. int main(void)
    21. {
    22.     ControlREG |= (1<<RS) | (1<<RW) | (1<<E);
    23.     /*
    24.     // Initialization of LCD display [video tutorial version]
    25.     _delay_ms(50);
    26.     SendCommand(0x38);
    27.     _delay_us(50);
    28.     SendCommand(0b00001111);
    29.     _delay_us(50);
    30.     SendCommand(0b00000001);
    31.     _delay_ms(2);
    32.     // Initialization end
    33.     */
    34.    
    35.     // Initialization of LCD display [datasheet version]
    36.     _delay_ms(60);
    37.     SendCommand(0x24); // 0b00110000
    38.     _delay_us(50);
    39.     SendCommand(0x24);
    40.     _delay_us(50);
    41.     SendCommand(0x0c);
    42.     _delay_ms(150);
    43.     SendCommand(0x01);
    44.     _delay_ms(15);
    45.     SendCommand(0x06);
    46.     // Initalization end
    47.    
    48.     //SendCommand(0x82);  // Set character adress
    49.     //SendChar(0xF7);
    50.     //SendChar(0xA6);
    51.     //SendChinese(0xF7A7);
    52.    
    53.     /*
    54.     // Initialization of LCD display [grafic display mode]
    55.     _delay_ms(60);
    56.     SendCommand(0x36);
    57.     _delay_ms(50);
    58.     SendCommand(0x36);
    59.     _delay_ms(50);
    60.     SendCommand(0x0c);
    61.     _delay_ms(150);
    62.     SendCommand(0x01);
    63.     _delay_ms(15);
    64.     SendCommand(0x04);
    65.     // End of initialization
    66.     */
    67.    
    68.     SendCommand(0x0B);
    69.     SendCommand(0x03);
    70.     SendCommand(0x41);
    71.     SendCommand(0x22);
    72.     SendCommand(0x05);
    73.     SendCommand(0x21);
    74.     SendChinese(0x0007);
    75.    
    76.     while(1)
    77.     {
    78.     }
    79. }
    80.  
    81. void CheckBusyFlag()
    82. {
    83.     DataREG = 0;
    84.     PORTB &= ~(1<<RS);
    85.     PORTB |= (1<<RW);
    86.     while(PORTD >= 0x80)                // 0x80 = 0b10000000
    87.     {
    88.         Strobe();
    89.     }
    90.     DataREG = 0xFF;
    91. }
    92.  
    93. void Strobe()
    94. {
    95.     PORTB |= (1<<E);
    96.     asm volatile("nop");
    97.     asm volatile("nop");
    98.     PORTB &= ~(1<<E);
    99. }
    100.    
    101.  
    102. void SendCommand(unsigned char command)
    103. {
    104.     CheckBusyFlag();
    105.     PORTD = command;
    106.     PORTB &= ~(1<<RS | 1<<RW);
    107.     Strobe();
    108.     PORTD = 0;
    109. }
    110.  
    111. void SendChar(unsigned char character)
    112. {
    113.     CheckBusyFlag();
    114.     PORTD = character;
    115.     PORTB |= (1<<RS);
    116.     PORTB &= ~(1<<RW);
    117.     Strobe();
    118.     PORTD = 0;
    119. }
    120.  
    121. void SendChinese(unsigned int chinesechar)
    122. {
    123.     CheckBusyFlag();
    124.     PORTD |= ((chinesechar & 0xFF00) >> 8);
    125.     PORTB |= (1<<RS);
    126.     PORTB &= ~(1<<RW);
    127.     Strobe();
    128.     PORTD = 0;
    129.     PORTD |= (chinesechar & 0x00FF);
    130.     PORTB |= (1<<RS);
    131.     PORTB &= ~(1<<RW);
    132.     Strobe();
    133.     PORTD = 0;
    134. }
    135.  
    Moderators note: please use code tags for pieces of code
     
    Last edited by a moderator: Jun 11, 2016
  2. dannyf

    Well-Known Member

    Sep 13, 2015
    1,771
    358
    It's fairly easy. the timing is outlined on Page 8 and bottom of Page 11 of the datasheet. The commands are on Page 14 - 22, and the sample code goes from Page 43 - bottom of Page 49. A simple copy-and-paste job.
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    I browsed a data sheet for this device by Digole who I believe make this thing. Find it and look at the section on Graphic RAM or GDRAM. It explains how to access the device at a pixel level.

    Seems you write 8 pixels at a time, so to change any particular pixel means you need read the byte, modify it, then write it back.

    There is a command in the instructs set 2 that gets you access to this graphic data area. That command also includes vertical and horizontal address info. This address auto increments, which is not very handy as you need to set it, read the data, set it once more to write the data to the same address.
     
  4. LinardsSmeiksts

    Thread Starter New Member

    May 12, 2016
    4
    0
    On which datasheet?
     
  5. LinardsSmeiksts

    Thread Starter New Member

    May 12, 2016
    4
    0
    I don't understand why I need to READ first and then WRITE. Why isn't working algorithm: 1) set vertical adress, 2) set horizontal adress, 3) write HIGH byte, 4) write LOW byte, which is written in datasheet? :(
     
  6. dannyf

    Well-Known Member

    Sep 13, 2015
    1,771
    358
    that's correct. See the datasheet.
     
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Because you asked how to access a specific pixel, not a group of 8 pixels.

    To change one pixel you must find which byte it is in, read that byte, change the pixel, then write it back where it was.
     
  8. LinardsSmeiksts

    Thread Starter New Member

    May 12, 2016
    4
    0
    Thanks for replies! I have finally found the problem and solved it. Everything was working fine, I only had to clean all random pixels after initialization. :)
     
Loading...