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
Revision 0:1a97e0243dbc, committed 2012-06-29
- 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 |
diff -r 000000000000 -r 1a97e0243dbc st7920.cpp --- /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); + } + } + } +}
diff -r 000000000000 -r 1a97e0243dbc st7920.h --- /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 �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�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�cAC0, Horizontal address range: AC3�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