⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd_driver.c

📁 STM32+ov7670
💻 C
📖 第 1 页 / 共 2 页
字号:
# include "LCD_Driver.h"
# include "Delay.h"
# include "LCD_Driver.h"
# include "MyUSART.h"
////////////////////////////////////////////////////////////////////////////////
//数据输出,包括寄存器内容和GRAM数据内容			
//将用宏定义代替,说明:							
//  LCD_DATA_OUT()将一个16位数据输出到数据总线, 	
//被写寄存器和写GRAM(写像素点)的函数调用,移植时 	
//根据数据接口是8位或16位更改该函数(或称宏定义)		
////////////////////////////////////////////////////////////////////////////////
void LCD_DATA_OUT(u16 data)
{
	/*
	//默认为8位数据端口写高8位			
	DATA_L_PORT = (unsigned char)(data>>8);			
	LCD_WR_L;
	
	LCD_WR_H;
	//写低8位							
	DATA_L_PORT = (unsigned char)data;			
	LCD_WR_L;
	
	LCD_WR_H;
	*/
	
	//16位数据接口
	DATAOUT(data);
	LCD_WR_L;
	LCD_WR_H;
}
////////////////////////////////////////////////////////////////////////////////
//数据输入,包括寄存器内容和GRAM数据内容		 	
//说明:											 	
//  LCD_DATA_IN()将一个16位数据从数据总线上读取  	
//被读寄存器和读GRAM(读像素点)的函数调用,移植时  	
//根据数据接口是8位或16位更改该函数(可用内联函数)	
////////////////////////////////////////////////////////////////////////////////
u16 LCD_DATA_IN(void)
{
	u16 temp = 0;
	/*
	DATA_L_IN;
	
	LCD_RD_L;									//读有效						
	LCD_RD_H;
	temp = DATA_L_PIN;							//读取高字节					
	
	LCD_RD_L;									//读有效						
	LCD_RD_H;
	temp <<= 8;
	temp |= DATA_L_PIN;							//读取低字节					
	
	DATA_L_OUT;
	*/
	//置为输入
	GPIOC->CRL = 0x88888888; //PC0-7  上拉输入
	GPIOB->CRH = 0X88888888; // PB8-15上拉输入
	GPIOB->ODR |= 0XFF00;    //全部输出高
	GPIOC->ODR |= 0X00FF; 
	
	LCD_RD_L;									//读有效						
	LCD_RD_H;
	temp = DATAIN;	
	
	GPIOC->CRL = 0X33333333; //PC0-7  上拉输出
	GPIOB->CRH = 0X33333333; //PB8-15 上拉输出
	GPIOB->ODR |= 0XFF00;    //全部输出高
	GPIOC->ODR |= 0X00FF;
	return temp;
}
//写LCD缓存命令,视需要更改0x0022的值,一般LCD驱动
//IC都使用的该命令								
void LCD_WriteGRAM_EN(void)
{
	LCD_CS_L;									//选中片选						
	
	LCD_RS_L;									//命令读写控制RS->0有效			
	LCD_DATA_OUT(0x0022);						//写入寄存器地址				
	LCD_RS_H;
}
//读LCD缓存命令,视需要更改0x0022的值,一般LCD驱动
//IC都使用的该命令								
void LCD_ReadGRAM_EN(void)
{
	LCD_CS_L;									//选中片选						
	
	LCD_RS_L;									//命令读写控制RS->0有效			
	LCD_DATA_OUT(0x0022);						//写入寄存器地址				
	LCD_RS_H;
}
////////////////////////////////////////////////////////////////////////////////
//  LCD_SetCursor ->设置读写指针				
//  该函数在移植时视需要修改,一般驱动IC使用了20H
//和21H分别设置GARM的x和y地址					
////////////////////////////////////////////////////////////////////////////////
void LCD_SetCursor(u16 x,u16 y)
{	//													   	*-------->x			
  	LCD_WriteRegister(0x0020, x); // 行				   		|		(H 127)		
  	LCD_WriteRegister(0x0021, y); // 列				   		|					
	///////////////////////////////							|					
	//R61514屏没有20H寄存器,xy坐标通过21H寄存器转化	   	|					
	//完成,公式:y*256 + x,参见手册R21H寄存器描述		   	V(V 159)			
# if R61514_EN 		> 0		
	LCD_WriteRegister(0x0021,(y << 8) + x);
# endif
}

