STM32F767 FSMC驱动8位LCD显示屏

STM32F767 FSMC驱动8位LCD显示屏

ili9342_lcd.c:
#include "ili9342_lcd.h"
#include "stdlib.h"
#include "ili9342_font.h" 
#include "usart.h"	 
#include "delay.h"	 

SRAM_HandleTypeDef SRAM_Handler;    //SRAM句柄(用于控制LCD)
//LCD的画笔颜色和背景色	   
u32 POINT_COLOR=0xFF000000;		//画笔颜色
u32 BACK_COLOR =0xFFFFFFFF;  	//背景色 
  
//管理LCD重要参数
//默认为竖屏
_lcd_dev lcddev;




void LCD_WR_REG(uint8_t regval)
{   
	regval=regval;
	LCD->LCD_REG=regval;
}


//写LCD数据
//data:要写入的值
void LCD_WR_DATA_8BIT(uint8_t data)
{	  
	data=data;
	LCD->LCD_RAM=data;
}


//读LCD数据
//返回值:读到的值
uint8_t LCD_RD_DATA(void)
{
	uint8_t ram;			//防止被优化
	ram=LCD->LCD_RAM;	
	return ram;	 
}


//读取液晶ID
uint16_t LCD_GET_ID(void)
{
	uint16_t id=0;
	LCD_WR_REG(0xD3);
//	
	LCD_RD_DATA();
	LCD_RD_DATA();
	
	//高位
	id|=LCD_RD_DATA();
	id<<=8;
	//低位
	id|=LCD_RD_DATA();
	 
	return id;
	
}


void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
	
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA_8BIT(x1);
		LCD_WR_DATA_8BIT(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA_8BIT(y1);
		LCD_WR_DATA_8BIT(y2);
		LCD_WR_REG(0x2c);//储存器写
	
}



void LCD_SetCursor(u16 Xpos, u16 Ypos)
{	 	    
	LCD_WR_REG(0x2A); 
	LCD_WR_DATA_8BIT(Xpos); 	 
	LCD_WR_REG(0x2B); 
	LCD_WR_DATA_8BIT(Ypos);
	LCD_WR_REG(0x2C); 
} 		 

void LCD_DrawPoint(u16 x,u16 y)
{
	LCD_Address_Set(x,y,x,y);
//	LCD->LCD_RAM=POINT_COLOR>>8;
//	LCD->LCD_RAM=POINT_COLOR;
//	LCD_SetCursor(x,y);		//设置光标位置 
	LCD->LCD_REG=0x2C;//开始写入GRAM
		LCD->LCD_RAM=POINT_COLOR>>8;
	LCD->LCD_RAM=POINT_COLOR;
}

void LCD_Fast_DrawPoint(u16 x,u16 y,u32 color)
{
	LCD_WR_REG(0x2A); 
	LCD_WR_DATA_8BIT(x>>8);
	LCD_WR_DATA_8BIT(x&0XFF);  			 
	LCD_WR_REG(0x2B); 
	LCD_WR_DATA_8BIT(y>>8);
	LCD_WR_DATA_8BIT(y&0XFF); 
	LCD->LCD_REG=0x2C;//开始写入GRAM
	LCD->LCD_RAM=color>>8;
	LCD->LCD_RAM=color;
}


//当mdk -O1时间优化时需要设置
//延时i
void opt_delay(u8 i)
{
	while(i--);
}



//读取个某点的颜色值	 
//x,y:坐标
//返回值:此点的颜色
u32 LCD_ReadPoint(u16 x,u16 y)
{
 	u16 r=0,g=0,b=0,rgb=0;
	LCD_Address_Set(x, y, x, y);
	LCD_WR_REG(0X2E);     		 				    
 	r=LCD_RD_DATA();								//dummy Read	   
 	r=LCD_RD_DATA();  		  						//实际坐标颜色
//	printf("r=%X\r\n",r);

	g=LCD_RD_DATA();
//	printf("g=%X\r\n",g);

	b=LCD_RD_DATA(); 
//	printf("b=%X\r\n",b);
	
	r=(r<<8)&0xF800;
	g=(g<<3)&0x07E0;
	b=(b>>3)&0x001F;
	rgb=r|g|b;	
	return rgb;	
}	









