硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2198|回复: 14
收起左侧

[技术讨论] 关于8080时序驱动ST7789V屏幕

[复制链接]

6

主题

27

回帖

45

积分

新手上路

积分
45
发表于 2024-6-13 09:29:08 | 显示全部楼层 |阅读模式

我这边使用的是AT32F403A系列的单片机,屏幕是2寸的触摸显示屏。显示屏是ST7789v的,8bit数据位的,我在使用8080时序去驱动屏幕的时候。在系统上跑程序能发现有的图案就是会乱跑然后导致整个屏幕上的其他图片都乱掉了,而在裸机跑也是没有任何问题的。最近,硬件就是将外部的flash W25Q64 挪到了里单片机比较近的地方就会出现这样的花屏效果,我不知道是什么引起的,因为在之前,我通过调整部分图片的坐标将图片乱跑的情况刚刚解决,显示也是没问题的。

同时我也注意到一篇帖子,在这篇帖子中,关于“benny”层主的介绍,使用8080就需要使用16bit传输数据,而不是8位?同时8080接口时,对图片取模不能使用高位在前吗?这是我在做之前没有注意到的地方。我想知道我目前调试屏幕时,屏幕上出现这样显示的问题是因为什么,不然我也没办法下手去解决。感谢各位的查看与回帖。
用GPIO模拟8080时序驱动st7796s屏幕, 花屏, 并且读 Read Display Pixel Format 错误
https://forum.anfulai.cn/forum.p ... 6&fromuid=71229
(出处: 硬汉嵌入式论坛)


[C] 纯文本查看 复制代码
#define USE_HORIZONTAL 0  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏


#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
#define LCD_W 240
#define LCD_H 320

#else
#define LCD_W 240
#define LCD_H 240
#endif

//#define	u8 unsigned char
//#define	u16 unsigned int
//#define	u32 unsigned long

   						  
//-----------------测试LED端口定义---------------- 

#define LED_ON GPIO_ResetBits(GPIOA,GPIO_Pin_15)
#define LED_OFF GPIO_SetBits(GPIOA,GPIO_Pin_15)

//-----------------OLED端口定义---------------- 
#define DATAOUT(x) GPIOD->ODR=x; //数据输出
#define DATAIN     GPIOD->IDR;   //数据输入
//#define DATAOUT(x)  DATAchange(x);
//#define DATAIN     GPIOE->IDR;   //数据输入

#define	LCD_RST_SET	GPIOB->BSRR=1<<3    //复位			  PB15
#define	LCD_CS_SET  GPIOA->BSRR=1<<15   //片选端口  	PB14
#define	LCD_DC_SET	GPIOC->BSRR=1<<10    //数据/命令   PB13
#define	LCD_WR_SET	GPIOC->BSRR=1<<11    //写数据	    PB12
#define	LCD_RD_SET	GPIOC->BSRR=1<<12    //读数据		  PB11

#define	LCD_RST_CLR	GPIOB->BRR=1<<3     //复位       PB15
#define	LCD_CS_CLR  GPIOA->BRR=1<<15     //片选端口    PB14
#define	LCD_DC_CLR	GPIOC->BRR=1<<10     //数据/命令   PB13
#define	LCD_WR_CLR	GPIOC->BRR=1<<11     //写数据	    PB12
#define	LCD_RD_CLR	GPIOC->BRR=1<<12     //读数据	    PB11




/******************************************************************************
      函数说明:LCD并行数据写入函数
      入口数据:dat  要写入的并行数据
      返回值:  无
******************************************************************************/
void LCD_Writ_Bus(u8 dat) 
{	
	LCD_CS_CLR;
	LCD_WR_CLR;
	DATAOUT(dat);
	LCD_WR_SET;
	LCD_CS_SET;
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(u8 dat)
{
	LCD_DC_SET;//写数据
	LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(u16 dat)
{
	LCD_DC_SET;//写数据
	LCD_Writ_Bus(dat>>8);
	LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(u8 dat)
{
	LCD_DC_CLR;//写命令
	LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:  无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
	if(USE_HORIZONTAL==0)
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
	else if(USE_HORIZONTAL==1)
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1+80);
		LCD_WR_DATA(y2+80);
		LCD_WR_REG(0x2c);//储存器写
	}
	else if(USE_HORIZONTAL==2)
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
	else
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1+80);
		LCD_WR_DATA(x2+80);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
}


