| 硬件简介 主控:STM32H750
 
 LCD屏幕为16位并口屏幕
 
 CubeMX配置
 
 
   
 chip select: 选择起始地址块号,ADDR[27:26]
 
 Memory type: 内存类型,选择LCD Interface
 
 LCD Register Select: 根据选择计算映射地址, FSNC_A[25]
 
 Data: 数据宽度
 
 NOR/PSRAM timing: 调整时间,能够提升屏幕刷新的速率
 
 代码
 2.1 获取LCD屏幕驱动源码
 获取到一份能够正常使用的屏幕驱动源码
 
 2.2 计算地址
 #define Bank1_LCD_DATA ((uint32_t)0x60080000) /* display data address */
 #define Bank1_LCD_REG ((uint32_t)0X60000000)  /* display register addres
 
 
 2.3.1 根据chip select计算 register addres
 NE1 -NE4分别对应ADDR[27:26]对应00 - 11
 
 对应的为映射起始地址
 
 
   
 2.3.2 根据Memory type和LCD Register Select计算data address
 
 
   
 对于8位数据宽度的地址为:
 
 Bank1_LCD_DATA = Bank1_LCD_REG + 1 << 18(LCD Register Select + 0)
 
 对于16位数据宽度的地址为:
 
 Bank1_LCD_DATA = Bank1_LCD_REG + 1 << (18 + 1)(LCD Register Select + 1)
 
 所以
 
 #define Bank1_LCD_DATA ((uint32_t)0x60080000) /* display data address */
 
 驱动代码
 lcd.h
 #ifndef __LCD_H
 #define __LCD_H
 
 /* BEGIN Includes */
 #include "main.h"
 /* END Includes */
 
 void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color);
 void LCD_Fill_1(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint8_t color);
 void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color);
 void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color);
 //void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[]);
 void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint16_t pic[]);
 
 #endif /* __LCD_H */
 
 
 lcd.c
 /* BEGIN Includes */
 
 #include "lcd.h"
 #include "Lcd_init.h"
 #include <string.h>
 #include "dma.h"
 /* END Includes */
 
 /******************************************************************************
 函数说明:在指定区域填充颜色
 入口数据:   xsta,ysta   起始坐标
 xend,yend   终止坐标
 color       要填充的颜色
 返回值:  无
 ******************************************************************************/
 void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
 {
 uint16_t i,j;
 LCD_Address_Set(xsta,ysta,xend-1,yend-1);
 for(i=ysta;i<yend;i++)
 {
 for(j=xsta;j<xend;j++)
 {
 LCD_WR_DATA(color);
 }
 }
 }
 
 static uint8_t buf[240*10*2] __attribute__((section(".ARM.__at_0x38000400")));
 void LCD_Fill_1(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint8_t color)
 {
 
 memset(buf, color, sizeof(buf));
 LCD_Address_Set(xsta,ysta,xend-1,yend-1);
 HAL_DMA_Start_IT(&hdma_memtomem_dma1_stream0, (uint32_t)0x38000400, Bank1_LCD_DATA, ((yend + 1) - ysta) * ((xend + 1) - xsta) * 2);
 
 }
 /******************************************************************************
 函数说明:在指定位置画点
 入口数据:x,y 画点坐标
 color 点的颜色
 返回值:  无
 ******************************************************************************/
 void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color)
 {
 LCD_Address_Set(x,y,x,y);//
 LCD_WR_DATA(color);
 }
 /******************************************************************************
 函数说明:画线
 入口数据:x1,y1   起始坐标
 x2,y2   终止坐标
 color   线的颜色
 返回值:  无
 ******************************************************************************/
 void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
 {
 uint16_t 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_DrawPoint(uRow,uCol,color);//
 xerr+=delta_x;
 yerr+=delta_y;
 if(xerr>distance)
 {
 xerr-=distance;
 uRow+=incx;
 }
 if(yerr>distance)
 {
 yerr-=distance;
 uCol+=incy;
 }
 }
 }
 /******************************************************************************
 函数说明:画矩形
 入口数据:x1,y1   起始坐标
 x2,y2   终止坐标
 color   矩形的颜色
 返回值:  无
 ******************************************************************************/
 void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t 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);
 }
 /******************************************************************************
 函数说明:画圆
 入口数据:x0,y0   圆心坐标
 r       半径
 color   圆的颜色
 返回值:  无
 ******************************************************************************/
 void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color)
 {
 int a,b;
 a=0;b=r;
 while(a<=b)
 {
 LCD_DrawPoint(x0-b,y0-a,color);             //3
 LCD_DrawPoint(x0+b,y0-a,color);             //0
 LCD_DrawPoint(x0-a,y0+b,color);             //1
 LCD_DrawPoint(x0-a,y0-b,color);             //2
 LCD_DrawPoint(x0+b,y0+a,color);             //4
 LCD_DrawPoint(x0+a,y0-b,color);             //5
 LCD_DrawPoint(x0+a,y0+b,color);             //6
 LCD_DrawPoint(x0-b,y0+a,color);             //7
 a++;
 if((a*a+b*b)>(r*r))//
 {
 b--;
 }
 }
 }
 
 
 /******************************************************************************
 函数说明:显示图片
 入口数据:x,y起点坐标
 length 图片长度
 width  图片宽度
 pic[]  图片数组
 返回值:  无
 ******************************************************************************/
 
 void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint16_t pic[])
 {
 uint16_t i,j;
 uint32_t 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_DATA(pic[k]);
 k++;
 }
 }
 
 }
 
 
 
 Lcd_init.h
 #ifndef __LCD_INIT_H
 #define __LCD_INIT_H
 
 /* BEGIN Includes */
 #include "main.h"
 /* END Includes */
 
 #define USE_HORIZONTAL 1  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏
 
 #if USE_HORIZONTAL==0||USE_HORIZONTAL==1
 
 #define LCD_W 320
 #define LCD_H 240
 
 #else
 #define LCD_W 320
 #define LCD_H 240
 #endif
 
 //#define Bank1_LCD_DATA ((uint32_t)0x60108CA0) /* display data address */
 #define Bank1_LCD_DATA ((uint32_t)0x6010fff0) /* display data address */
 #define Bank1_LCD_REG ((uint32_t)0X60000000)  /* display register address */
 
 #define LCD_FMC_DATA(value) ((*(__IO uint8_t  *)(Bank1_LCD_DATA)) = ((uint8_t )(value))) // 写数据寄存器
 #define LCD_FMC_REG(index) ((*(__IO uint8_t  *)(Bank1_LCD_REG)) = ((uint8_t )index))
 
 #define LCD_SCLK_Clr         //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,0)//SCL=SCLK
 #define LCD_SCLK_Set         //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,1)
 
 #define LCD_MOSI_Clr        //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,0)//SDA=MOSI
 #define LCD_MOSI_Set        //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,1)
 
 #define LCD_RES_Clr                HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,0)//RES
 #define LCD_RES_Set                HAL_GPIO_WritePin(GPIOE,GPIO_PIN_1,1)
 
 #define LCD_DC_Clr                HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,0)//DC
 #define LCD_DC_Set                HAL_GPIO_WritePin(GPIOE,GPIO_PIN_4,1)
 
 #define LCD_CS_Clr                HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,0)//CS
 #define LCD_CS_Set                HAL_GPIO_WritePin(GPIOC,GPIO_PIN_7,1)
 
 #define LCD_BLK_Clr() //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,0)//BLK
 #define LCD_BLK_Set() //HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,1)
 
 void LCD_Writ_Bus(uint8_t dat);//
 void LCD_WR_DATA8(uint8_t dat);//
 void LCD_WR_DATA(uint16_t dat);//
 void LCD_WR_REG(uint8_t dat);//
 void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);//
 void LCD_Init(void);//
 
 #endif /* __LCD_INIT_H */
 
 
 
 Lcd_init_.c
 /* BEGIN Includes */
 
 #include "Lcd_init.h"
 #include "lcd.h"
 
 /* END Includes */
 
 void LCD_Writ_Bus(uint8_t dat)
 {
 
 LCD_FMC_DATA(dat);
 }
 void LCD_WR_DATA8(uint8_t dat)
 {
 LCD_FMC_DATA(dat);
 }
 
 void LCD_WR_DATA(uint16_t dat)
 {
 LCD_FMC_DATA(dat >> 8);
 LCD_FMC_DATA(dat);
 }
 
 void LCD_WR_REG(uint8_t dat)
 {
 LCD_FMC_REG(dat);
 }
 void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
 {
 LCD_WR_REG(0x2a);//
 LCD_Writ_Bus(x1>>8);
 LCD_Writ_Bus(x1);
 LCD_Writ_Bus(x2>>8);
 LCD_Writ_Bus(x2);
 LCD_WR_REG(0x2b);//
 
 LCD_Writ_Bus(y1>>8);
 LCD_Writ_Bus(y1);
 LCD_Writ_Bus(y2>>8);
 LCD_Writ_Bus(y2);
 LCD_WR_REG(0x2c);//
 }
 void LCD_Init(void)
 {
 
 
 LCD_RES_Clr;//
 HAL_Delay(100);
 LCD_RES_Set;
 HAL_Delay(100);
 
 LCD_BLK_Set();//
 HAL_Delay(100);
 
 //************* Start Initial Sequence **********//
 LCD_WR_REG(0x11);
 HAL_Delay(1000); //Delay 120ms
 LCD_WR_REG(0X36);// Memory Access Control
 
 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_DATA8(0X05);
 //--------------------------------ST7789S Frame rate setting-------------------------
 
 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);
 //---------------------------------ST7789S Power setting-----------------------------
 
 LCD_WR_REG(0xbb);
 LCD_WR_DATA8(0x35);
 LCD_WR_REG(0xc0);
 LCD_WR_DATA8(0x2c);
 LCD_WR_REG(0xc2);
 LCD_WR_DATA8(0x01);
 LCD_WR_REG(0xc3);
 LCD_WR_DATA8(0x13);
 LCD_WR_REG(0xc4);
 LCD_WR_DATA8(0x20);
 LCD_WR_REG(0xc6);
 LCD_WR_DATA8(0x0f);
 LCD_WR_REG(0xca);
 LCD_WR_DATA8(0x0f);
 LCD_WR_REG(0xc8);
 LCD_WR_DATA8(0x08);
 LCD_WR_REG(0x55);
 LCD_WR_DATA8(0x90);
 LCD_WR_REG(0xd0);
 LCD_WR_DATA8(0xa4);
 LCD_WR_DATA8(0xa1);
 //--------------------------------ST7789S gamma setting------------------------------
 LCD_WR_REG(0xe0);
 LCD_WR_DATA8(0xd0);
 LCD_WR_DATA8(0x00);
 LCD_WR_DATA8(0x06);
 LCD_WR_DATA8(0x09);
 LCD_WR_DATA8(0x0b);
 LCD_WR_DATA8(0x2a);
 LCD_WR_DATA8(0x3c);
 LCD_WR_DATA8(0x55);
 LCD_WR_DATA8(0x4b);
 LCD_WR_DATA8(0x08);
 LCD_WR_DATA8(0x16);
 LCD_WR_DATA8(0x14);
 LCD_WR_DATA8(0x19);
 LCD_WR_DATA8(0x20);
 LCD_WR_REG(0xe1);
 LCD_WR_DATA8(0xd0);
 LCD_WR_DATA8(0x00);
 LCD_WR_DATA8(0x06);
 LCD_WR_DATA8(0x09);
 LCD_WR_DATA8(0x0b);
 LCD_WR_DATA8(0x29);
 LCD_WR_DATA8(0x36);
 LCD_WR_DATA8(0x54);
 LCD_WR_DATA8(0x4b);
 LCD_WR_DATA8(0x0d);
 LCD_WR_DATA8(0x16);
 LCD_WR_DATA8(0x14);
 LCD_WR_DATA8(0x21);
 LCD_WR_DATA8(0x20);
 LCD_WR_REG(0x29);
 
 
 //        LCD_WR_REG(0x21);                        //´
 |