STM32H7使用HAL库驱动3.5寸SPI电容触摸屏幕+DMA刷新

先上效果

VID_20240629_191036

VID_20240701_195036

使用100mhz的SPI频率,在不使用DMA情况下,大约10帧左右,加上DMA后提高到接近40帧.

使用480*320*2大小的缓冲区,如果单纯刷屏可以减小到HAL库SPI发送函数最大长度.因为缓冲区过大所以分几次发送的.

CUBEMX生成代码

一共需要使用3个外设,定时器可以不用

硬件I2C+SPI+串口

首先使能RCC,SPI,USART,I2C

电容触摸

电容触摸芯片GT911,I2C频率最大400khz,STM32开到1000k也无所谓,没有使能DMA和中断,使用外部中断获取触摸信号,读寄存器

对配置好的I2C封装一下,这里沿用了以前的代码,因为GT911有16位寄存器,所以再写一个16位读写函数.

void i2c_write(uint8_t devaddr,uint8_t addr,uint8_t pdata,int len){
  HAL_I2C_Mem_Write(&I2C,devaddr,addr,I2C_MEMADD_SIZE_8BIT,&pdata,len,1000);
}
uint8_t i2c_read(uint8_t devaddr,uint8_t addr)
{ uint8_t data;
  HAL_I2C_Mem_Read(&I2C,devaddr,addr,I2C_MEMADD_SIZE_8BIT,&data,1,1000);
  return data;
}

void i2c_write16(uint8_t devaddr,uint16_t addr,uint8_t pdata,int len){

  HAL_I2C_Mem_Write(&I2C,devaddr,addr,I2C_MEMADD_SIZE_16BIT,&pdata,len,1000);
}
uint8_t i2c_read16(uint8_t devaddr,uint16_t addr)
{ uint8_t data;
  HAL_I2C_Mem_Read(&I2C,devaddr,addr,I2C_MEMADD_SIZE_16BIT,&data,1,1000);
  return data;
}

void i2c_read16n(uint8_t devaddr,uint16_t addr,uint8_t* data,uint8_t n)
{
  HAL_I2C_Mem_Read(&I2C,devaddr,addr,I2C_MEMADD_SIZE_16BIT,data,n,1000);
}
void i2c_write16n(uint8_t devaddr,uint16_t addr,uint8_t* data,uint8_t n)
{
  HAL_I2C_Mem_Write(&I2C,devaddr,addr,I2C_MEMADD_SIZE_16BIT,data,n,1000);
}

GT911初始化

GT911的寄存器表大概就用这几个就好了

#define USE_GT911
#define hi2cx GT911
//#define GT_WRITECFG //写配置表
#define GT_ADDR 0X28
#define GT_CTRL_REG     0X8040       //GT911控制寄存器
#define GT_CFGS_REG     0X8047       //GT911配置起始地址寄存器
#define GT_CHECK_REG     0X80FF       //GT911校验和寄存器
#define GT_PID_REG         0X8140       //GT911产品ID寄存器
#define GT_GSTID_REG     0X814E       //GT911当前检测到的触摸情况

GT911的初始化很简单,不用配置什么,上电就能读取数据,因为我没找到芯片id到底是多少所以没有读id,同时千万别写控制寄存器0x8040,写了就裂开,找厂家要配置表.这里选择了要不要写配置表

void GT911_INIT(){
		HAL_Delay(100);
    uint8_t data;
		#ifdef GT_WRITECFG
		i2c_write16(GT_ADDR,GT_CTRL_REG,2,1);
    i2c_write16n(GT_ADDR,0x8047,(uint8_t *)datacfg,186);
		i2c_write16(GT_ADDR,GT_CTRL_REG,0,1);
		#endif
    touch=0;
    HAL_Delay(100);
		i2c_write16(GT_ADDR,GT_GSTID_REG,0x00,1);
}

随后就是判断是否被触摸以及触摸点数.

通过电容触摸屏GT911、GT928、GT9147的使用_gt911 3.5寸配置文件-优快云博客得知,当触摸发生时,寄存器0x814E 最高位变成1,同时低四位表示有几个点

例如10000011:触摸按下,有3个点按下,这里我用了两次判断,先判断高位在判断低四位是否不为0,因为触摸结束的时候没有及时清除814E寄存器,第8位还为1,会误入读取坐标,加一个判断能够在触摸结束马上得知.

通过上文得知,坐标寄存器都是挨着的,只用按顺序读就好了氛围高8位和低8位

坐标=高八位*255+低八位

读完以后存储到LIST里面,方便读取.

void GET_NUM(void){
		#ifdef TOUCHOK
		touch=0;
		uint8_t data;
		data=i2c_read16(GT_ADDR,GT_GSTID_REG);
		if((data&0x80)!=0){
			if((data&0X0f)!=0){
			touch=data&0x0F;
			read_point(LIST,touch);
			}
			i2c_write16(GT_ADDR,GT_GSTID_REG,0x00,1);
		}
		return ;
  #endif
		printf("TOUCH ERROR PLEASE TRY LATER\r\n");
}
void read_point(POINT LIST[],uint8_t NUM){
  uint16_t x,y;
  i2c_read16n(GT_ADDR,0x8150,datatemp,8*NUM);
	for(uint8_t i=0;i<NUM;i++){
    x=(datatemp[i*8]+(datatemp[i*8+1]<<8));
    y=(datatemp[i*8+2]+(datatemp[i*8+3]<<8));
    LIST[i].xPos=x;
    LIST[i].yPos=y;
    LIST[i].id=i+1;
		printf("TOUCH %d X->%d Y->%d\r\n",i+1,x,y);
  }
}

测试,数据也是比较准的

SPI初始化

200mhz 2分频 ,h7就是暴力,直接硬干都有10多帧,8位传输,仅发送,加入DMA,开启SPI DMA中断

其他配置都差不多不用改

封装一下发送函数

void SPI_ReadWriteByte(uint8_t TxData)
{			
      HAL_SPI_Transmit(&SPI,&TxData,1,10);              		    //·µ»ØÊÕµ½µÄÊý¾Ý		
}

void SPI_SetSpeed(uint32_t SPI_BaudRatePrescaler)
{
    assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//ÅжÏÓÐЧÐÔ
    __HAL_SPI_DISABLE(&SPI);            //¹Ø±ÕSPI
    SPI.Instance->CFG1&=~(0X7<<28);     //λ30-28ÇåÁ㣬ÓÃÀ´ÉèÖò¨ÌØÂÊ
    SPI.Instance->CFG1|=SPI_BaudRatePrescaler;//ÉèÖÃSPIËÙ¶È
    __HAL_SPI_ENABLE(&SPI);             //ʹÄÜSPI
}

引脚,这里使用cubemx的宏定义,方便移植,命名好就能直接使用

DMA

这里是最难绷的,前前后后试了好久,不知道为什么一直发送不成功,返回不是HAL_ERROR就是HAL_BUSY,直到这几天突然看到片文章STM32H7:解决DMA传输无效的问题-优快云博客