/******************************************************************************
      函数说明:LCD初始化函数    模拟8080协议并口屏  FSMC引脚被占用
      入口数据:无
      返回值:  无
******************************************************************************/
void Lcd_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);	 //使能A端口时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOD, &GPIO_InitStructure);	  //初始化GPIOA
 	GPIO_SetBits(GPIOD,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;	           //RESET
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOB, &GPIO_InitStructure);	  //初始化GPIOA
 	GPIO_SetBits(GPIOB,GPIO_Pin_3);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;					 //CS
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOA, &GPIO_InitStructure);	  //初始化GPIOA
 	GPIO_SetBits(GPIOA,GPIO_Pin_15);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;					 //RS   WR   RD
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOC, &GPIO_InitStructure);	  //初始化GPIOA
 	GPIO_SetBits(GPIOC,GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;					 //RS   WR   RD
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
 	GPIO_Init(GPIOA, &GPIO_InitStructure);	  //初始化GPIOA
 	GPIO_SetBits(GPIOA,GPIO_Pin_11);
	GPIO_WriteBit(GPIOA,GPIO_Pin_11,Bit_RESET);//拉低使能
	


	LCD_RST_CLR;
	delay_ms(100);
	LCD_RST_SET;
//	OLED_BLK_Set();
	delay_ms(100);
	LCD_WR_REG(0x11);
	LCD_WR_DATA8(0x00);
	delay_ms(120);

//************* Start Initial Sequence **********// 
LCD_WR_REG(0x36);
if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
else LCD_WR_DATA8(0xA0);

	LCD_WR_REG(0x3A);			
	LCD_WR_DATA(0x05);



	LCD_WR_REG(0xB2);			
	LCD_WR_DATA(0x0C);
	LCD_WR_DATA(0x0C); 
	LCD_WR_DATA(0x00); 
	LCD_WR_DATA(0x33); 
	LCD_WR_DATA(0x33); 			

	LCD_WR_REG(0xB7); 
	LCD_WR_DATA8(0x35);  

	LCD_WR_REG(0xBB);
	LCD_WR_DATA8(0x19);

	LCD_WR_REG(0xC0);
	LCD_WR_DATA8(0x2C);

	LCD_WR_REG(0xC2);
	LCD_WR_DATA8(0x01);

	LCD_WR_REG(0xC3);
	LCD_WR_DATA8(0x12);   

	LCD_WR_REG(0xC4);
	LCD_WR_DATA8(0x20);  

	LCD_WR_REG(0xC6); 
	LCD_WR_DATA8(0x0F);    

	LCD_WR_REG(0xD0); 
	LCD_WR_DATA8(0xA4);
	LCD_WR_DATA8(0xA1);										  												  																								
	    
  
	LCD_WR_REG( 0xE0);     
	LCD_WR_DATA( 0xD0);   
	LCD_WR_DATA( 0x08);   
	LCD_WR_DATA( 0x0E);   
	LCD_WR_DATA( 0x09);   
	LCD_WR_DATA( 0x09);   
	LCD_WR_DATA( 0x05);   
	LCD_WR_DATA( 0x31);   
	LCD_WR_DATA( 0x33);   
	LCD_WR_DATA( 0x48);   
	LCD_WR_DATA( 0x17);   
	LCD_WR_DATA( 0x14);   
	LCD_WR_DATA( 0x15);   
	LCD_WR_DATA( 0x31);   
	LCD_WR_DATA( 0x34);   

	LCD_WR_REG( 0xE1);     
	LCD_WR_DATA( 0xD0);   
	LCD_WR_DATA( 0x08);   
	LCD_WR_DATA( 0x0E);   
	LCD_WR_DATA( 0x09);   
	LCD_WR_DATA( 0x09);   
	LCD_WR_DATA( 0x15);   
	LCD_WR_DATA( 0x31);   
	LCD_WR_DATA( 0x33);   
	LCD_WR_DATA( 0x48);   
	LCD_WR_DATA( 0x17);   
	LCD_WR_DATA( 0x14);   
	LCD_WR_DATA( 0x15);   
	LCD_WR_DATA( 0x31);   
	LCD_WR_DATA( 0x34);
	 

	LCD_WR_REG(0x21);

	LCD_WR_REG(0x29);
} 


