Simple driver for the ST7920 graphic LCD 128x64. Basic functions for displaying internal ROM fonts like a 16x4 LCD Extended function to fill the screen with a bitmap

Files at this revision

API Documentation at this revision

Comitter:
Bas
Date:
Fri Jun 29 22:47:51 2012 +0000
Commit message:
Function added for displaying vertical oriented bitmaps

Changed in this revision

st7920.cpp Show annotated file Show diff for this revision Revisions of this file
st7920.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/st7920.cpp	Fri Jun 29 22:47:51 2012 +0000
@@ -0,0 +1,246 @@
+#include "st7920.h"
+
+ST7920::ST7920 (PinName _RS,PinName _RW, PinName _E, PinName DB0, PinName DB1, PinName DB2, PinName DB3, PinName DB4, PinName DB5, PinName DB6, PinName DB7)
+        : DB(DB0,DB1,DB2,DB3,DB4,DB5,DB6,DB7),RS(_RS), RW(_RW), E(_E) {
+
+    DB.output();
+    E.write(0);
+    RS.write(0);
+    RW.write(0);
+    InitDisplay();
+}
+
+unsigned int ST7920::ByteReadLCD() {
+    unsigned int data;
+
+    DB.input();
+    E.write(1);
+    data = DB.read();
+    E.write(0);
+    DB.output();
+
+    return data;
+}
+
+void ST7920::ByteWriteLCD(unsigned int data) {
+    DB.output();
+    E.write(1);
+    DB.write(data);
+    E.write(0);
+}
+
+void ST7920::WriteInstruction(unsigned int Command) {
+    ReadBusyFlag();
+    RS.write(0);
+    RW.write(0);
+    ByteWriteLCD(Command);
+}
+
+void ST7920::WriteRAM(unsigned int data) {
+    ReadBusyFlag();
+    RS.write(1);
+    RW.write(0);
+    ByteWriteLCD(data);
+}
+
+void ST7920::ReadBusyFlag() {
+    unsigned char data;
+
+    RS.write(0);
+    RW.write(1);
+    while ((data & 0x7F) == BUSY_FLAG_BF) {
+        data = ByteReadLCD();
+    }
+}
+
+unsigned int ST7920::Read_AC() {
+    RS.write(0);
+    RW.write(1);
+    return (ByteReadLCD() & 0x7F);
+}
+
+unsigned int ST7920::ReadRAM() {
+    ReadBusyFlag();
+    RS.write(1);
+    RW.write(1);
+    return ByteReadLCD();
+}
+
+void ST7920::InitDisplay() {
+    wait_ms(40); // wait 40ms
+    E.write(0);
+    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // 8 bits interface, RE=0
+    wait_us(100); // wait 100us
+    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // again
+    wait_us(37); // wait 37us
+    WriteInstruction(DISPLAY_CONTROL | DISPLAY_ON_D ); // display on
+    wait_us(100); // wait 100us
+    WriteInstruction(DISPLAY_CLEAR); // clear display
+    wait_ms(10); // wait 10ms
+    WriteInstruction(ENTRY_MODE_SET | INCREASE_DECREASE_ID); // move cursor right
+    wait_ms(10); // wait 10ms
+    WriteInstruction(RETURN_HOME);
+    SetGraphicsMode();
+}
+
+//************************************************************************************************
+//public methodes
+void ST7920::SetGraphicsMode() {
+    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL);
+    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL | EXTENDED_INSTRUCTION_RE); //RE=1 (Extended funtion set)
+    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL | EXTENDED_INSTRUCTION_RE | GRAPHIC_ON_G);
+}
+
+void ST7920::SetTextMode() {
+    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // RE=0 (Basic funtion set)
+}
+
+void ST7920::ClearScreen() {
+    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); // RE=0 (Basic funtion set)
+    WriteInstruction(DISPLAY_CLEAR);
+}
+
+void ST7920::ReturnHome() {
+    WriteInstruction(FUNCTION_SET | DATA_LENGTH_DL); //RE=0 (Basic funtion set)
+    WriteInstruction(RETURN_HOME);
+}
+
+void ST7920::Standby() {
+    WriteInstruction(EXTENDED_FUNCTION_SET | DATA_LENGTH_DL | EXTENDED_INSTRUCTION_RE); //RE=1 (Extended funtion set)
+    WriteInstruction(STANDBY);
+}
+
+//Basic text functions
+void ST7920::DisplayString(int Row,int Column,unsigned char *ptr,int length) {
+    int i=0;
+
+    switch (Row) {
+        case 0:
+            Column|=0x80;
+            break;
+        case 1:
+            Column|=0x90;
+            break;
+        case 2:
+            Column|=0x88;
+            break;
+        case 3:
+            Column|=0x98;
+            break;
+        default:
+            Column=0x80;
+            break;
+    }
+
+    if (Column%2!=0) {
+        Column-=1;
+        i=1;
+    }
+    WriteInstruction((unsigned int)Column);
+
+    if (i==1) {
+        WriteRAM(' ');
+    }
+    for (i=0; i<length; i++) {
+        WriteRAM((unsigned int)ptr[i]);
+    }
+}
+
+void ST7920::DisplayChar(int Row,int Column,int inpChr) {
+    int i=0;
+
+    switch (Row) {
+        case 0:
+            Column|=0x80; // SET_DDRAM_ADDRESS
+            break;
+        case 1:
+            Column|=0x90;
+            break;
+        case 2:
+            Column|=0x88;
+            break;
+        case 3:
+            Column|=0x98;
+            break;
+        default:
+            Column=0x80;
+            break;
+    }
+
+    if (Column%2!=0) {
+        Column-=1;
+        i=1;
+    }
+    WriteInstruction((unsigned int)Column);
+
+    if (i==1) {
+        WriteRAM(' ');
+    }
+    WriteRAM((unsigned int)inpChr);
+}
+
+// Graphic functions
+void ST7920::FillGDRAM(unsigned char *bitmap) {
+    unsigned char i, j, k ;
+
+    for ( i = 0 ; i < 2 ; i++ ) {
+        for ( j = 0 ; j < 32 ; j++ ) {
+            WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | j) ;
+            if ( i == 0 ) {
+                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS) ;
+            } else {
+                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | 0x08) ;
+            }
+            for ( k = 0 ; k < 16 ; k++ ) {
+                WriteRAM( *bitmap++ ) ;
+            }
+        }
+    }
+}
+
+void ST7920::FillGDRAM_Turned(unsigned char *bitmap) {
+    int i, j, k, m, offset_row, mask ;
+    unsigned char data;
+
+    for ( i = 0 ; i < 2 ; i++ ) { //upper and lower page
+        for ( j = 0 ; j < 32 ; j++ ) { //32 lines per page
+            WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | j) ;
+            if ( i == 0 ) {
+                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS) ;
+            } else {
+                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | 0x08) ;
+            }
+            mask=1<<(j%8); // extract bitnumber
+            //printf("mask: %d\r\n",mask);
+            for ( k = 0 ; k < 16 ; k++ ) { //16 bytes per line
+                offset_row=((i*32+j)/8)*128 + k*8; //y coordinate/8 = row 0-7 * 128 = byte offset, read 8 bytes
+                data=0;
+                for (m = 0 ; m < 8 ; m++) { // read 8 bytes from source
+
+                    if ((bitmap[offset_row+m] & mask)) { //pixel = 1
+                        data|=(128>>m);
+                    }
+                }
+                WriteRAM(data) ;
+            }
+        }
+    }
+}
+
+void ST7920::ClearGDRAM() {
+    unsigned char i, j, k ;
+
+    for ( i = 0 ; i < 2 ; i++ ) {
+        for ( j = 0 ; j < 32 ; j++ ) {
+            WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | j) ;
+            if ( i == 0 ) {
+                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS) ;
+            } else {
+                WriteInstruction(SET_GRAPHIC_RAM_ADDRESS | 0x08) ;
+            }
+            for ( k = 0 ; k < 16 ; k++ ) {
+                WriteRAM(0);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/st7920.h	Fri Jun 29 22:47:51 2012 +0000
@@ -0,0 +1,270 @@
+#ifndef __ST7920_H
+#define __ST7920_H
+
+#define VERSION 1.0
+
+#include <mbed.h>
+
+// Instruction Set 1: (RE=0: Basic Instruction)
+#define DISPLAY_CLEAR           0x01 // Fill DDRAM with "20H" and set DDRAM address counter (AC) to "00H"
+#define RETURN_HOME             0x02 // Set DDRAM address counter (AC) to "00H", and put cursor
+// to origin &#65533;Gthe content of DDRAM are not changed
+#define ENTRY_MODE_SET          0x04 // Set cursor position and display shift when doing write or read
+// operation
+#define DISPLAY_CONTROL         0x08 // D=1: Display ON, C=1: Cursor ON, B=1: Character Blink ON
+#define CURSOR_DISPLAY_CONTROL  0x10 // Cursor position and display shift control; the content of
+// DDRAM are not changed
+#define FUNCTION_SET            0x20 // DL=1 8-bit interface, DL=0 4-bit interface
+// RE=1: extended instruction, RE=0: basic instruction
+#define SET_CGRAM_ADDRESS       0x40 // Set CGRAM address to address counter (AC)
+// Make sure that in extended instruction SR=0
+#define SET_DDRAM_ADDRESS       0x80 // Set DDRAM address to address counter (AC)
+// AC6 is fixed to 0
+
+// Instruction set 2: (RE=1: extended instruction)
+#define STANDBY                 0x01 // Enter standby mode, any other instruction can terminate.
+// COM1&#65533;c32 are halted
+#define SCROLL_OR_RAM_ADDR_SEL  0x02 // SR=1: enable vertical scroll position
+// SR=0: enable CGRAM address (basic instruction)
+#define REVERSE_BY_LINE         0x04 // Select 1 out of 4 line (in DDRAM) and decide whether to
+// reverse the display by toggling this instruction
+// R1,R0 initial value is 0,0
+#define EXTENDED_FUNCTION_SET   0x20 // DL=1 :8-bit interface, DL=0 :4-bit interface
+// RE=1: extended instruction, RE=0: basic instruction
+#define SET_SCROLL_ADDRESS      0x40 // G=1 :graphic display ON, G=0 :graphic display OFF
+#define SET_GRAPHIC_RAM_ADDRESS 0x80 // Set GDRAM address to address counter (AC)
+// Set the vertical address first and followed the horizontal
+// address by consecutive writings
+// Vertical address range: AC5&#65533;cAC0, Horizontal address range: AC3&#65533;cAC0
+
+// Parameters regarding Instruction Sets 1 & 2
+#define DISPLAY_SHIFT_S         0x01 // Set 1, ENTRY_MODE_SET
+#define INCREASE_DECREASE_ID    0x02 // Set 1, ENTRY_MODE_SET
+#define CURSOR_BLINK_ON_B       0x01 // Set 1, DISPLAY_CONTROL
+#define CURSOR_ON_C             0x02 // Set 1, DISPLAY_CONTROL
+#define DISPLAY_ON_D            0x04 // Set 1, DISPLAY_CONTROL
+#define SHIFT_RL                0x04 // Set 1, CURSOR_DISPLAY_CONTROL
+#define CURSOR_SC               0x08 // Set 1, CURSOR_DISPLAY_CONTROL
+#define EXTENDED_INSTRUCTION_RE 0x04 // Set 1, FUNCTION_SET; Set 2, EXTENDED_FUNTION_SET
+#define DATA_LENGTH_DL          0x10 // Set 1, FUNCTION_SET; Set 2, EXTENDED_FUNTION_SET
+#define REVERSE_BY_LINE_R0      0x01 // Set 2, REVERSE_BY_LINE
+#define REVERSE_BY_LINE_R1      0x02 // Set 2, REVERSE_BY_LINE
+#define EN_VERTICAL_SCROLL_SR   0x01 // Set 2, SCROLL_OR_RAM_ADDR_SEL
+#define GRAPHIC_ON_G            0x02 // Set 2, EXTENDED_FUNTION_SET
+
+#define BUSY_FLAG_BF            0x80
+
+/*********************************************************************************/
+
+class ST7920  {
+public:
+    /**
+    *@brief Constructor, initializes the lcd on the respective pins.
+    *@param control pins     RS,RW,E
+    *@param databus        DB0-DB7    data pins
+    *@return none
+    *@  ----> pin PSB @ Vdd for 8/4-bit parallel bus mode.
+    */
+    ST7920 (PinName _RS, PinName _RW, PinName _E, PinName DB0, PinName DB1, PinName DB2, PinName DB3, PinName DB4, PinName DB5, PinName DB6, PinName DB7);
+
+
+    /**
+     *@brief Display initialision
+     *
+     *@param none
+     *@return none
+     *
+     */
+    void InitDisplay(void);
+
+
+    /**
+     *@brief Enable Extended Instructions, RE=1, Graphic on
+     *
+     *@param none
+     *@return none
+     *
+     */
+    void SetGraphicsMode(void);
+    
+        /**
+     *@brief Go back to Basic Instructions, RE=0
+     *
+     *@param none
+     *@return none
+     *
+     */
+    void SetTextMode(void);
+
+    /**
+    *@brief Sets DDRAM address counter (AC) to '00H'
+    *@basic function, clear screen
+    *@param none
+    *@return none
+    *
+    */
+    void ClearScreen(void);
+    
+    void ReturnHome(void);
+    void Standby(void);
+
+    /**
+    *@brief Places a string on the screen with internal characters from the HCGROM
+    *@
+    *@param row, column, string
+    *@return none
+    *
+    */
+/*
+* DESCRIPTIONS:
+* Place a string to the GLCD controller on the specified row and column.
+* Due to the design of the ST7920 controller (to accomodate Mandarin and Cyrillic), you must place the text on the column
+* according to the numbers above the diagram below:
+*
+* |--0--|--1--|--2--|...      ...|--7--|
+* +--+--+--+--+--+---------------------+
+* |H |e |l |l |o |  ...                | <- row 0 (address 0x80)
+* +--+--+--+--+--+---------------------+
+* |T |h |i |s |  |i ...                   | <- row 1 (address 0x90)
+* +--+--+--+--+--+---------------------+
+* |* |* |* |* |* |* ...                   | <- row 2 (address 0x88)
+* +--+--+--+--+--+---------------------+
+* |- |- |- |- |- |- ...                   | <- row 3 (address 0x98)
+* +--+--+--+--+--+---------------------+ 
+*
+* Example:
+* Writing "abc" onto the 1st column, and 1st row:
+* |--0--|--1--|--2--|...      ...|--7--|
+* +--+--+--+--+--+---------------------+
+* |  |  |  |  |  |  ...                | <- row 0 (address 0x80)
+* +--+--+--+--+--+---------------------+
+* |  |  |a |b |c |  ...                   | <- row 1 (address 0x90)
+* +--+--+--+--+--+---------------------+
+* |  |  |  |  |  |  ...                   | <- row 2 (address 0x88)
+* +--+--+--+--+--+---------------------+
+* |  |  |  |  |  |  ...                   | <- row 3 (address 0x98)
+* +--+--+--+--+--+---------------------+ 
+*
+******************************************************************************
+*/
+    void DisplayString(int Row,int Column, unsigned char *ptr,int length);
+
+    /**
+    *@brief Places a character on the screen with an internal character from the HCGROM
+    *@
+    *@param row, column, character
+    *@return none
+    *
+    */    
+/*
+* DESCRIPTIONS:
+* Place a character to the GLCD controller on the specified row and column.
+* Due to the design of the ST7920 controller (to accomodate Mandarin and Cyrillic), you must place the text on the column
+* according to the numbers above the diagram below:
+* 
+* |--0--|--1--|--2--|...      ...|--7--|
+* +--+--+--+--+--+---------------------+
+* |H |e |l |l |o |  ...                | <- row 0 (address 0x80)
+* +--+--+--+--+--+---------------------+
+* |T |h |i |s |  |i ...                   | <- row 1 (address 0x90)
+* +--+--+--+--+--+---------------------+
+* |* |* |* |* |* |* ...                   | <- row 2 (address 0x88)
+* +--+--+--+--+--+---------------------+
+* |- |- |- |- |- |- ...                   | <- row 3 (address 0x98)
+* +--+--+--+--+--+---------------------+ 
+*
+* Example:
+* Writing 'a' onto the 1st column, and 1st row:
+* |--0--|--1--|--2--|...      ...|--7--|
+* +--+--+--+--+--+---------------------+
+* |  |  |  |  |  |  ...                | <- row 0 (address 0x80)
+* +--+--+--+--+--+---------------------+
+* |  |  |a |  |  |  ...                   | <- row 1 (address 0x90)
+* +--+--+--+--+--+---------------------+
+* |  |  |  |  |  |  ...                   | <- row 2 (address 0x88)
+* +--+--+--+--+--+---------------------+
+* |  |  |  |  |  |  ...                   | <- row 3 (address 0x98)
+* +--+--+--+--+--+---------------------+ 
+* 
+*******************************************************************************
+*/
+    void DisplayChar(int Row, int Column,int inpChr);
+    
+     /**
+    *@brief Fills the screen with the graphics described in a 1024-byte array
+    *@
+    *@param bitmap 128x64, bytes horizontal
+    *@return none
+    *
+    */
+    void FillGDRAM(unsigned char *bitmap);
+    
+    //same as FILLGDRAM, but turnes all the bytes from vertical to horizontal
+    //now pictures for eg KS0108 can be used
+    void FillGDRAM_Turned(unsigned char *bitmap);
+    
+    /**
+    *@brief Clears the graphics RAM of the screen
+    *@writes all pixels to zero
+    *@param none
+    *@return none
+    *
+    */
+    void ClearGDRAM(void);
+    
+
+    
+private:
+    BusInOut DB;
+    DigitalOut RS;
+    DigitalOut RW;
+    DigitalOut E;
+    //DigitalOut RST;
+    
+    unsigned char screen[1024];
+    
+    unsigned int ByteReadLCD(void);
+
+    void ByteWriteLCD(unsigned int data);
+
+    /**
+    *@brief Write instruction to the controller.
+    *@param Command     command to send to the controller
+    *@return none
+    *
+    */
+    void  WriteInstruction(unsigned int Command);
+
+    /**
+     *@brief Write data byte to the controller.
+     *@param data     data send to the controller chip (DDRAM/CGRAM/GDRAM)
+     *@return none
+     *
+     */
+    void WriteRAM(unsigned int data);
+
+    /**
+     *@brief Read busy flag, keep looking
+     *@param none
+     *@return none
+     *
+     */
+    void ReadBusyFlag(void);
+
+    /**
+     *@brief Read Address Counter (AC) from the controller.
+     *@param none
+     *@return read Address Counter (AC) from the controller chip (DDRAM/CGRAM/GDRAM)
+     *
+     */
+    unsigned int Read_AC(void);
+
+    /**
+     *@brief Read data byte from the controller.
+     *@param none
+     *@return data read from the controller chip (DDRAM/CGRAM/GDRAM)
+     *
+     */
+    unsigned int ReadRAM(void);
+};
+#endif
\ No newline at end of file