牛莫得,H7默认的程序执行范围起始位置DMA是无法访问的,解决方法也很简单

将起始区域修改为可以的就好了

LCD代码

这里使用了安富莱的LCD代码

lcd.h注释不知道为什么乱码,内容挺好理解的

#ifndef __LCD_H
#define __LCD_H		


#include "stdlib.h"
#include "GPIO.h"
typedef   signed          char int8_t;
typedef   signed short     int int16_t;
typedef   signed           int int32_t;
typedef   signed       long long int64_t;

typedef unsigned          char   uint8_t;
typedef unsigned short     int   uint16_t;
typedef unsigned           int   uint32_t;
typedef unsigned       long long uint64_t;


typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;

extern uint16_t D_Color;
extern uint16_t B_Color;


/******************************************************************************

  ½Ó¿Ú¶¨Ò壬Çë¸ù¾Ý½ÓÏßÐ޸IJ¢ÐÞ¸ÄÏàÓ¦IO³õʼ»¯--Çý¶¯°å×ÓºÍIOÒª¶ÔÓ¦


//	#define LCD_SDA        	//PD7  //Êý¾ÝÊäÈëÏß
//	#define LCD_SCL        	//PB3  //ʱÖÓÏß
//	#define LCD_CS        	//PB4  //Ƭѡ	
//	#define LCD_RESET     	//PG11  //Êý¾ÝÊä³ö/¸´Î»
//	#define LCD_RS         	//PD6   //ÃüÁî/Êý¾ÝÇл»
//	#define LCD_BLK         //PG14   //±³¹â¿ØÖÆ  

*******************************************************************************/ 



//Òº¾§¿ØÖÆ¿ÚÖÃ1²Ù×÷Óï¾äºê¶¨Òå
#define	LCD_SDA_SET  	HAL_GPIO_WritePin(LCD_MOSI_GPIO_Port,LCD_MOSI_Pin,GPIO_PIN_SET) 	   //PB15ÖÃ1    LCD_SDI£º PB15 //Êý¾ÝÊäÈëÏß

#define	LCD_SCL_SET  	HAL_GPIO_WritePin(LCD_CLK_GPIO_Port,LCD_CLK_Pin,GPIO_PIN_SET)	     //PB13ÖÃ1    LCD_SCL£º PB13 //ʱÖÓÏß

#define	LCD_CS_SET  	HAL_GPIO_WritePin(LCD_CS_GPIO_Port,LCD_CS_Pin,GPIO_PIN_SET)	     //PB12ÖÃ1    LCD_CS£º  PB12 //Ƭѡ	

#define LCD_RST_SET   	HAL_GPIO_WritePin(LCD_RESET_GPIO_Port,LCD_RESET_Pin,GPIO_PIN_SET)	     //PB14ÖÃ1      LCD_SDO £ºPB14 //Êý¾ÝÊä³ö/¸´Î»

#define	LCD_RS_SET  	HAL_GPIO_WritePin(LCD_RS_GPIO_Port,LCD_RS_Pin,GPIO_PIN_SET)		   //PB1ÖÃ1     LCD_RS£º PB1   //ÃüÁî/Êý¾ÝÇл»

#define	LCD_BLK_SET  	HAL_GPIO_WritePin(LCD_BL_GPIO_Port,LCD_BL_Pin,GPIO_PIN_SET) 	     //PB0ÖÃ1     LCD_BLK £ºPB0   //±³¹â¿ØÖÆ  


//Òº¾§¿ØÖÆ¿ÚÖÃ0²Ù×÷Óï¾äºê¶¨Òå

#define	LCD_SDA_CLR  	HAL_GPIO_WritePin(LCD_MOSI_GPIO_Port,LCD_MOSI_Pin,GPIO_PIN_RESET)  	  //PB15ÖÃ0 //DIN  LCD_SDI£º PB15 //Êý¾ÝÊäÈëÏß

#define	LCD_SCL_CLR  	HAL_GPIO_WritePin(LCD_SCL_GPIO_Port,LCD_CLK_Pin,GPIO_PIN_RESET)	    //PB13ÖÃ0 //CLK  LCD_SCL£º PB13 //ʱÖÓÏß

#define	LCD_CS_CLR  	HAL_GPIO_WritePin(LCD_CS_GPIO_Port,LCD_CS_Pin,GPIO_PIN_RESET)	   	//PB12ÖÃ0/CS     LCD_CS£º  PB12 //Ƭѡ	

#define LCD_RST_CLR   	HAL_GPIO_WritePin(LCD_RESET_GPIO_Port,LCD_RESET_Pin,GPIO_PIN_RESET)	    //PB14ÖÃ0 //RES  LCD_SDO £ºPB14 //Êý¾ÝÊä³ö/¸´Î»

#define	LCD_RS_CLR  	HAL_GPIO_WritePin(LCD_RS_GPIO_Port,LCD_RS_Pin,GPIO_PIN_RESET)		 	//PB1ÖÃ0 //DC    LCD_RS£º PB1   //ÃüÁî/Êý¾ÝÇл»

#define	LCD_BLK_CLR  	HAL_GPIO_WritePin(LCD_BL_GPIO_Port,LCD_BL_Pin,GPIO_PIN_RESET)  	  //PB0ÖÃ0 //DIN   LCD_BLK £ºPB0   //±³¹â¿ØÖÆ  



#define	LCD_BLK_On          LCD_BLK_SET   		 //¿ª±³¹â  LCD±³¹â¿ØÖÆ  
#define	LCD_BLK_Off         LCD_BLK_CLR    		 //¹Ø±³¹â  LCD±³¹â¿ØÖÆ	 


//LCDÖØÒª²ÎÊý¼¯
typedef struct  
{										    
	u16 width;			//LCD ¿í¶È
	u16 height;			//LCD ¸ß¶È
	u16 id;				  //LCD ID
	u8  dir;			  //ºáÆÁ»¹ÊÇÊúÆÁ¿ØÖÆ£ºÊúÆÁºÍºáÆÁ¡£	
	u16	wramcmd;		//¿ªÊ¼Ð´gramÖ¸Áî
	u16  setxcmd;		//ÉèÖÃx×ø±êÖ¸Áî
	u16  setycmd;		//ÉèÖÃy×ø±êÖ¸Áî 
}_lcd_dev; 	  



/////////////////////////////////////Óû§ÅäÖÃÇø///////////////////////////////////	

//Ö§³ÖºáÊúÆÁ¿ìËÙ¶¨ÒåÇл»


#define LCD_DIR_Mode  	  0	    //4ÖÖ¹¤×÷ģʽ£¬0ºÍ2ÊÇÊúÆÁģʽ£¬1ºÍ3ÊǺáÆÁģʽ

#define USE_HORIZONTAL  	0     //·½ÏòÉèÖ㺠		0,ÊúÆÁģʽ   1,ºáÆÁģʽ.



//////////////////////////////////////////////////////////////////////////////////	

//LCD²ÎÊý
extern _lcd_dev lcddev;	//¹ÜÀíLCDÖØÒª²ÎÊý