/******************************************************************************
      函数说明:LCD清屏函数
      入口数据:无
      返回值:  无
******************************************************************************/
void LCD_Clear(u16 Color)
{
	u16 i,j;  	
	LCD_Address_Set(0,0,LCD_W-1,LCD_H-1);
    for(i=0;i<LCD_W;i++)
	 {
	  for (j=0;j<LCD_H;j++)
	   	{
        	LCD_WR_DATA(Color);	 			 
	    }

	  }
}
/******************************************************************************
      函数说明:显示图片
      入口数据:x,y起点坐标
                length 图片长度
                width  图片宽度
                pic[]  图片数组    
      返回值:  无
******************************************************************************/
void LCD_ShowPicture(u16 x,u16 y,u16 length,u16 width,const u8 pic[])
{
	u16 i,j;
	u32 k=0;
	LCD_Address_Set(x,y,x+length-1,y+width-1);
	for(i=0;i<length;i++)
	{
		for(j=0;j<width;j++)
		{
			LCD_WR_DATA8(pic[k*2]);
			LCD_WR_DATA8(pic[k*2+1]);
			k++;
		}
	}		
return;	
}

void LCD_Clear_def(u16 x,u16 y,u16 length,u16 width,u16 Color)
{
	u16 i,j;  	
   LCD_Address_Set(x,y,x+length-1,y+width-1);
    for(i=0;i<length;i++)
	 {
	  for (j=0;j<width;j++)
	   	{
        	LCD_WR_DATA(Color);	 			 
	    }

	  }
}


图1.初次在系统上跑,

图1.初次在系统上跑,

图2.flash靠近MCU后显示

图2.flash靠近MCU后显示

图3.裸机跑的界面

图3.裸机跑的界面
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118345
QQ
发表于 2024-6-13 10:19:30 | 显示全部楼层
有个地方可以测试下,不配置使用SPI Flash,在系统下是不是正常的。
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-13 10:24:25 | 显示全部楼层
eric2013 发表于 2024-6-13 10:19
有个地方可以测试下,不配置使用SPI Flash,在系统下是不是正常的。

你好,这个是什么意思呢,意思是不使用SPI去读取Flash,在系统中直接用图片数组去显示一张图片的意思吗
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-13 11:47:42 | 显示全部楼层
eric2013 发表于 2024-6-13 10:19
有个地方可以测试下,不配置使用SPI Flash,在系统下是不是正常的。

我刚刚测试了一下直接去显示图片数据,发现好像不会有显示。那这会是什么问题
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118345
QQ
发表于 2024-6-14 13:04:43 | 显示全部楼层
cmz 发表于 2024-6-13 11:47
我刚刚测试了一下直接去显示图片数据,发现好像不会有显示。那这会是什么问题

那有点奇怪。有几个问题,我确认下
1、你的程序是在内部运行,而图片是从SPI Flash读取的,是这样吧
2、裸机下测试这个程序没问题,但OS下不行,且最近的硬件设计是将SPI Flash换了个里PCB比较近的位置。

难道是你的程序多任务环境下运行不同步导致的

回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-14 15:27:08 | 显示全部楼层
eric2013 发表于 2024-6-14 13:04
那有点奇怪。有几个问题,我确认下
1、你的程序是在内部运行,而图片是从SPI Flash读取的,是这样吧
2 ...

第一点跟第二点都是你说的这样,最近的硬件是改了电机部分的东西,关于屏幕跟Flash改动就Flash移动了一下位置。而且现在能看到屏幕中下部分有大片花屏,程序刷不到这块花屏的地方,我觉得有可能是有什么干扰到才会这样或者是其他的某些原因。
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-14 15:48:54 | 显示全部楼层
eric2013 发表于 2024-6-14 13:04
那有点奇怪。有几个问题,我确认下
1、你的程序是在内部运行,而图片是从SPI Flash读取的,是这样吧
2 ...

这不能是我取模时把图片设置为高位在前的原因吧,而且现在我就是把全部图片都不显示,仅仅初始化屏幕,仍然能看见底下的花屏。是不是需要对GRAM进行操作
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118345
QQ
发表于 2024-6-15 08:57:16 | 显示全部楼层
cmz 发表于 2024-6-14 15:48
这不能是我取模时把图片设置为高位在前的原因吧,而且现在我就是把全部图片都不显示,仅仅初始化屏幕,仍 ...

你们这个显示屏是不是排线接的,有没有可能是这个有干扰导致的。
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-17 10:23:55 | 显示全部楼层
eric2013 发表于 2024-6-15 08:57
你们这个显示屏是不是排线接的,有没有可能是这个有干扰导致的。

的确是排线接的,看原理图基本上是直连,中间也就用了2个0R电阻,我用万用表测过没有虚焊什么的
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118345
QQ
发表于 2024-6-18 08:49:05 | 显示全部楼层
cmz 发表于 2024-6-17 10:23
的确是排线接的,看原理图基本上是直连,中间也就用了2个0R电阻,我用万用表测过没有虚焊什么的

不知道你的线长不长,之前有个客户他是线有干扰,显示有错位,弄了个锡箔纸包裹,效果好了很多。
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-18 08:52:38 | 显示全部楼层
eric2013 发表于 2024-6-18 08:49
不知道你的线长不长,之前有个客户他是线有干扰,显示有错位,弄了个锡箔纸包裹,效果好了很多。

线也就小手指头这么长,可能都不到2-3cm
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118345
QQ
发表于 2024-6-18 09:04:02 | 显示全部楼层
cmz 发表于 2024-6-18 08:52
线也就小手指头这么长,可能都不到2-3cm

那看来问题不在这里。
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-18 09:06:47 | 显示全部楼层
大概定位到问题了。先通过逻辑分析仪去看了CS跟WR引脚的波形,发现两个引脚输出的波形中间有100ns的延时(低电平高电平转换中间一边100ns,两边就200ns),无论是裸机或是系统都存在这个问题,不过在系统上面由于采样频率不够后面使用的示波器进行采集,可以看到CS跟WR引脚存在明显的延时的现象,同时输出的数据线输出信号也没有开始于WR低电平期间。后面用了在CS跟WR引脚电平转换的时候加了延时以后的波形就好了一点,屏幕的显示也正常了,但是刷新会慢。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118345
QQ
发表于 2024-6-19 09:22:04 | 显示全部楼层
cmz 发表于 2024-6-18 09:06
大概定位到问题了。先通过逻辑分析仪去看了CS跟WR引脚的波形,发现两个引脚输出的波形中间有100ns的延时( ...

谢谢告知最终问题原因。
回复

使用道具 举报

6

主题

27

回帖

45

积分

新手上路

积分
45
 楼主| 发表于 2024-6-19 15:50:58 | 显示全部楼层
eric2013 发表于 2024-6-19 09:22
谢谢告知最终问题原因。

共同学习
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-9-27 16:43 , Processed in 0.055805 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表