近段时间做一个项目,要调试3.2寸320x820分辨率的LCD。在此做下记录:
屏规格书如上图
屏的主要接口如上图
1.查看屏的规格书,如图所示,需要8836和st7701s通讯,方式是3线SPI。
2.通讯接口SDA,SCK,CS。
3.RGB接口就比较简单了。
下面贴一些主要的函数:
-
初始化函数,对屏进行复位。在初始化函数里面读屏的ID,如果读到就证明通讯成功了撒。根据描述,读DA,DB,DC也是可以的嘛,读完ID后适当延时再去发命令和数据,不然显示会不正常的,调通之后读不读ID不影响后面发的命令和数据。
-
初始化成功后就发送命令和数据了,按照屏厂给的参数填数据发送就可以了。
spi_st7701s_WriteCommand( BYTE i);
spi_st7701s_WriteData( BYTE i);屏厂给的格式大概是这样滴:
W_C (0xFF);
W_D (0x77);
W_D (0x01);
W_D (0x00);
W_D (0x00);
W_D (0x13); -
我的程序里是用的这几个管脚
P3_3 SPI_CS PIN117
P1_0 SPI_DSIO PIN60
P1_1 SPI_SCLK PIN61D/C 第一位 D/C = 0,Commond
D/C = 1,Data
发送完一个字节后,CS必须拉高,如果不拉高接着就是读取数据。SPI时序 eg: send com:0x11 接逻辑分析后再补张逻辑分析仪捉到的图吧。
#define SPI_DSIO P1_0
#define SPI_SCLK P1_1
#define SPI_CS P3_3
#define RST_PANEL P3_7
void ST7701S_Init(void)
{
BYTE ID1,ID2,ID3;
#if 1
RST_PANEL = 1;
delay1ms(100);
#endif
RST_PANEL = 0;
delay1ms(200);
RST_PANEL = 1;
#if 0
ID1 = Spi_St7701s_ReadByte(0xDA);
ID2 = Spi_St7701s_ReadByte(0xDB);
ID3 = Spi_St7701s_ReadByte(0xDC);
Printf("\nLCD ID:0x%bx 0x%bx 0x%bx", ID1,ID2,ID3);
#endif
}
static BYTE Spi_St7701s_ReadByte(BYTE id)
{
BYTE i,tmp = 0;
SPI_CS = 0;
SPI_DSIO = 0;
SPI_SCLK = 0;
SPI_Dealy(1);
SPI_SCLK = 1;
SPI_Dealy(1);
spi_st7701s_SendData(id);
//先写寄存器地址0x04
SPI_SCLK = 0;
SPI_DSIO = 1;//设为高阻态输入模式?
SPI_Dealy(1);
for(i = 0;i < 8;i++)
{
SPI_SCLK = 1;
tmp <<= 1; //移位
if(SPI_DSIO) tmp |= 1; //读取一位数据
SPI_SCLK = 0;
}
SPI_SCLK = 1;
SPI_Dealy(1);
SPI_SCLK = 0;
SPI_DSIO = 1;
SPI_CS = 1;
return tmp; //返回数据
}
static void spi_st7701s_SendData(BYTE i)
{
unsigned char n;
for(n = 0; n < 8; n++) {
if(i & 0x80) {
SPI_DSIO = 1;
} else {
SPI_DSIO = 0;
}
i<<= 1;
SPI_SCLK = 0;
SPI_Dealy(1);
SPI_SCLK = 1;
SPI_Dealy(1);
}
}
static void spi_st7701s_WriteCommand( BYTE i)
{
SPI_CS = 0;
SPI_DSIO = 0;
SPI_SCLK = 0;
SPI_Dealy(1);
SPI_SCLK = 1;
SPI_Dealy(1);
spi_st7701s_SendData(i);
SPI_CS = 1;
}
static void spi_st7701s_WriteData( BYTE i)
{
SPI_CS = 0;
SPI_DSIO = 1;
SPI_SCLK = 0;
SPI_Dealy(1);
SPI_SCLK = 1;
SPI_Dealy(1);
spi_st7701s_SendData(i);
SPI_CS = 1;
}
关于程序还有一种发送命令和数据的做法
typedef struct _st7701s_reg {
BYTE comm;
BYTE val[20];
BYTE len;
}st7701s_reg;
static CONST st7701s_reg st7701s_organize[] = {
/*comm val len*/
{0x11,NULL,NULL},
{0xFF,{0x77,0x01,0x00,0x00,0x10},5},
...//屏厂给的参数
};
static void Spi_WriteC_D(st7701s_reg *st7701s_reg_dat)
{
#if 1
BYTE i,j;
for (i = 0; i < 36; ++i)//LEN_ARRAY(st7701s_organize, struct st7701s_reg)
{
spi_st7701s_WriteCommand(st7701s_reg_dat[i].comm);
if(st7701s_reg_dat[i].comm == 0x11)
{ delay1ms(120);}
Printf(" \nWriteCommand: %bx,datalen:%bd\n", st7701s_reg_dat[i].comm,st7701s_reg_dat[i].len);
for (j = 0; j < st7701s_reg_dat[i].len; ++j)//LEN_ARRAY(st7701s_organize[i].val, BYTE)
{
if (st7701s_reg_dat[i].comm == st7701s_reg_dat[i].val[j])
{
if (st7701s_reg_dat[i].val[j] == 0xB9)
{
//LOG("Now Delay 10 ms!\n");
delay1ms(10);
}
break;
}
//if(st7701s_reg_dat[i].val[j]!=NULL)
spi_st7701s_WriteData(st7701s_reg_dat[i].val[j]);
if(st7701s_reg_dat[i].comm == 0xD0)
delay1ms(100);
Printf(" WriteData: %bx", st7701s_organize[i].val[j]);
}
//Printf(" WriteData: %bx", st7701s_reg_dat[i].val);
}
#endif
}
#endif
这个是之前在网上找的例程,想贴个连接没找着,找着再说吧。我试过了,好像有点问题,虽然发送数据是一样的,但是屏显示的效果有点差异,可能是延时问题,有时间再看看这个问题。