用TW8836驱动ST7701S TTL屏调试记录

近段时间做一个项目,要调试3.2寸320x820分辨率的LCD。在此做下记录:

用TW8836驱动ST7701S TTL屏调试记录_第1张图片屏规格书如上图
用TW8836驱动ST7701S TTL屏调试记录_第2张图片
屏的主要接口如上图

1.查看屏的规格书,如图所示,需要8836和st7701s通讯,方式是3线SPI。
2.通讯接口SDA,SCK,CS。
3.RGB接口就比较简单了。

下面贴一些主要的函数:

  1. 初始化函数,对屏进行复位。在初始化函数里面读屏的ID,如果读到就证明通讯成功了撒。根据描述,读DA,DB,DC也是可以的嘛,读完ID后适当延时再去发命令和数据,不然显示会不正常的,调通之后读不读ID不影响后面发的命令和数据。
    用TW8836驱动ST7701S TTL屏调试记录_第3张图片

  2. 初始化成功后就发送命令和数据了,按照屏厂给的参数填数据发送就可以了。

    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);

  3. 我的程序里是用的这几个管脚
    P3_3 SPI_CS PIN117
    P1_0 SPI_DSIO PIN60
    P1_1 SPI_SCLK PIN61

    D/C 第一位 D/C = 0,Commond
    D/C = 1,Data
    发送完一个字节后,CS必须拉高,如果不拉高接着就是读取数据。

    SPI时序 eg: send com:0x11 接逻辑分析后再补张逻辑分析仪捉到的图吧。
    用TW8836驱动ST7701S TTL屏调试记录_第4张图片

#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

这个是之前在网上找的例程,想贴个连接没找着,找着再说吧。我试过了,好像有点问题,虽然发送数据是一样的,但是屏显示的效果有点差异,可能是延时问题,有时间再看看这个问题。

你可能感兴趣的:(用TW8836驱动ST7701S TTL屏调试记录)