I2C 'Busy' issue
Sometimes the data sent to the first line of the display is missing when it is sent after a 'Clear Screen' command or after setting the cursor position using the 'Set DDRAM address' command.
This display uses the ST7036 controller and the datasheet for that controller states in the "I2C Protocol" section on page 18:
Busy Flag (BF)
When BF = "High”, it indicates that the internal operation is being processed. So during this time the next
instruction cannot be accepted. BF can be read, when RS = Low and R/W = High (Read Instruction Operation),
through DB7 port. Before executing the next instruction, be sure that BF is not High.
However, that same document also indicates that the I2C interface is write-only. Under the function description for the I2C interface on page 14 it states:
I2C interface
It just only could write Data or Instruction to ST7036 by the IIC Interface.
It could not read Data or Instruction from ST7036 (except Acknowledge signal).
So, the specification states that before executing an instruction you need to check the "Busy Flag" by executing a "Read Instruction Operation" (I2C read with RS=Low and R/W=High). But it also says that the device cannot be read. When I tried executing a "Read Instruction Operation" I always get a value of 0xFF.
Currently I am trying to avoid the problems that I have seen by executing a delay after a "Clear Screen" command.
What is the correct solution?
-
Before I address the clear display command, first I would like to clear up the confusion regarding the i2c interface.
The ST7036 is a dot matrix LCD controller that can be used in several different ways. There are several pins of the controller which are not accessible through the displays connections. In particular, there are a couple of pins that dictate which interface is to be used. Looking through the datasheet, you will see it can use a 4-bit/8-bit parallel , 4 line SPI, or i2c interface. For this display, it is configured for use of an i2c interface only. Anywhere in that datasheet where it talks about reading or checking busy flags, it is not applicable when using i2c (which is why it states what you have copied from page 14). Therefore, there should be no read instructions used with this display.
As for the clear display command, if there is not a delay in place after you execute it, you will see exactly what you described. As indicated in the ST7036 datasheet, this command (and the return home command) requires more execution time than the others. To be safe , I like to use a 2ms delay after I execute either of these commands.
I have replicated the issue with an Arduino, and have posted my code below:#include <Wire.h>
int RES = 22;
int ASDA = 20;
int ASCL = 21;
unsigned char text1[]={" Newhaven Display "};
unsigned char text2[]={" Clear Display Test "};
unsigned char text3[]={" March 27, 2014 "};
unsigned char text4[]={" Michael LaVine "};
const char slave2w = 0x3C; //(0x78 shifted over 1 bit)
const char comsend = 0x00;
const char datasend = 0x40;
const char line2 = 0xC0;
void show(unsigned char *text)
{
int n, d;
d=0x00;
Wire.beginTransmission(slave2w);
Wire.write(datasend);
for(n=0;n<20;n++)
{
Wire.write(*text);
++text;
}
Wire.endTransmission();
}
void nextline(void)
{
Wire.beginTransmission(slave2w);
Wire.write(comsend);
Wire.write(line2);
Wire.endTransmission();
}
void cleardisplay(void)
{
Wire.beginTransmission(slave2w);
Wire.write(comsend);
Wire.write(0x01);
Wire.endTransmission();
}
void CiZ_init()
{
Wire.beginTransmission(slave2w);
Wire.write(comsend);
Wire.write(0x39);
delay(1);
Wire.write(0x14);
Wire.write(0x70);
Wire.write(0x5E);
Wire.write(0x6D);
Wire.write(0x0C);
Wire.write(0x01);
Wire.write(0x06);
Wire.endTransmission();
}
void setup()
{
pinMode(RES, OUTPUT);
pinMode(ASCL, OUTPUT);
pinMode(ASDA, OUTPUT);
digitalWrite(RES, HIGH);
delay(10);
digitalWrite(ASCL, LOW);
digitalWrite(ASDA, LOW);
delay(10);
Wire.begin();
delay(10);
CiZ_init();
delay(5);
}
void loop()
{
show(text1);
nextline();
show(text2);
delay(1500);
cleardisplay();
delay(2);
show(text3);
nextline();
show(text4);
delay(1500);
cleardisplay();
delay(2);
}I commented out the lines where you see delay(2); in the main loop, and saw the issue you are referring to. I then uncommented these delays and ran the code again, and the display worked perfectly.
0
Please sign in to leave a comment.
Comments
1 comment