//配置MPU的region(SRAM区域为透写模式)
void LCD_MPU_Config(void)
{	
	MPU_Region_InitTypeDef MPU_Initure;

	HAL_MPU_Disable();							//配置MPU之前先关闭MPU,配置完成以后在使能MPU	
	//外部SRAM为region0,大小为2MB,此区域可读写
	MPU_Initure.Enable=MPU_REGION_ENABLE;	    //使能region
	MPU_Initure.Number=LCD_REGION_NUMBER;		//设置region,外部SRAM使用的region0
	MPU_Initure.BaseAddress=LCD_ADDRESS_START;	//region基地址
	MPU_Initure.Size=LCD_REGION_SIZE;			//region大小
	MPU_Initure.SubRegionDisable=0X00;
	MPU_Initure.TypeExtField=MPU_TEX_LEVEL0;
	MPU_Initure.AccessPermission=MPU_REGION_FULL_ACCESS;	//此region可读写
	MPU_Initure.DisableExec=MPU_INSTRUCTION_ACCESS_ENABLE;	//允许读取此区域中的指令
	MPU_Initure.IsShareable=MPU_ACCESS_NOT_SHAREABLE;
	MPU_Initure.IsCacheable=MPU_ACCESS_NOT_CACHEABLE;
	MPU_Initure.IsBufferable=MPU_ACCESS_BUFFERABLE;
	HAL_MPU_ConfigRegion(&MPU_Initure);
	HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);     //开启MPU
}
//SRAM底层驱动,时钟使能,引脚分配
//此函数会被HAL_SRAM_Init()调用
//hsram:SRAM句柄
void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
{
    GPIO_InitTypeDef GPIO_Initure;
	
	__HAL_RCC_FMC_CLK_ENABLE();				//使能FMC时钟
	__HAL_RCC_GPIOD_CLK_ENABLE();			//使能GPIOD时钟
	__HAL_RCC_GPIOE_CLK_ENABLE();			//使能GPIOE时钟
	
	//初始化PD0,1,4,5,7,8,9,10,13,14,15
	GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7|GPIO_PIN_8|\
                     GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
	GPIO_Initure.Mode=GPIO_MODE_AF_PP; 		//推挽复用
	GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
	GPIO_Initure.Speed=GPIO_SPEED_HIGH;		//高速
	GPIO_Initure.Alternate=GPIO_AF12_FMC;	//复用为FMC
	HAL_GPIO_Init(GPIOD,&GPIO_Initure);     //初始化
	
	//初始化PE7,8,9,10,11,12,13,14,15
	GPIO_Initure.Pin=GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|\
                     GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
	HAL_GPIO_Init(GPIOE,&GPIO_Initure);
}
        