//LCDµÄ»­±ÊÑÕÉ«ºÍ±³¾°É«	   

extern u16  POINT_COLOR;//ĬÈϺìÉ«    
extern u16  BACK_COLOR; //±³¾°ÑÕÉ«.ĬÈÏΪ°×É«

#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	//dzÀ¶É«  
#define GRAYBLUE       	 0x5458 //»ÒÀ¶É«
//ÒÔÉÏÈýɫΪPANELµÄÑÕÉ« 
#define LIGHTGREEN     	 0x841F //dzÂÌÉ«
#define LGRAY 			     0xC618 //dz»ÒÉ«(PANNEL),´°Ìå±³¾°É«
#define GRAY0  0xEF7D   	    //»ÒÉ«0 
#define GRAY1   0x8410      	//»ÒÉ«1   
#define GRAY2   0x4208      	//»ÒÉ«2  
#define LGRAYBLUE        0xA651 //dz»ÒÀ¶É«(Öмä²ãÑÕÉ«)
#define LBBLUE           0x2B12 //Ç³×ØÀ¶É«(Ñ¡ÔñÌõÄ¿µÄ·´É«)

#define	LCD_Delay_us  	delay_us   //ÑÓʱº¯Êý
#define	LCD_HAL_Delay  	HAL_Delay   //ÑÓʱº¯Êý

////////////////////////Ó²¼þÇý¶¯-¹¦Äܺ¯Êý//////DevEBox  ´óÔ½´´ÐÂ//////shop389957290.taobao.com///////////////////////////////////////////////////

void LCD_GPIO_Init(void);            //Òº¾§IO³õʼ»¯ÅäÖÃ


void LCD_WR_REG(uint16_t regval);        //Òº¾§ÆÁ--д¼Ä´æÆ÷º¯Êý
void LCD_WR_DATA8(u8 data);          //д8λÊý¾Ý
void LCD_WR_DATA16(uint16_t data);       //д16λÊý¾Ý


void LCD_Init(void);													   	              //³õʼ»¯
void LCD_HardwareRest(void);                                    //Ó²¸´Î»--Èç¹ûIOÁ¬½Ó£¬Ó²¼þ¸´Î»¿É¿ØÓÐЧ
void LCD_SoftRest(void);                                        //Èí¸´Î»
void LCD_DisplayOn(void);													              //¿ªÏÔʾ
void LCD_DisplayOff(void);													            //¹ØÏÔʾ


//////////////////ÒÔϺ¯ÊýÊÇÆÁÄ»ÏÔʾͼÐεļòµ¥Çý¶¯º¯Êý////////////DevEBox  ´óÔ½´´ÐÂ//////shop389957290.taobao.com//////////////////////////////////////

void LCD_SetCursor(u16 Xpos, u16 Ypos);										      //ÉèÖùâ±ê
void LCD_DrawPoint(u16 x,u16 y);											          //»­µã--ʹÓÃÉèÖõıʼâÑÕÉ«
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color);								  //¿ìËÙ»­µã--ʹÓõ±Ç°ÊäÈëÑÕÉ«²ÎÊý
void LCD_QCLEAR_DMA(u16 color);
void LCD_QCLEAR(u16 color);
void LCD_Clear(u16 color);
void LCD_Draw_Circle(u16 x0,u16 y0,u8 r, 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 LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);		   			             //Ìî³äµ¥É«
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color);		             //Ìî³äÖ¸¶¨ÑÕÉ«
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u16 color,u8 mode);					   //ÏÔʾһ¸ö×Ö·û
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size,u16 color);  					    //ÏÔʾһ¸öÊý×Ö
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u16 color,u8 mode);				  //ÏÔʾ Êý×Ö
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u16 color,u8 *p,u8 mode);		//ÏÔʾһ¸ö×Ö·û´®,12/16×ÖÌå
void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue);               //д¼Ä´æÆ÷
void LCD_WriteRAM_Prepare(void);                                //¿ªÊ¼Ð´GRAM  ÃüÁî
void LCD_WriteRAM(u16 RGB_Code);		                            //LCDдGRAM
void LCD_Scan_Dir(u8 dir);							                        //ÉèÖÃÆÁɨÃè·½Ïò
void LCD_Display_Dir(u8 dir);						                        //ÉèÖÃÆÁÄ»ÏÔʾ·½Ïò
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height);         //ÉèÖô°¿Ú					
void SHOW_PIC_DMA(void);
void Draw_Test(void);//»æÍ¼¹¤¾ßº¯Êý²âÊÔ
void Color_Test(void);//ÑÕÉ«Ìî³äÏÔʾ²âÊÔ
void Font_Test(void);// ×ÖÌå×ÖÐÎÏÔʾ²âÊÔ
void GBK_LibFont_Test(void);//GBK ×ÖÌå×ÖÐÎÏÔʾ²âÊÔ
void Demo_Menu(void);//ÑÝʾ³ÌÐò²Ëµ¥



#endif  
	 
	































/*******************************************************************************/

//DevEBox  ´óÔ½´´ÐÂ

//ÌÔ±¦µêÆÌ£ºmcudev.taobao.com
//ÌÔ±¦µêÆÌ£ºshop389957290.taobao.com
/*******************************************************************************/


lcd.c



#include "lcd.h"
#include "stdlib.h"
#include "font.h" 
#include "usart.h"	 
#include "Text.h"
#include "Dis_Picture.h" 
#include "SPI.h" 
#include "stdio.h"
#include "Picture.h"
u16 POINT_COLOR=0x0000;	//»­±ÊÑÕÉ«
u16 BACK_COLOR=0xFFFF;  //±³¾°É« 
uint8_t gram[320*480*2]={0};


//¹ÜÀíLCDÖØÒª²ÎÊý
//ĬÈÏΪÊúÆÁ
_lcd_dev lcddev;

/******************************************************************************/
void LCD_GPIO_Init(void)
{

    __HAL_RCC_GPIOB_CLK_ENABLE();	
		__HAL_RCC_GPIOC_CLK_ENABLE();	
		HAL_GPIO_WritePin(GPIOB,LCD_RS_Pin,GPIO_PIN_SET);	  //PB1ÖÃ1 
		HAL_GPIO_WritePin(GPIOC,LCD_CS_Pin,GPIO_PIN_SET);	//PB12ÖÃ1 
		HAL_GPIO_WritePin(GPIOC,LCD_RESET_Pin,GPIO_PIN_SET);

		MX_SPI1_Init();
		//SPI_SetSpeed(SPI_BAUDRATEPRESCALER_8);
		
      
}



void LCD_WR_REG(u16 regval)//д¼Ä´æÆ÷
{   
	LCD_CS_CLR;  //LCD_CS=0  //Ƭѡ
	LCD_RS_CLR;  //LCD_RS=0  //ÉèÖÃÃüÁî״̬
	SPI_ReadWriteByte(regval&0x00FF);
	LCD_CS_SET;  //LCD_CS=1	 
}