////////////////////////////////////////////////////////////////////////////////
//  LCD_WriteRegister()->写寄存器												
//  写寄存器,LCD i80接口标准,RS为低时写寄存器IR	
//(寄存器指针),将index的值赋给他;RS为高时写数据,
//将data的值赋给IR指向的寄存器,该函数是i80接口上
//层应用,移植时不用修改							
////////////////////////////////////////////////////////////////////////////////
void LCD_WriteRegister(u16 index, u16 data)
{
////////////////////////////////////////////////////////////////////////////////
  	// 对于8位模式,则数据端口要进行两次操作,下图是16位模式情况下的操作   //
  	// nCS       ----\__________________________________________/-------  //
  	// RS        ------\____________/-----------------------------------  //
  	// nRD       -------------------------------------------------------  //
  	// nWR       --------\_______/--------\_____/-----------------------  //
  	// DB[0:15]  ---------[index]----------[data]-----------------------  //
  	//                                                                    //
////////////////////////////////////////////////////////////////////////////////
	LCD_CS_L;									//选中片选						
	
	LCD_RS_L;									//命令读写控制RS->0有效			
	LCD_DATA_OUT(index);						//先写入寄存器地址				
	
	LCD_RS_H;									//数据读写控制RS->1有效			
	LCD_DATA_OUT(data);
	
	LCD_CS_H;									//关闭片选						
}

////////////////////////////////////////////////////////////////////////////////
//  LCD_ReadRegister()->读寄存器												
//  读寄存器,LCD i80接口标准,RS为低时写寄存器IR	
//(寄存器指针),将index的值赋给他;RS为高时读数据,
//将data的值赋给IR指向的寄存器,该函数是i80接口上
//层应用,移植时不用修改							
////////////////////////////////////////////////////////////////////////////////
u16 LCD_ReadRegister(u16 index)
{
////////////////////////////////////////////////////////////////////////////////
  	// 对于8位模式,则数据端口要进行两次操作,下图是16位模式情况下的操作   //
  	// nCS       ----\__________________________________________/-------  //
  	// RS        ------\____________/-----------------------------------  //
  	// nRD       -------------------------\_____/-----------------------  //
  	// nWR       --------\_______/--------------------------------------  //
  	// DB[0:15]  ---------[index]----------[data]-----------------------  //
  	//                                                                    //
////////////////////////////////////////////////////////////////////////////////
	u16 temp = 0;
  	LCD_CS_L;									//选中片选						
	
	LCD_RS_L;									//命令读写控制RS->0有效			
	LCD_DATA_OUT(index);						//写入寄存器地址				
	
	LCD_RS_H;									//数据读写控制RS->1有效			
	temp = LCD_DATA_IN();
	LCD_CS_H;									//关闭片选						
	return temp;
}

