Files
lcd_model/BSP/lcd.c
T
2025-06-18 12:20:53 +08:00

540 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "lcd.h"
#include "stdlib.h"
#include "main.h"
//管理LCD重要参数
//默认为竖屏
_lcd_dev lcddev;
//写寄存器函数
//regval:寄存器值
void LCD_WR_REG(uint16_t reg)
{
#if LCD_USE8BIT_MODEL==1//使用8位并行数据总线模式
LCD_RS_CLR;
LCD_CS_CLR;
DATAOUT(reg);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
LCD_RS_SET;
#else //使用16位并行数据总线模式
LCD_RS_CLR;
LCD_CS_CLR;
DATAOUT(reg);
LCD_WR_CLR;
LCD_WR_SET;
LCD_RS_SET;
LCD_CS_SET;
#endif
}
//写LCD数据
//data:要写入的值
void LCD_WR_data(uint16_t data)
{
#if LCD_USE8BIT_MODEL==1//使用8位并行数据总线模式
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
#else //使用16位并行数据总线模式
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
#endif
}
//写LCD数据
//data:要写入的值
void LCD_WR_DATA(uint16_t data)
{
#if LCD_USE8BIT_MODEL==1//使用8位并行数据总线模式
LCD_CS_CLR;
DATAOUT(data>>8);
LCD_WR_CLR;
LCD_WR_SET;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
#else //使用16位并行数据总线模式
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
#endif
}
//读LCD数据
//返回值:读到的值
uint16_t LCD_RD_DATA(void)
{
uint16_t data=0,data0=0;
LCD_DATA_IN();
#if LCD_USE8BIT_MODEL==1//使用8位并行数据总线模式
LCD_CS_CLR;
LCD_RD_CLR;
data=DATAIN;
LCD_RD_SET;
LCD_RD_CLR;
data0=DATAIN;
LCD_RD_SET;
LCD_CS_SET;
data&=0xff;
data=data0|data<<8;
#else //使用16位并行数据总线模式
LCD_CS_CLR;
LCD_RD_CLR;
data=DATAIN;
LCD_RD_SET;
LCD_CS_SET;
#endif
LCD_DATA_OUT();
return data;
}
/******************************************************************************
函数说明:设置起始和结束地址
入口数据:x1,x2 设置列的起始和结束地址
y1,y2 设置行的起始和结束地址
返回值: 无
******************************************************************************/
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x1>>8);
LCD_WR_DATA(x1&0xff);
LCD_WR_DATA(x2>>8);
LCD_WR_DATA(x2&0xff);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y1>>8);
LCD_WR_DATA(y1&0xff);
LCD_WR_DATA(y2>>8);
LCD_WR_DATA(y2&0xff);
LCD_WR_REG(0x2c);//储存器写
}
/******************************************************************************
函数说明:设置光标位置
入口数据:x,y 光标位置
返回值: 无
******************************************************************************/
void LCD_SetCursor(uint16_t x,uint16_t y)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA(x>>8);
LCD_WR_DATA(x&0xff);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA(y>>8);
LCD_WR_DATA(y&0xff);
}
//LCD开启显示
void LCD_DisplayOn(void)
{
LCD_WR_REG(0X29); //开启显示
}
//LCD关闭显示
void LCD_DisplayOff(void)
{
LCD_WR_REG(0X28); //关闭显示
}
//读取个某点的颜色值
//x,y:坐标
//返回值:此点的颜色
uint16_t LCD_ReadPoint(uint16_t x,uint16_t y)
{
uint16_t rgb;
LCD_SetCursor(x,y);
LCD_WR_REG(0X2E);
rgb=LCD_RD_DATA();//dummy Read
rgb=LCD_RD_DATA();//实际坐标颜色
return rgb;
}
void LCD_Clear(uint16_t color)
{
uint16_t i,j;
LCD_Address_Set(0,0,lcddev.width-1,lcddev.height-1);//设置显示范围
for(i=0;i<lcddev.width;i++)
{
for(j=0;j<lcddev.height;j++)
{
LCD_WR_DATA(color);
}
}
}
/******************************************************************************
函数说明:在指定区域填充颜色
入口数据: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);
}
}
}
/******************************************************************************
函数说明:在指定位置画点
入口数据: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--;
}
}
}
/******************************************************************************
函数说明:显示数字
入口数据:m底数,n指数
返回值: 无
******************************************************************************/
uint32_t mypow(uint8_t m,uint8_t n)
{
uint32_t result=1;
while(n--)result*=m;
return result;
}
/******************************************************************************
函数说明:显示图片
入口数据:x,y起点坐标
length 图片长度
width 图片宽度
pic[] 图片数组
返回值: 无
******************************************************************************/
void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[])
{
uint8_t picH,picL;
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++)
{
picH=pic[k*2];
picL=pic[k*2+1];
LCD_WR_DATA(picH<<8|picL);
k++;
}
}
}
void Set_Dir(uint8_t dir)
{
if((dir>>4)%4)
{
lcddev.width=480;
lcddev.height=320;
}else
{
lcddev.width=320;
lcddev.height=480;
}
}
//初始化lcd
void LCD_Init(void)
{
LCD_RST_SET;
HAL_Delay(20);
LCD_RST_CLR;
HAL_Delay(20);
LCD_RST_SET;
HAL_Delay(50); // delay 50 ms
Set_Dir(DFT_SCAN_DIR);
LCD_WR_REG(0xE0);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x0f);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x1B);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x3c);
LCD_WR_DATA(0x78);
LCD_WR_DATA(0x4A);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x0E);
LCD_WR_DATA(0x09);
LCD_WR_DATA(0x1B);
LCD_WR_DATA(0x1e);
LCD_WR_DATA(0x0f);
LCD_WR_REG(0xE1);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x22);
LCD_WR_DATA(0x24);
LCD_WR_DATA(0x06);
LCD_WR_DATA(0x12);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x36);
LCD_WR_DATA(0x47);
LCD_WR_DATA(0x47);
LCD_WR_DATA(0x06);
LCD_WR_DATA(0x0a);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x30);
LCD_WR_DATA(0x37);
LCD_WR_DATA(0x0f);
LCD_WR_REG(0xC0);
LCD_WR_DATA(0x10);
LCD_WR_DATA(0x10);
LCD_WR_REG(0xC1);
LCD_WR_DATA(0x41);
LCD_WR_REG(0xC5);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x22);
LCD_WR_DATA(0x80);
LCD_WR_REG(0x36); // Memory Access Control
if(DFT_SCAN_DIR==L2R_U2D)LCD_WR_DATA(0x48);
else if(DFT_SCAN_DIR==R2L_D2U)LCD_WR_DATA(0x88);
else if(DFT_SCAN_DIR==U2D_R2L)LCD_WR_DATA(0x28);
else LCD_WR_DATA(0xE8);
LCD_WR_REG(0x3A); //Interface Mode Control
LCD_WR_DATA(0x55);
LCD_WR_REG(0XB0); //Interface Mode Control
LCD_WR_DATA(0x00);
LCD_WR_REG(0xB1); //Frame rate 70HZ
LCD_WR_DATA(0xB0);
LCD_WR_DATA(0x11);
LCD_WR_REG(0xB4);
LCD_WR_DATA(0x02);
LCD_WR_REG(0xB6); //RGB/MCU Interface Control
LCD_WR_DATA(0x02);
LCD_WR_DATA(0x02);
LCD_WR_REG(0xB7);
LCD_WR_DATA(0xC6);
LCD_WR_REG(0xE9);
LCD_WR_DATA(0x00);
LCD_WR_REG(0XF7);
LCD_WR_DATA(0xA9);
LCD_WR_DATA(0x51);
LCD_WR_DATA(0x2C);
LCD_WR_DATA(0x82);
LCD_WR_REG(0x11);
HAL_Delay(120);
LCD_WR_REG(0x29);
LCD_LED=1000;
/*
LCD_WR_REG(0xE0);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x13);
LCD_WR_DATA(0x1D);
LCD_WR_DATA(0x09);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x43);
LCD_WR_DATA(0x66);
LCD_WR_DATA(0x4F);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x0E);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0x1A);
LCD_WR_DATA(0x03);
LCD_WR_REG(0xE1);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x1A);
LCD_WR_DATA(0x1D);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x0F);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x31);
LCD_WR_DATA(0x14);
LCD_WR_DATA(0x43);
LCD_WR_DATA(0x03);
LCD_WR_DATA(0x0D);
LCD_WR_DATA(0x0C);
LCD_WR_DATA(0x26);
LCD_WR_DATA(0x29);
LCD_WR_DATA(0x00);
LCD_WR_REG(0x36); //Memory Access
LCD_WR_DATA(0x08);
LCD_WR_REG(0x3A); //Interface Pixel Format
LCD_WR_DATA(0x66); //66:18Bit,55:18Bit
LCD_WR_REG(0xC0); //Power Control 1
LCD_WR_DATA(0x14); //Vreg1out
LCD_WR_DATA(0x0E); //Vreg2out
LCD_WR_REG(0xC1); //Power Control 2
LCD_WR_DATA(0x43); //VGH,VGL
LCD_WR_REG(0xC5); //Power Control 3
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x36); //Vcom
LCD_WR_DATA(0x80);
LCD_WR_REG(0xB0); //Interface Mode Control
LCD_WR_DATA(0x80); //SDA_EN
LCD_WR_REG(0xB1); //Frame rate
LCD_WR_DATA(0xA0); //60Hz
LCD_WR_DATA(0x11);
LCD_WR_REG(0xB4); //Display Inversion Control
LCD_WR_DATA(0x02); //2-dot
LCD_WR_REG(0xB6); //RGB/MCU Interface Control
LCD_WR_DATA(0x22); //RGB 22, MCU 02
LCD_WR_DATA(0x22); //Source,Gate scan dieection
LCD_WR_DATA(0x3B);
LCD_WR_REG(0xE9); //Set Image Function
LCD_WR_DATA(0x00); //Disable 24 bit data input
LCD_WR_REG(0xF7);
LCD_WR_DATA(0xA9);
LCD_WR_DATA(0x51);
LCD_WR_DATA(0x2C);
LCD_WR_DATA(0x82);
LCD_WR_REG(0x11);
HAL_Delay(120);
LCD_WR_REG(0x29); //SET Panel
LCD_DisplayOn();
*/
}