void LCD_WR_DATA8(u8 data)   //д8λÊý¾Ý
{
	LCD_CS_CLR;  //LCD_CS=0  //Ƭѡ
	LCD_RS_SET;	 //LCD_RS=1   //ÉèÖÃÊý¾Ý״̬			    	   
	SPI_ReadWriteByte(data);	
	LCD_CS_SET;  //LCD_CS=1   			 
}





void LCD_WR_DATA16(u16 data)//д16λÊý¾Ý
{	
	
 	LCD_CS_CLR;  //LCD_CS=0  //Ƭѡ
	LCD_RS_SET;	 //LCD_RS=1   //ÉèÖÃÊý¾Ý״̬
	SPI_ReadWriteByte(data>>8);
	SPI_ReadWriteByte(data);
	LCD_CS_SET;    //LCD_CS=1
	
}


void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)//дҺ¾§ÆÁ¼Ä´æÆ÷
{	
	LCD_WR_REG(LCD_Reg);		   //дÈëҪдµÄ¼Ä´æÆ÷ÐòºÅ	 
	LCD_WR_DATA8(LCD_RegValue);//дÈëÊý¾Ý	    		 
}


void LCD_WriteRAM_Prepare(void)//¿ªÊ¼Ð´GRAM
{
 	LCD_WR_REG(lcddev.wramcmd);	  
}	


void LCD_WriteRAM(u16 RGB_Code)//дµãÑÕÉ«
{							    
	LCD_WR_DATA16(RGB_Code);//дʮÁùλGRAM
}

void LCD_DisplayOn(void)//LCD¿ªÆô
{					   
	LCD_WR_REG(0X29);	//¿ªÆôÏÔʾ
}	

void LCD_DisplayOff(void)//LCD¿ª¹Ø±Õ
{	   
	LCD_WR_REG(0X28);	//¹Ø±ÕÏÔʾ

} 

void LCD_SoftRest(void)
{					   
	LCD_WR_REG(0x01);	//·¢ËÍÈí¸´Î»ÃüÁî
	LCD_HAL_Delay(50);      // delay 50 ms 
}	

void LCD_HardwareRest(void)
{					   
	LCD_RST_CLR;     //Òº¾§ÆÁ¸´Î» --Ó²¸´Î»--ʹÄÜ       //PB14×÷ΪҺ¾§ÆÁ¸´Î»¿ØÖÆÒý½Å
	LCD_HAL_Delay(50);      // delay 50 ms 
	LCD_RST_SET;      //Òº¾§ÆÁ¸´Î» --Ó²¸´Î»--ʧÄÜ       //PB14×÷ΪҺ¾§ÆÁ¸´Î»¿ØÖÆÒý½Å
	LCD_HAL_Delay(30);      // delay 30 ms 
}	


void LCD_SetCursor(u16 Xpos, u16 Ypos)//ÉèÖùâ±êλÖÃ
{	 
		LCD_WR_REG(lcddev.setxcmd); 
		LCD_WR_DATA16(Xpos);

		LCD_WR_REG(lcddev.setycmd);
		LCD_WR_DATA16(Ypos);	

	
}

void LCD_DrawPoint(u16 x,u16 y)//»­µã
{
	LCD_SetCursor(x,y);
	LCD_WriteRAM_Prepare();
	LCD_WR_DATA16(POINT_COLOR); 
}

void LCD_TRANMITE(long num){
	long i;
	LCD_CS_CLR;
	LCD_RS_SET;
	if(num%38400==0)		
		for(i=0;i<num;i+=38400)
			HAL_SPI_Transmit(&SPI,&gram[i],38400,10);
	else{
		for(i=0;i<num-38400;i+=38400)
				HAL_SPI_Transmit(&SPI,&gram[i],38400,10);
		HAL_SPI_Transmit(&SPI,&gram[i],num%38400,10);
	}
	LCD_CS_SET;
}

void LCD_QCLEAR_DMA(u16 color){
	long i;
	uint8_t data;
	for(i=0;i<320*480*2;i+=2){
			gram[i]=color>>8;
			gram[i+1]=color;
	}
	LCD_SetCursor(0x00,0x00);
	LCD_WriteRAM_Prepare();
	HAL_StatusTypeDef CALL;
	LCD_CS_CLR;
	LCD_RS_SET;
	for(i=0;i<320*480*2;i+=38400){
		HAL_SPI_Transmit_DMA(&SPI,&gram[i],38400);
		while(HAL_SPI_GetState(&SPI)!=HAL_SPI_STATE_READY);
	}	
	LCD_CS_SET; 
}

void LCD_QCLEAR(u16 color){
	long i;
	for(i=0;i<320*480*2;i+=2){
			gram[i]=color>>8;
			gram[i+1]=color;
	}
	LCD_SetCursor(0x00,0x00);
	LCD_WriteRAM_Prepare();
  LCD_TRANMITE(320*480*2);    	   
}


void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)
{	
	
		LCD_WR_REG(lcddev.setxcmd); 
		LCD_WR_DATA16(x);

		LCD_WR_REG(lcddev.setycmd); 
		LCD_WR_DATA16(y);
			
		LCD_WR_REG(lcddev.wramcmd); 
		LCD_WR_DATA16(color); 
}	 



//*******************************************************************/
//º¯Êý£ºvoid LCD_Scan_Dir(u8 dir)
//º¯Êý¹¦ÄÜ£ºÉèÖÃLCDµÄ×Ô¶¯É¨Ãè·½Ïò
//ÊäÈë²ÎÊý£º

//ĬÈÏÉèÖÃΪL2R_U2D,Èç¹ûÉèÖÃΪÆäËûɨÃ跽ʽ,¿ÉÄܵ¼ÖÂÏÔʾ²»Õý³£.
//dir:0~7,´ú±í8¸ö·½Ïò

//DevEBox  ´óÔ½´´ÐÂ
//ÌÔ±¦µêÆÌ£ºmcudev.taobao.com
//ÌÔ±¦µêÆÌ£ºshop389957290.taobao.com	
//*******************************************************************/

void LCD_Scan_Dir(u8 dir)
{
	u8 regval=0;

	//ɨÃè·½Ïò¶¨Òå--ɨÃ跽ʽÓв»Í¬¹æ¸ñ£¬¿ÉÄܶ¨Òå²»×óÓÒºÍÉÏϵIJÎÕÕ·½Ïò²»Í¬£¬×᷽ܽʽ£¬Ö»ÓÐһϰËÖÖ
	dir=2;
	
	switch(dir)
		{
			case 0:
				regval|=(0<<7)|(0<<6)|(0<<5); 
				break;
			case 1:
				regval|=(0<<7)|(1<<6)|(1<<5); 
				break;
			case 2:
				regval|=(0<<7)|(1<<6)|(0<<5)|(1<<3); 
				break;
			case 3:
				regval|=(1<<7)|(0<<6)|(1<<5); 
				break;	 
	 
		}
				
		LCD_WriteReg(0x36,regval);//¸Ä±äɨÃè·½ÏòÃüÁî  ---´Ë´¦ÐèÒª²é¿´Êý¾ÝÊֲᣬȷ¶¨RGBÑÕÉ«½»»»Î»µÄÅäÖÃ


} 