////////////////////////////////////////////////////////////////////////////////
//  LCD_DrawPoint()->画点函数					
//  该函数先设置GARM地址,然后发送写命令,接着再将
//color的值赋给GRAM中对应的地址.该函数是上层应用
//移植时不用修改								
////////////////////////////////////////////////////////////////////////////////
void LCD_DrawPoint(u16 x, u16 y, u16 color)
{
	if ((x > X_END) || (y > Y_END)) 			//显示不能超过最大坐标值		
	{
		return;
	}
	LCD_SetCursor(x, y);
	
	LCD_WriteGRAM_EN();
	LCD_DATA_OUT(color);
	LCD_WR_END();
}
////////////////////////////////////////////////////////////////////////////////
//  LCD_GetPoint()->读点函数					
//  该函数先设置GARM地址,然后发送写命令,接着是一
//个哑操作,该哑操作根据8位或16位接口需要更改宏定
//义.该函数是上层应用移植时不用修改				
////////////////////////////////////////////////////////////////////////////////
u16 LCD_GetPoint(u16 x, u16 y)
{
////////////////////////////////////////////////////////////////////////////////
  	// 对于8位模式,则数据端口要进行两次操作,下图是16位模式情况下的操作   //
  	// nCS       ----\__________________________________________/-------  //
  	// RS        ------\____________/-----------------------------------  //
  	// nRD       -------------------------\_____/------\_____/----------  //
  	// nWR       --------\_______/--------------------------------------  //
  	// DB[0:15]  ---------[Address]-------[Dummy]-------[data]----------  //
  	// 注意:在读GRAM时,要先设置读地址,再写读命令,然后是Dummy Read,最后 //
	//      才是数据。同时,在8位模式下,Dummy Read 是一个Word的时间,意味//
	//		着RD要产生2次上升沿,最后读回来的数据还要进行转换			  //
////////////////////////////////////////////////////////////////////////////////
	u16 temp_color = 0;
  	u16 temp = 0;
  	
	LCD_SetCursor(x,y);
  	
	LCD_ReadGRAM_EN();
	
	DUMMY_READ();						//第一次不读							
	temp_color = LCD_DATA_IN();
	
	LCD_WR_END();
										
	temp = temp_color >> 11;			//RRRRRGGGGGGBBBBB 改为 				
	temp |= temp_color << 11;			//BBBBBGGGGGGRRRRR 格式					
	temp |= (temp_color & 0x07E0);		//0000011111100000  = 0x07E0			
  	
	return temp;
}
////////////////////////////////////////////////////////////////////////////////
//  LCD_SetWindow()->设置GRAM窗口				
//  该函数对于块写很有用,用户只需设置好块写区域 
//然后一次给设置GRAM区域写数据即可,GC指针会自动 
//增加而无需用户更改,这样就提高了写效率.读数据时
//GC不会自动增加(GC->GRAM Counter)				
////////////////////////////////////////////////////////////////////////////////
void LCD_SetWindow(u16 start_x,u16 start_y,
					u16 end_x,u16 end_y)
{ 
  		
  	LCD_WriteRegister(0x0050, start_x);	
  	LCD_WriteRegister(0x0052, start_y);	
  	LCD_WriteRegister(0x0051, end_x);		
  	LCD_WriteRegister(0x0053, end_y);	 
	 	
	//驱动ICR61514->设置GARM地址			
  	////////////////////////////////////////
# if R61514_EN		> 0
	end_x <<= 8;					//高8位是垂直结束地址						
  	end_x |= (unsigned char)start_x;//低8位是垂直开始地址(水平GRAM地址也是如此 )
  	end_y <<= 8;
  	end_y |= (unsigned char)start_y;
	
  	LCD_WriteRegister(0x0044, end_x);
  	LCD_WriteRegister(0x0045, end_y);
# endif
	LCD_SetCursor(start_x, start_y);//设置起始绘图的GRAM地址					
	
}
//LCD清屏函数							
void LCD_Clear(u16 color)
{
	unsigned long  i;
	LCD_SetWindow(0, 0, X_END, Y_END);
	LCD_WriteGRAM_EN();
	for(i=0; i< X_SIZE*Y_SIZE; i++)		//R61514为128*160						
  	{
    	LCD_DATA_OUT(color);
  	}
	LCD_WR_END();
	
	LCD_SetWindow(0,0, X_END, Y_END);	//恢复全局作图区						
}
//填充一个矩形区域						
void LCD_Fill(u16 start_x,u16 start_y,
			  u16 end_x,u16 end_y,
			  u16 color)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -