硬件简介
主控: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); //3LCD_DrawPoint(x0+b,y0-a,color); //0LCD_DrawPoint(x0-a,y0+b,color); //1LCD_DrawPoint(x0-a,y0-b,color); //2LCD_DrawPoint(x0+b,y0+a,color); //4LCD_DrawPoint(x0+a,y0-b,color); //5LCD_DrawPoint(x0+a,y0+b,color); //6LCD_DrawPoint(x0-b,y0+a,color); //7a++;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 120msLCD_WR_REG(0X36);// Memory Access Controlif(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); //´Չ«·´ת
}