/**************************************************************************/
//º¯Êý£ºvoid LCD_Display_Dir(u8 dir)
//º¯Êý¹¦ÄÜ£ºÉèÖÃLCDµÄÏÔʾ·½Ïò¼°ÏñËØ²ÎÊý

//ÊäÈë²ÎÊý£º

//ÉèÖÃLCDÏÔʾ·½Ïò

////dir:   0,ÊúÆÁ  Õý
//         1,ÊúÆÁ  ·´
//         2,ºáÆÁ  ×ó
//         3,ºáÆÁ  ÓÒ

void LCD_Display_Dir(u8 dir)
{
	
	u8 SCAN_DIR;
		
	if(dir==0)			     //ÊúÆÁ  Õý
	{
		lcddev.dir=0;	     //ÊúÆÁ
		lcddev.width=320;
		lcddev.height=480;
    
		lcddev.wramcmd=0X2C;
	 	lcddev.setxcmd=0X2A;
		lcddev.setycmd=0X2B;

    SCAN_DIR=0; //Ñ¡ÔñɨÃè·½Ïò		
		

	}
	
else if (dir==1)			 //ºáÆÁ
	{	  				
		lcddev.dir=0;	     //ºáÆÁ
		lcddev.width=480;
		lcddev.height=320;
    
		lcddev.wramcmd=0X2C;
	 	lcddev.setxcmd=0X2A;
		lcddev.setycmd=0X2B;
		
    SCAN_DIR=1; //Ñ¡ÔñɨÃè·½Ïò		

		
	} 	
	
	
	else if (dir==2)			//ÊúÆÁ  
	{	  				
		lcddev.dir=1;	     //ÊúÆÁ  
		lcddev.width=320;
		lcddev.height=480;

		lcddev.wramcmd=0X2C;
	 	lcddev.setxcmd=0X2A;
		lcddev.setycmd=0X2B;  
		
    SCAN_DIR=2; //Ñ¡ÔñɨÃè·½Ïò		
	
		
	} 
 else if (dir==3)				  //ºáÆÁ
	{	  				
		lcddev.dir=1;	        //ºáÆÁ
		lcddev.width=480;
		lcddev.height=320;

		lcddev.wramcmd=0X2C;
	 	lcddev.setxcmd=0X2A;
		lcddev.setycmd=0X2B; 
    
    SCAN_DIR=3; //Ñ¡ÔñɨÃè·½Ïò

	

	} 	
 else //ÉèÖÃĬÈÏΪÊúÆÁ--Õý
 {
	  lcddev.dir=0;	     //ÊúÆÁ
		lcddev.width=320;
		lcddev.height=480;
    
		lcddev.wramcmd=0X2C;
	 	lcddev.setxcmd=0X2A;
		lcddev.setycmd=0X2B;

    SCAN_DIR=0; //Ñ¡ÔñɨÃè·½Ïò		
	 

 }	 

 
 //////ÒÔÏÂÉèÖã¬Îª´°¿Ú²ÎÊýÉèÖã¬ÉèÖÃÁËÈ«ÆÁµÄÏÔʾ·¶Î§			

    LCD_Set_Window(0,0,lcddev.width,lcddev.height);//ÉèÖÃÈ«ÆÁ´°¿Ú	

 /////ÉèÖÃÆÁÄ»ÏÔʾ--ɨÃè·½Ïò
	
	  LCD_Scan_Dir(SCAN_DIR);	//ÉèÖÃÆÁÄ»ÏÔʾ--ɨÃè·½Ïò
	
     
}	
void SHOW_PIC_DMA(void){
		long i;
		LCD_SetCursor(0x00,0x00);
		LCD_WriteRAM_Prepare();
		LCD_CS_CLR;
		LCD_RS_SET;
		for(i=0;i<320*480*2;i+=38400){
			HAL_SPI_Transmit_DMA(&SPI,&gImage_mn[i],38400);
			while(HAL_SPI_GetState(&SPI)!=HAL_SPI_STATE_READY);
		}	
		LCD_CS_SET; 
}

/**************************************************************************/
//º¯Êý£ºvoid LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)
//º¯Êý¹¦ÄÜ£ºÉèÖÃLCDµÄÏÔʾ´°¿Ú

//ÉèÖô°¿Ú,²¢×Ô¶¯ÉèÖû­µã×ø±êµ½´°¿Ú×óÉϽÇ(sx,sy).
//sx,sy:´°¿ÚÆðÊ¼×ø±ê(×óÉϽÇ)
//width,height:´°¿Ú¿í¶ÈºÍ¸ß¶È,±ØÐë´óÓÚ0!!
//´°Ìå´óС:width*height.

//DevEBox  ´óÔ½´´ÐÂ
//ÌÔ±¦µêÆÌ£ºmcudev.taobao.com
//ÌÔ±¦µêÆÌ£ºshop389957290.taobao.com	
//*************************************************************************/

void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)
{   
	
	
	  width=sx+width-1;
	  height=sy+height-1;

	if(LCD_DIR_Mode==0)
		{	
			LCD_WR_REG(lcddev.setxcmd); 
			LCD_WR_DATA16(sx);      //ÉèÖà X·½ÏòÆðµã
			LCD_WR_DATA16(width);   //ÉèÖà X·½ÏòÖÕµã	
		
			LCD_WR_REG(lcddev.setycmd);
			LCD_WR_DATA16(sy);      //ÉèÖà Y·½ÏòÆðµã
			LCD_WR_DATA16(height);  //ÉèÖà Y·½ÏòÖÕµã
		}
	else if(LCD_DIR_Mode==1)
		{	
			LCD_WR_REG(lcddev.setxcmd); 
			LCD_WR_DATA16(sx);      //ÉèÖà X·½ÏòÆðµã
			LCD_WR_DATA16(width);   //ÉèÖà X·½ÏòÖÕµã	
		
			LCD_WR_REG(lcddev.setycmd);
			LCD_WR_DATA16(sy);      //ÉèÖà Y·½ÏòÆðµã
			LCD_WR_DATA16(height);  //ÉèÖà Y·½ÏòÖÕµã
		}	
		else if(LCD_DIR_Mode==2)
		{	
			LCD_WR_REG(lcddev.setxcmd); 
			LCD_WR_DATA16(sx);      //ÉèÖà X·½ÏòÆðµã
			LCD_WR_DATA16(width);   //ÉèÖà X·½ÏòÖÕµã	
		
			LCD_WR_REG(lcddev.setycmd);
			LCD_WR_DATA16(sy);      //ÉèÖà Y·½ÏòÆðµã
			LCD_WR_DATA16(height);  //ÉèÖà Y·½ÏòÖÕµã
		}		
	 else if(LCD_DIR_Mode==3)
		{	
			LCD_WR_REG(lcddev.setxcmd); 
			LCD_WR_DATA16(sx);      //ÉèÖà X·½ÏòÆðµã
			LCD_WR_DATA16(width);   //ÉèÖà X·½ÏòÖÕµã	
		
			LCD_WR_REG(lcddev.setycmd);
			LCD_WR_DATA16(sy);      //ÉèÖà Y·½ÏòÆðµã
			LCD_WR_DATA16(height);  //ÉèÖà Y·½ÏòÖÕµã
		}
} 