//初始化lcd
//该初始化函数可以初始化各种型号的LCD(详见本.c文件最前面的描述)
void ILI9342_LCD_Init(void)
{ 	  
    GPIO_InitTypeDef GPIO_Initure;
	FMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim;
    FMC_NORSRAM_TimingTypeDef FSMC_WriteTim;
	
	
    
    __HAL_RCC_GPIOB_CLK_ENABLE();			//开启GPIOB时钟
    GPIO_Initure.Pin=GPIO_PIN_5;            //PB5,背光控制
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOB,&GPIO_Initure); 
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);	//PB5置1 
	

    
    LCD_MPU_Config();                       //使能MPU保护LCD区域
    SRAM_Handler.Instance=FMC_NORSRAM_DEVICE;       
    SRAM_Handler.Extended=FMC_NORSRAM_EXTENDED_DEVICE;       
    
    SRAM_Handler.Init.NSBank=FMC_NORSRAM_BANK1;     //使用NE1
    SRAM_Handler.Init.DataAddressMux=FMC_DATA_ADDRESS_MUX_DISABLE; //不复用数据线
    SRAM_Handler.Init.MemoryType=FMC_MEMORY_TYPE_SRAM;   //SRAM
    SRAM_Handler.Init.MemoryDataWidth=FMC_NORSRAM_MEM_BUS_WIDTH_8; //8位数据宽度
    SRAM_Handler.Init.BurstAccessMode=FMC_BURST_ACCESS_MODE_DISABLE; //是否使能突发访问,仅对同步突发存储器有效,此处未用到
    SRAM_Handler.Init.WaitSignalPolarity=FMC_WAIT_SIGNAL_POLARITY_LOW;//等待信号的极性,仅在突发模式访问下有用
    SRAM_Handler.Init.WaitSignalActive=FMC_WAIT_TIMING_BEFORE_WS;   //存储器是在等待周期之前的一个时钟周期还是等待周期期间使能NWAIT
    SRAM_Handler.Init.WriteOperation=FMC_WRITE_OPERATION_ENABLE;    //存储器写使能
    SRAM_Handler.Init.WaitSignal=FMC_WAIT_SIGNAL_DISABLE;           //等待使能位,此处未用到
    SRAM_Handler.Init.ExtendedMode=FMC_EXTENDED_MODE_ENABLE;        //读写使用不同的时序
    SRAM_Handler.Init.AsynchronousWait=FMC_ASYNCHRONOUS_WAIT_DISABLE;//是否使能同步传输模式下的等待信号,此处未用到
    SRAM_Handler.Init.WriteBurst=FMC_WRITE_BURST_DISABLE;           //禁止突发写
    SRAM_Handler.Init.ContinuousClock=FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;
    
    //FSMC读时序控制寄存器
    FSMC_ReadWriteTim.AddressSetupTime=0x11; // 0x11  //地址建立时间(ADDSET)为17个HCLK 1/216M=4.6ns*17=78ns
    FSMC_ReadWriteTim.AddressHoldTime=0x00;
    FSMC_ReadWriteTim.DataSetupTime=0x55;   //  0x55  //数据保存时间(DATAST)为85个HCLK	=4.6*85=391ns
    FSMC_ReadWriteTim.AccessMode=FMC_ACCESS_MODE_A; //模式A
    //FSMC写时序控制寄存器
    FSMC_WriteTim.AddressSetupTime=0x15;   // 0x15    //地址建立时间(ADDSET)为21个HCLK=96ns
    FSMC_WriteTim.AddressHoldTime=0x00;
    FSMC_WriteTim.DataSetupTime=0x15;    // 0x15    //数据保存时间(DATAST)为4.6ns*21个HCLK=96ns
    FSMC_WriteTim.AccessMode=FMC_ACCESS_MODE_A;     //模式A
	HAL_SRAM_Init(&SRAM_Handler,&FSMC_ReadWriteTim,&FSMC_WriteTim);		
 	delay_ms(50); // delay 50 ms 
	
	//尝试9342 ID的读取					   
	lcddev.id=LCD_GET_ID();	//dummy read 	
	lcddev.width=320;
	lcddev.height=240;
	if(lcddev.id==0x9342)
	{
		LCD_WR_REG(0xC8);       //Set EXTC
		LCD_WR_DATA_8BIT(0xFF);
		LCD_WR_DATA_8BIT(0x93);
		LCD_WR_DATA_8BIT(0x42);

		LCD_WR_REG(0xb6);  
		LCD_WR_DATA_8BIT(0x0a);
		LCD_WR_DATA_8BIT(0xE0);//SS GS

		LCD_WR_REG(0x36); //Memory Access Control
		LCD_WR_DATA_8BIT(0x08); //MY,MX,MV,ML,BGR,MH

		LCD_WR_REG(0x3A); //Pixel Format Set
		LCD_WR_DATA_8BIT(0x55); //DPI [2:0],DBI [2:0]

		LCD_WR_REG(0xC0); //Power Control 1
		LCD_WR_DATA_8BIT(0x12); //VRH[5:0]
		LCD_WR_DATA_8BIT(0x12); //VC[3:0]

		LCD_WR_REG(0xC1);  //Power Control 2
		LCD_WR_DATA_8BIT(0x04); //02,SAP[2:0],BT[3:0]VGL=12V,VGH=15V

		LCD_WR_REG(0xC5); //VCOM
		LCD_WR_DATA_8BIT(0XFD); //C8++

		LCD_WR_REG(0xB1);      
		LCD_WR_DATA_8BIT(0x00);     
		LCD_WR_DATA_8BIT(0x1B);

		LCD_WR_REG(0xB4);      
		LCD_WR_DATA_8BIT(0x02);
		//	//*****************GAMMA*****************  
		LCD_WR_REG(0xE0);
		LCD_WR_DATA_8BIT(0x00);//P01-VP63   
		LCD_WR_DATA_8BIT(0x05);//P02-VP62   
		LCD_WR_DATA_8BIT(0x08);//P03-VP61   
		LCD_WR_DATA_8BIT(0x04);//P04-VP59   
		LCD_WR_DATA_8BIT(0x13);//P05-VP57   
		LCD_WR_DATA_8BIT(0x0A);//P06-VP50   
		LCD_WR_DATA_8BIT(0x34);//P07-VP43   
		LCD_WR_DATA_8BIT(0x8A);//P08-VP27,36
		LCD_WR_DATA_8BIT(0x46);//P09-VP20   
		LCD_WR_DATA_8BIT(0x07);//P10-VP13   
		LCD_WR_DATA_8BIT(0x0E);//P11-VP6    
		LCD_WR_DATA_8BIT(0x0A);//P12-VP4    
		LCD_WR_DATA_8BIT(0x1B);//P13-VP2    
		LCD_WR_DATA_8BIT(0x1D);//P14-VP1    
		LCD_WR_DATA_8BIT(0x0F);//P15-VP0    

		LCD_WR_REG(0xE1);
		LCD_WR_DATA_8BIT(0x0C);//P01
		LCD_WR_DATA_8BIT(0x05);//P02
		LCD_WR_DATA_8BIT(0x08);//P03
		LCD_WR_DATA_8BIT(0x04);//P04
		LCD_WR_DATA_8BIT(0x13);//P05
		LCD_WR_DATA_8BIT(0x0A);//P06
		LCD_WR_DATA_8BIT(0x34);//P07
		LCD_WR_DATA_8BIT(0x8A);//P08
		LCD_WR_DATA_8BIT(0x46);//P09
		LCD_WR_DATA_8BIT(0x07);//P10
		LCD_WR_DATA_8BIT(0x0E);//P11
		LCD_WR_DATA_8BIT(0x0A);//P12
		LCD_WR_DATA_8BIT(0x1B);//P13
		LCD_WR_DATA_8BIT(0x1D);//P14
		LCD_WR_DATA_8BIT(0x0F);//P15

		LCD_WR_REG(0x21); 

		//********Window(窗口/地址)****************
		LCD_WR_REG(0x2A); //320
		LCD_WR_DATA_8BIT(0x00);
		LCD_WR_DATA_8BIT(0x00);
		LCD_WR_DATA_8BIT(0x01);
		LCD_WR_DATA_8BIT(0x3F);

		LCD_WR_REG(0x2B); //240
		LCD_WR_DATA_8BIT(0x00);
		LCD_WR_DATA_8BIT(0x00);
		LCD_WR_DATA_8BIT(0x00);
		LCD_WR_DATA_8BIT(0xEF);
		//****************************** 
		LCD_WR_REG(0x11);//Exit Sleep
		delay_ms(120);
		LCD_WR_REG(0x29);//Display On
		LCD_WR_REG(0x2c); 
		LCD_Clear(WHITE);
	}

	
   
	
}  


