I'm trying to get a ST7920 display (12864ZW) working in serial mode.
This is a 128x64 display, so quite a lot of information can be displayed.
I'm using serial mode, so number of GPIO's are limited to the minimum.
A fist try was with SPI, but that didn't work, so I'm trying to bitbang the serial data first, and after that I can try SPI.
I've found this example code for AVR as a starting point:
http://parenthetic.blogspot.be/2011/12/ ... 0-lcd.html
My code running on the Pi:
Code: Select all
#include <wiringPi.h>
#include <wiringShift.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define P_RS 8 //CE0
#define P_RW 10 //MOSI
#define P_E 11 //SCLK
#define P_RST 25 //GPIO25
#define D_SYNC 0b11111000
#define D_RW 0b00000100
#define D_RS 0b00000010
#define D_FSET 0b00100000
#define D_8BIT 0b00010000
#define D_DCONT 0b00001000
#define D_DON 0b00000100
#define D_CON 0b00000010
#define D_BON 0b00000001
#define D_ENMOD 0b00000100
#define D_INC 0b00000010
#define D_CLR 0b00000001
void initGPIO();
void initLCD();
void resetLCD();
void clearLCD();
void instrLCD(uint8_t);
void dataLCD(uint8_t);
void shiftOutH(uint8_t, uint8_t, uint8_t, uint8_t);
int main(int argc, char **argv)
{
//if(wiringPiSetup() == -1)
if(wiringPiSetupGpio() == -1)
{
printf("wiringPiSetupGpio() failed\n");
return EXIT_FAILURE;
}
initGPIO();
delay(40);
initLCD();
instrLCD(0x80);
dataLCD('A');
return EXIT_SUCCESS;
}
void initGPIO()
{
pinMode(P_RS, OUTPUT); //CE0
digitalWrite(P_RS, LOW);
delay(100);
pinMode(P_RW, OUTPUT); //MOSI
digitalWrite(P_RW, LOW);
delay(100);
pinMode(P_E, OUTPUT); //SCLK
digitalWrite(P_E, HIGH);
delay(100);
pinMode(P_RST, OUTPUT); //RST
digitalWrite(P_RST, HIGH);
delay(100);
}
void initLCD()
{
delay(40); //Startup delay
resetLCD();
}
void resetLCD()
{
digitalWrite(P_RST, LOW);
delay(100);
digitalWrite(P_RST, HIGH);
delay(100); //40?
instrLCD(D_FSET | D_8BIT);
delayMicroseconds(100 - 72); //Delay 100 us needed, 72 done already
instrLCD(D_FSET | D_8BIT);
instrLCD(D_DCONT | D_DON);
delayMicroseconds(100 - 72); //Delay 100 us needed, 72 done already
clearLCD();
delayMicroseconds(10000 - 1600);
instrLCD(D_ENMOD | D_INC);
}
void clearLCD()
{
instrLCD(D_CLR);
delayMicroseconds(1600 - 72); //Delay 1.6 ms needed, 72 us done already
}
void instrLCD(uint8_t byte){
printf("instrLCD(0x%X): %u ms\n", byte, millis());
digitalWrite(P_RS, HIGH);
delay(100);
shiftOutH(P_RW, P_E, MSBFIRST, D_SYNC);
shiftOutH(P_RW, P_E, MSBFIRST, byte & 0xf0);
shiftOutH(P_RW, P_E, MSBFIRST, (byte << 4));
delay(100);
digitalWrite(P_RS, LOW);
delay(100);
delayMicroseconds(72); //Delay for most instructions
}
void dataLCD(uint8_t byte){
printf("dataLCD(0x%X): %u ms\n", byte, millis());
digitalWrite(P_RS, HIGH);
delay(100);
shiftOutH(P_RW, P_E, MSBFIRST, D_SYNC | D_RS);
shiftOutH(P_RW, P_E, MSBFIRST, byte & 0xf0);
shiftOutH(P_RW, P_E, MSBFIRST, (byte << 4));
delay(100);
digitalWrite(P_RS, LOW);
delay(100);
delayMicroseconds(72); //Delay for most data
}
void shiftOutH(uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val)
{
printf("shiftOutH(0x%X)\n", val);
int8_t i;
digitalWrite(cPin, HIGH); //To be shure idle = HIGH
delay(100);
if (order == MSBFIRST)
for(i = 7; i >= 0; i--)
{
digitalWrite(dPin, val & (1 << i));
delay(100);
digitalWrite(cPin, LOW);
delay(100);
digitalWrite(cPin, HIGH);
delay(100);
}
else
for(i = 0; i < 8; i++)
{
digitalWrite(dPin, val & (1 << i));
digitalWrite (cPin, LOW);
digitalWrite (cPin, HIGH);
}
}
Code: Select all
instrLCD(0x30): 680 ms
shiftOutH(0xF8)
shiftOutH(0x30)
shiftOutH(0x0)
instrLCD(0x30): 8492 ms
shiftOutH(0xF8)
shiftOutH(0x30)
shiftOutH(0x0)
instrLCD(0xC): 16302 ms
shiftOutH(0xF8)
shiftOutH(0x0)
shiftOutH(0xC0)
instrLCD(0x1): 24114 ms
shiftOutH(0xF8)
shiftOutH(0x0)
shiftOutH(0x10)
instrLCD(0x6): 31936 ms
shiftOutH(0xF8)
shiftOutH(0x0)
shiftOutH(0x60)
instrLCD(0x80): 39748 ms
shiftOutH(0xF8)
shiftOutH(0x80)
shiftOutH(0x0)
dataLCD(0x41): 47560 ms
shiftOutH(0xFA)
shiftOutH(0x40)
shiftOutH(0x10)
Wiring should be OK, and everything seems to work.
The datasheet of the module:
http://www.dfrobot.com/image/data/fit0021/st7920.pdf
Who can help please?
I've spent almost two days on this LCD now.
Thank you