void LCD_Init(void)//lcd³õʼ»¯
{ 	
	 
		MX_SPI1_Init();
		LCD_SoftRest();        //Èí¸´Î» 
 	  	HAL_Delay(50);      // delay 50 ms 
		LCD_WR_REG(0x3A);//½Ó¿ÚÏñËØ¸ñʽ
		LCD_WR_DATA8(0x55);
		LCD_WR_REG(0xB2);     //ÃÅÀÈÉèÖÃ
		LCD_WR_DATA8(0x0C);
		LCD_WR_DATA8(0x0C);
		LCD_WR_DATA8(0x00);
		LCD_WR_DATA8(0x33);
		LCD_WR_DATA8(0x33); 
		LCD_WR_REG(0xB7);    //ÃÅ¿ØÖÆ
		LCD_WR_DATA8(0x35);  
		LCD_WR_REG(0xBB);    //VCOM Setting
		LCD_WR_DATA8(0x19);
		LCD_WR_REG(0xC0);    //LCM Control
		LCD_WR_DATA8(0x2C);
		LCD_WR_REG(0xC2);   //VDV and VRH Command Enable
		LCD_WR_DATA8(0x01);
		LCD_WR_REG(0xC3);  //VRH Set
		LCD_WR_DATA8(0x12);   
		LCD_WR_REG(0xC4);  //VDV Set
		LCD_WR_DATA8(0x20);  
		LCD_WR_REG(0xC6);   //Õý³£Ä£Ê½ÏµÄÖ¡ÂÊ¿ØÖÆ
		LCD_WR_DATA8(0x0F); //֡ƵÂÊ60Ö¡   
		LCD_WR_REG(0xD0);   //Power Control
		LCD_WR_DATA8(0xA4);
		LCD_WR_DATA8(0xA1);
		LCD_WR_REG(0xE0);    //Õýµçѹ٤Âê¿ØÖÆ
		LCD_WR_DATA8(0xD0);
		LCD_WR_DATA8(0x04);
		LCD_WR_DATA8(0x0D);
		LCD_WR_DATA8(0x11);
		LCD_WR_DATA8(0x13);
		LCD_WR_DATA8(0x2B);
		LCD_WR_DATA8(0x3F);
		LCD_WR_DATA8(0x54);
		LCD_WR_DATA8(0x4C);
		LCD_WR_DATA8(0x18);
		LCD_WR_DATA8(0x0D);
		LCD_WR_DATA8(0x0B);
		LCD_WR_DATA8(0x1F);
		LCD_WR_DATA8(0x23);
		LCD_WR_REG(0xE1);   //¸ºµçѹ٤Âê¿ØÖÆ
		LCD_WR_DATA8(0xD0);
		LCD_WR_DATA8(0x04);
		LCD_WR_DATA8(0x0C);
		LCD_WR_DATA8(0x11);
		LCD_WR_DATA8(0x13);
		LCD_WR_DATA8(0x2C);
		LCD_WR_DATA8(0x3F);
		LCD_WR_DATA8(0x44);
		LCD_WR_DATA8(0x51);
		LCD_WR_DATA8(0x2F);
		LCD_WR_DATA8(0x1F);
		LCD_WR_DATA8(0x1F);
		LCD_WR_DATA8(0x20);
		LCD_WR_DATA8(0x23);
		LCD_WR_REG(0x11); //Í˳öÐÝÃß
		LCD_WR_REG(0x29); //¿ªÏÔʾ
	  	LCD_Display_Dir(LCD_DIR_Mode);	//Ñ¡Ôñ--ÆÁÄ»ÏÔʾ·½Ê½
		LCD_BLK_On;
		LCD_RST_SET;
	
}



void LCD_Clear(u16 color)
{
	u32 index=0;
	u32 totalpoint;
	
	LCD_Set_Window(0,0,lcddev.width,lcddev.height);//ÉèÖÃÈ«ÆÁ´°¿Ú
	
	totalpoint=lcddev.width * lcddev.height; 			//µÃµ½×ܵãÊý
 
	LCD_SetCursor(0x00,0x00);	//ÉèÖùâ±êλÖà 
	
	LCD_WriteRAM_Prepare();     		//¿ªÊ¼Ð´ÈëGRAM	
	
	for(index=0;index<totalpoint;index++)
	{
		LCD_WR_DATA16(color);	
	}
} 

void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)//color fill
{          
		u32 i;
		u32 xlen=0;
    	LCD_Set_Window(sx,sy,ex-sx+1,ey-sy+1);//ÉèÖô°¿Ú
	  	LCD_WR_REG(lcddev.wramcmd);	  
 		xlen=(ex-sx+1)*(ey-sy+1);//¼ÆËã³ö×ܹ²ÐèҪдÈëµÄµãÊý
		LCD_WriteRAM_Prepare();     			//¿ªÊ¼Ð´ÈëGRAM
		for(i=0;i<=xlen*2;i+=2)
		{
		 	gram[i]=color>>8;
			gram[i+1]=color; 
		}
		LCD_TRANMITE(xlen*2);		
   		LCD_Set_Window(0,0,lcddev.width,lcddev.height);//ÉèÖÃÈ«ÆÁ´°¿Ú	
}
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
{  

		u32 i;
		u32 xlen=0;	
		LCD_Set_Window(sx,sy,ex-sx+1,ey-sy+1);

		LCD_WR_REG(lcddev.wramcmd);	  

		xlen=(ex-sx+1)*(ey-sy+1);

		LCD_WriteRAM_Prepare();

		for(i=0;i<=xlen;i++)
		{
		LCD_WR_DATA16(*color);	    
		}

		LCD_Set_Window(0,0,lcddev.width,lcddev.height);
		

}

void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2, u16 Color)
{
	u16 t; 
	int xerr=0,yerr=0,delta_x,delta_y,distance; 
	int incx,incy,uRow,uCol; 
	
	delta_x=x2-x1; //¼ÆËã×ø±êÔöÁ¿ 
	delta_y=y2-y1; 
	uRow=x1; 
	uCol=y1; 
	
	
	if(delta_x>0)incx=1; //ÉèÖõ¥²½·½Ïò 
	else if(delta_x==0)incx=0;//´¹Ö±Ïß 
	else
     {
		    incx=-1;
		    delta_x=-delta_x;
		 }

	
	if(delta_y>0)incy=1; 
	else if(delta_y==0)incy=0;//ˮƽÏß 
	else
     { 
		   incy=-1;
		   delta_y=-delta_y;
		 }

	
	if( delta_x>delta_y)distance=delta_x; //ѡȡ»ù±¾ÔöÁ¿×ø±êÖá 
	else distance=delta_y; 
	
	for(t=0;t<=distance+1;t++ )//»­ÏßÊä³ö 
	{  
		LCD_Fast_DrawPoint(uRow,uCol,Color);//»­µã --ʹÓÃÊäÈëÑÕÉ«²ÎÊý 
		xerr+=delta_x ; 
		yerr+=delta_y ; 
		if(xerr>distance) 
		{ 
			xerr-=distance; 
			uRow+=incx; 
		} 
		if(yerr>distance) 
		{ 
			yerr-=distance; 
			uCol+=incy; 
		} 
	}  
} 