/******************************************************************************
      函数说明:LCD清屏函数
      入口数据:无
      返回值:  无
******************************************************************************/
void LCD_Clear(u16 Color)
{
	u16 i,j;  	
	LCD_SetCursor(0,0);
    for(i=0;i<lcddev.width;i++)
	 {
	  for (j=0;j<lcddev.height;j++)
	   	{
        	LCD_WR_DATA_8BIT(Color>>8);
			LCD_WR_DATA_8BIT(Color);
	    }

	  }
}


/******************************************************************************
      函数说明:在指定区域填充颜色
      入口数据:xsta,ysta   起始坐标
                xend,yend   终止坐标
      返回值:  无
******************************************************************************/
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{          
	u16 i,j; 
	LCD_Address_Set(xsta,ysta,xend,yend);      //设置光标位置 
	for(i=xsta;i<xend;i++)
	{													   	 	
		for(j=ysta;j<yend;j++)
		{
			LCD_WR_REG(0x2A); 
			LCD_WR_DATA_8BIT(i>>8);
			LCD_WR_DATA_8BIT(i&0XFF);  			 
			LCD_WR_REG(0x2B); 
			LCD_WR_DATA_8BIT(j>>8);
			LCD_WR_DATA_8BIT(j&0XFF); 
			LCD->LCD_REG=0x2C;//开始写入GRAM
			LCD->LCD_RAM=color>>8;
			LCD->LCD_RAM=color;
			
		}
			    
	} 					  	    
}