void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2, u16 Color)//»­¸ö¿ò
{
	LCD_DrawLine(x1,y1,x2,y1,Color);
	LCD_DrawLine(x1,y1,x1,y2,Color);
	LCD_DrawLine(x1,y2,x2,y2,Color);
	LCD_DrawLine(x2,y1,x2,y2,Color);
}


void LCD_Draw_Circle(u16 x0,u16 y0,u8 r, u16 Color)//»­Ô²
{
	int a,b;
	int di;
	a=0;b=r;	  
	di=3-(r<<1);             //ÅжÏϸöµãλÖõıêÖ¾
	while(a<=b)
	{
		LCD_Fast_DrawPoint(x0+a,y0-b,Color);             //5
 		LCD_Fast_DrawPoint(x0+b,y0-a,Color);             //0           
		LCD_Fast_DrawPoint(x0+b,y0+a,Color);             //4               
		LCD_Fast_DrawPoint(x0+a,y0+b,Color);             //6 
		LCD_Fast_DrawPoint(x0-a,y0+b,Color);             //1       
 		LCD_Fast_DrawPoint(x0-b,y0+a,Color);             
		LCD_Fast_DrawPoint(x0-a,y0-b,Color);             //2             
  	LCD_Fast_DrawPoint(x0-b,y0-a,Color);             //7     	         
		a++;
		//ʹÓÃBresenhamËã·¨»­Ô²     
		if(di<0)di +=4*a+6;	  
		else
		{
			di+=10+4*(a-b);   
			b--;
		} 						    
	}
}




void LCD_ShowChar(u16 x,u16 y,u8 num,u8 size,u16 color,u8 mode)
{  							  
  	u8 temp,t1,t;
	u16 y0=y;
	u8 csize=(size/8+((size%8)?1:0))*(size/2);		//µÃµ½×ÖÌåÒ»¸ö×Ö·û¶ÔÓ¦µãÕó¼¯ËùÕ¼µÄ×Ö½ÚÊý	
	//ÉèÖô°¿Ú		   
	num=num-' ';//µÃµ½Æ«ÒƺóµÄÖµ
	for(t=0;t<csize;t++)
	{   
		if(size==12)
			temp=asc2_1206[num][t]; 	 	//µ÷ÓÃ1206×ÖÌå
		else if(size==16)
			temp=asc2_1608[num][t];	//µ÷ÓÃ1608×ÖÌå
		else if(size==24)
			temp=asc2_2412[num][t];	//µ÷ÓÃ2412×ÖÌå
		else return;								//ûÓеÄ×Ö¿â
		for(t1=0;t1<8;t1++)
		{			    
			if(temp&0x80)
				LCD_Fast_DrawPoint(x,y,color);
			else if(mode==0)
				LCD_Fast_DrawPoint(x,y,BLACK);
			temp<<=1;
			y++;
			if(y>=lcddev.height)return;		//³¬ÇøÓòÁË
			if((y-y0)==size)
			{
				y=y0;
				x++;
				if(x>=lcddev.width)return;	//³¬ÇøÓòÁË
				break;
			}
		}  	 
	}  	    	   	 	  
}


u32 LCD_Pow(u8 m,u8 n)//ƽ·½
{
	u32 result=1;	 
	while(n--)result*=m;    
	return result;
}	


void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size,u16 color)//º¯Êý¹¦ÄÜ£ºÏÔʾÊý×Ö,¸ßλΪ0,Ôò²»ÏÔʾ
{         	
	u8 t,temp;
	u8 enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/LCD_Pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				LCD_ShowChar(x+(size/2)*t,y,' ',size,color,0);
				continue;
			}else enshow=1; 
		 	 
		}
	 	LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,color,0); 
	}
} 


//[7]:0,²»Ìî³ä;1,Ìî³ä0.
//[6:1]:±£Áô
//[0]:0,·Çµþ¼ÓÏÔʾ;1,µþ¼ÓÏÔʾ.
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u16 color,u8 mode)//º¯Êý¹¦ÄÜ£ºÏÔʾÊý×Ö,¸ßλΪ0,Ôò²»ÏÔʾ
{  
	u8 t,temp;
	u8 enshow=0;						   
	for(t=0;t<len;t++)
	{
		temp=(num/LCD_Pow(10,len-t-1))%10;
		if(enshow==0&&t<(len-1))
		{
			if(temp==0)
			{
				if(mode&0X80)LCD_ShowChar(x+(size/2)*t,y,'0',size,color,mode&0X01);  
				else LCD_ShowChar(x+(size/2)*t,y,' ',size,color,mode&0X01);  
 				continue;
			}else enshow=1; 
		 	 
		}
	 	LCD_ShowChar(x+(size/2)*t,y,temp+'0',size,color,mode&0X01); 
	}
} 


void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u16 color,u8 *p,uint8_t mode)
{         
	u8 x0=x;
	width+=x;
	height+=y;
    while((*p<='~')&&(*p>=' '))//ÅжÏÊDz»ÊÇ·Ç·¨×Ö·û!
    {       
        if(x>=width){x=x0;y+=size;}
        if(y>=height)break;//Í˳ö
        LCD_ShowChar(x,y,*p,size,color,mode);
        x+=size/2;
        p++;
    }  
}

void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2)//¹¦ÄÜÃèÊö: ÔÚÆÁÄ»ÏÔʾһ͹ÆðµÄ°´Å¥¿ò
{
	
	LCD_DrawLine(x1,y1, x2,y1,GRAY2);  //H
		
	LCD_DrawLine(x1+1,y1+1,x2,y1+1,GRAY1);  //H
		
	LCD_DrawLine(x1,  y1,  x1,y2,GRAY2);    //V
		
	LCD_DrawLine(x1+1,y1+1,x1+1,y2,GRAY1);  //V
	
	LCD_DrawLine(x1, y2, x2, y2,WHITE);     //H
	LCD_DrawLine(x2, y1, x2, y2,WHITE);     //V
}


void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2)//¹¦ÄÜÃèÊö: ÔÚÆÁÄ»ÏÔʾһ°¼Ïµİ´Å¥¿ò
{
	
	LCD_DrawLine(x1,  y1,  x2,y1,WHITE);    //H
	LCD_DrawLine(x1,  y1,  x1,y2,WHITE);    //V
	
	LCD_DrawLine(x1+1,y2-1,x2,y2-1,GRAY1);  //H
		
	LCD_DrawLine(x1,  y2,  x2,y2,GRAY2);    //H
		
	LCD_DrawLine(x2-1,y1+1,x2-1,y2,GRAY1);  //V
		
  LCD_DrawLine(x2  ,y1  ,x2,y2,GRAY2);    //V
	

}

void Draw_Test(void)
{
	
		LCD_Clear(WHITE); //ÇåÆÁ
		
	  LCD_DrawLine(20,64, 220,128,RED);//»®Ïߺ¯Êý
	  LCD_DrawLine(20,128, 220,64,RED);//»®Ïߺ¯Êý
	
	  LCD_DrawRectangle(20,64,220,128, BLUE);//»æÖÆ·½ÐÎ×´
	  
	  LCD_Draw_Circle(120,96,81, BRED);//»æÖÆÔ²ÐÎ
	  LCD_Draw_Circle(120,96,80, BRED);//»æÖÆÔ²ÐÎ
	  LCD_Draw_Circle(120,96,79, BRED);//»æÖÆÔ²ÐÎ
			
		HAL_Delay(2000);//ÑÓʱ

}


void Color_Test(void)
{
	
		LCD_Clear(GRAY0); //ÇåÆÁ

		Draw_Font16B(24,16,BLUE,"1: ÑÕÉ«Ìî³ä²âÊÔ");

		LCD_Fill(5,5,lcddev.width-5,lcddev.height-5,RED);//ÉèÖÃÒ»¸ö´°¿Ú£¬Ð´ÈëÖ¸¶¨ÇøÓòÑÕÉ«

		LCD_Fill(20,20,lcddev.width-20,lcddev.height-20,YELLOW);//ÉèÖÃÒ»¸ö´°¿Ú£¬Ð´ÈëÖ¸¶¨ÇøÓòÑÕÉ«

		LCD_Fill(50,50,lcddev.width-50,lcddev.height-50,BLUE);//ÉèÖÃÒ»¸ö´°¿Ú£¬Ð´ÈëÖ¸¶¨ÇøÓòÑÕÉ«

		LCD_Fill(80,100,lcddev.width-80,lcddev.height-80,MAGENTA);//ÉèÖÃÒ»¸ö´°¿Ú£¬Ð´ÈëÖ¸¶¨ÇøÓòÑÕÉ«

		HAL_Delay(2000);

		LCD_Clear(WHITE);

		Draw_Test();//»æÍ¼º¯Êý²âÊÔ

		HAL_Delay(300);//ÑÓʱ
		LCD_Clear(BLACK);
		HAL_Delay(300);//ÑÓʱ
		LCD_Clear(RED);
		HAL_Delay(300);//ÑÓʱ
		LCD_Clear(YELLOW);
		HAL_Delay(300);//ÑÓʱ
		LCD_Clear(GREEN);
		HAL_Delay(300);//ÑÓʱ
		LCD_Clear(BLUE);
		HAL_Delay(300);//ÑÓʱ

}

uint16_t D_Color=BLUE; //µãÕóÑÕÉ«
uint16_t B_Color=WHITE; //±³¾°ÑÕÉ«

void Font_Test(void)
{
	LCD_Clear(GRAY0);
	Draw_Font16B(24,16,BLUE,"2: ÎÄ×ÖÏÔʾ²âÊÔ");

	HAL_Delay(1000);
	LCD_Clear(GRAY0);
	
	Draw_Font24B(16,4,BLACK,"DevEBox-´óÔ½´´ÐÂ");
	Draw_Font24B(48,32,BLACK,"Òº¾§ÆÁ²âÊÔ");
	
	Draw_Font16B(24,80, BLACK,"ǶÈëʽ¿ª·¢Íø");
	Draw_Font16B(24,96, GREEN,"ÖÐÎIJâÊÔ");
	Draw_Font16B(24,112,BLUE,"רעҺ¾§Åú·¢");
	Draw_Font16B(24,128,RED, "È«³Ì¼¼ÊõÖ§³Ö");
	Draw_Font16B(16,144,BLUE,"F: mcudev.taobao.com");
	Draw_Font16B(16,160,BLUE,"F: shop389957290.taobao.com");
	Draw_Font16B(16,176,RED,"0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");

	HAL_Delay(3000);	
	
	LCD_Clear(GRAY0);


}


void Demo_Menu(void)
{

	LCD_Clear(GRAY0); //ÇåÆÁ
	
	Draw_Font24B(16,4,MAGENTA,"DevEBox-´óÔ½´´ÐÂ");
	Draw_Font24B(48,32,MAGENTA,"Òº¾§ÆÁ²âÊÔ");


	DisplayButtonUp(16,64,224,88); //x1,y1,x2,y2
	Draw_Font16B(48,68,BLUE,"1: ÑÕÉ«Ìî³ä²âÊÔ");

	DisplayButtonUp(16,104,224,128); //x1,y1,x2,y2
	Draw_Font16B(48,108,BLUE,"2: ÎÄ×ÖÏÔʾ²âÊÔ");

	DisplayButtonUp(16,144,224,168); //x1,y1,x2,y2
	Draw_Font16B(48,148,BLUE,"3: ͼƬÏÔʾ²âÊÔ");
  
	Draw_Font16B(16,180,RED,"F: mcudev.taobao.com");
	Draw_Font16B(16,196,RED,"F: shop389957290.taobao.com");
	
	HAL_Delay(2000);//ÑÓʱ
		
	Color_Test(); 
	Font_Test();
	


}












lcd这部分直接移植就好了,不用都一样

需要注意

HAL_SPI_Transmit_DMA(&SPI,&gram[i],38400);
		while(HAL_SPI_GetState(&SPI)!=HAL_SPI_STATE_READY);

由于DMA传输不需要CPU参与,是不阻塞cpu的,在我写的DMA刷屏函数中使用循环发送,如果不主动阻塞的话就会发送前一个没发完后一个又来了,产生BUSY,所以主动读标志位,阻塞到发送完成.

由于使用的HAL库,发送大小有int范围限制,所以选取一个大小差不多的范围,38400传输8次刚刚好

另外我只写了刷新全屏的,局部刷新也是一个原理需要使用开窗和指定位置操作,随后将对应大小数组刷过去.

MAIN.C

不知道为什么触摸和dma有点冲突,会导致dma卡死

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "i2c.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "GT911.h"
//#include "Dis_Picture.h"
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
int num=0;
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */
	int i=0;
  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_ADC3_Init();
  MX_I2C2_Init();
  MX_TIM2_Init();
  MX_SPI1_Init();
  MX_TIM8_Init();
  /* USER CODE BEGIN 2 */
	GT911_INIT();
	LCD_Init();
	LCD_QCLEAR(GREEN);
	Delay(100);
	LCD_QCLEAR_DMA(RED);
  //LCD_QCLEAR(GREEN);
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		SHOW_PIC_DMA();
		LCD_QCLEAR(WHITE);
		

  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Supply configuration update enable
  */
  HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 8;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

 /* MPU Configuration */

void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};

  /* Disables the MPU */
  HAL_MPU_Disable();

  /** Initializes and configures the Region and the memory to be protected
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x0;
  MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
  MPU_InitStruct.SubRegionDisable = 0x87;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

}

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

代码打包

链接:https://pan.baidu.com/s/1XfTWm7aT6FEZASfxmKD34w 
提取码:elc8

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值