ILI9342.h:
#ifndef __ILI9342_LCD_H
#define __ILI9342_LCD_H
#include "sys.h"	 
#include "stdlib.h" 



//LCD重要参数集
typedef struct  
{		 	 
	u16 width;			//LCD 宽度
	u16 height;			//LCD 高度
	u16 id;				//LCD ID
	u8  dir;			//横屏还是竖屏控制:0,竖屏;1,横屏。	
	u16	wramcmd;		//开始写gram指令
	u16 setxcmd;		//设置x坐标指令
	u16 setycmd;		//设置y坐标指令 
}_lcd_dev; 	  

//LCD参数
extern _lcd_dev lcddev;	//管理LCD重要参数
//LCD的画笔颜色和背景色	   
extern u32  POINT_COLOR;//默认红色    
extern u32  BACK_COLOR; //背景颜色.默认为白色



//LCD MPU保护参数
#define LCD_REGION_NUMBER		MPU_REGION_NUMBER0		//LCD使用region0
#define LCD_ADDRESS_START		(0X60000000)			//LCD区的首地址
#define LCD_REGION_SIZE			MPU_REGION_SIZE_256MB   //LCD区大小

//	 
//-----------------MCU屏 LCD端口定义---------------- 
//LCD背光	PB5	
#define LCD_LED(n) (n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET)) 	    
//LCD地址结构体
typedef struct
{
	__IO uint8_t LCD_REG;
	__IO uint8_t LCD_RAM;
} LCD_TypeDef;

//使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A18作为数据命令区分线 
//注意设置时STM32内部会右移一位对其! 			    
//#define LCD_BASE        ((u32)(0x60000000 | 0x0007FFFE))
#define LCD_BASE          ((uint32_t)(0x60000000 | 0x0003ffff))

#define LCD             ((LCD_TypeDef *) LCD_BASE)
//
	 




//画笔颜色
#define WHITE         	 0xFFFF
#define BLACK         	 0x0000	  
#define BLUE         	 0x001F  
#define BRED             0XF81F
#define GRED 			 0XFFE0
#define GBLUE			 0X07FF
#define RED           	 0xF800
#define MAGENTA       	 0xF81F
#define GREEN         	 0x07E0
#define CYAN          	 0x7FFF
#define YELLOW        	 0xFFE0
#define BROWN 			 0XBC40 //棕色
#define BRRED 			 0XFC07 //棕红色
#define GRAY  			 0X8430 //灰色
//GUI颜色

#define DARKBLUE      	 0X01CF	//深蓝色
#define LIGHTBLUE      	 0X7D7C	//浅蓝色  
#define GRAYBLUE       	 0X5458 //灰蓝色
//以上三色为PANEL的颜色 
 
#define LIGHTGREEN     	 0X841F //浅绿色
//#define LIGHTGRAY        0XEF5B //浅灰色(PANNEL)
#define LGRAY 			 0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)
	    															  


void LCD_WR_REG(uint8_t regval);
void LCD_WR_DATA_8BIT(uint8_t data);
uint8_t LCD_RD_DATA(void);
uint16_t LCD_GET_ID(void);
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2);
void LCD_SetCursor(u16 Xpos, u16 Ypos);
void LCD_DrawPoint(u16 x,u16 y);
void LCD_Fast_DrawPoint(u16 x,u16 y,u32 color);
void opt_delay(u8 i);
u32 LCD_ReadPoint(u16 x,u16 y);
void LCD_MPU_Config(void);
void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram);
void ILI9342_LCD_Init(void);
void LCD_Clear(u16 Color);

void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color);
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color);
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color);
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color);


void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u8 mode);						//显示一个字符
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size);  						//显示一个数字
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);				//显示 数字
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p);		//显示一个字符串,12/16字体
u32 LCD_Pow(u8 m,u8 n);




void LCD_DrawLine2(u16 x1, u16 y1, u16 x2, u16 y2, u16 size, u16 color);
void gui_circle(int xc, int yc,u16 c,int r, int fill);
void _draw_circle_8(int xc, int yc, int x, int y, u16 c);







#endif  
	 

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值