#include"usart.h"
#include"delay.h"
#include"ILI93XX.h"
#include"font.h"
//画笔颜色,背景颜色
u16 POINT_COLOR = 0x0000,BACK_COLOR = 0xFFFF;
u16 DeviceCode;
#if LCD_FAST_IO==1 //快速IO
/*************************
//写寄存器函数
**************************/
void LCD_WR_REG(u8 data)
{
LCD_RS_CLR;//写地址
LCD_CS_CLR;
DATAOUT(data);
LCD_WR_CLR;
LCD_WR_SET;
LCD_CS_SET;
}
#endif
/*************************
//写寄存器
**************************/
void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue)
{
LCD_WR_REG(LCD_Reg);
LCD_WR_DATA(LCD_RegValue);
}
/*************************
//读寄存器 //IO口先设置为输入,读,再重新设置为输出
**************************/
u16 LCD_ReadReg(u8 LCD_Reg)
{
u16 t;
LCD_WR_REG(LCD_Reg); //写入要读的寄存器号
GPIOB->CRL=0X88888888; //PB0-7 上拉输入
GPIOB->CRH=0X88888888; //PB8-15 上拉输入
GPIOB->ODR=0XFFFF; //全部输出高
#if LCD_FAST_IO==1 //快速IO
LCD_RS_SET;
LCD_CS_CLR;
//读取数据(读寄存器时,并不需要读2次)
LCD_RD_CLR;
delay_us(5);//FOR 8989,延时5us
LCD_RD_SET;
t=DATAIN;
LCD_CS_SET;
#endif
GPIOB->CRL=0X33333333; //PB0-7 上拉输出
GPIOB->CRH=0X33333333; //PB8-15 上拉输出
GPIOB->ODR=0XFFFF; //全部输出高
return t;
}
/*************************
//开始写GRAM
**************************/
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_REG(R34); //单个操作命令,只需写入该值即可
}
/*************************
//LCD写GRAM
**************************/
void LCD_WriteRAM(u16 RGB_Code)
{
LCD_WR_DATA(RGB_Code);//写十六位GRAM
}
/*************************
//从ILI93xx读出的数据为GBR格式,而我们写入的时候为RGB格式。
//通过该函数转换
//c:GBR格式的颜色值
//返回值:RGB格式的颜色值
**************************/
u16 LCD_BGR2RGB(u16 c)
{
u16 r,g,b,rgb;
b=(c>>0)&0x1f;
g=(c>>5)&0x3f;
r=(c>>11)&0x1f;
rgb=(b<<11)+(g<<5)+(r<<0);
return(rgb);
}
/*************************
//读取个某点的颜色值
//x:0~239
//y:0~319
//返回值:此点的颜色
**************************/
u16 LCD_ReadPoint(u16 x,u16 y)
{
u16 t;
if(x>=LCD_W||y>=LCD_H)return 0;//超过了范围,直接返回
LCD_SetCursor(x,y);
LCD_WR_REG(R34);
GPIOB->CRL=0X88888888; //PBIO 全部上拉输入
GPIOB->CRH=0X88888888;
GPIOB->ODR=0XFFFF; //全部输出高
#if LCD_FAST_IO==1
LCD_RS_SET;
LCD_CS_CLR;
//读取数据(读GRAM时,需要读2次)
LCD_RD_CLR;
LCD_RD_SET;
delay_us(2);//FOR 9320,延时2us
//dummy READ
LCD_RD_CLR;
delay_us(2);//FOR 8989,延时2us
LCD_RD_SET;
t=DATAIN;
LCD_CS_SET;
#endif
GPIOB->CRL=0X33333333; //PBIO 全部上拉输出
GPIOB->CRH=0X33333333;
GPIOB->ODR=0XFFFF; // PBIO 全部输出高
return LCD_BGR2RGB(t);
}
/*************************
//LCD开启显示
*************************/
void LCD_DisplayOn(void)
{
LCD_WriteReg(R7,0x0173);///26万色显示开启
}
/*************************
//LCD关闭显示
*************************/
void LCD_DisplayOff(void)
{
LCD_WriteReg(R7,0x0);//关闭显示
}
/*************************
//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
*************************/
void LCD_SetCursor(u16 Xpos,u16 Ypos)
{
#if USE_HORIZONTAL==1 //定义是否使用横屏 0,不使用.1,使用.
if(DeviceCode==0x8989)
{
LCD_WriteReg(0x4e,Ypos);
LCD_WriteReg(0x4e,319-Xpos);
}
else
{
LCD_WriteReg(R32,Ypos);
LCD_WriteReg(R33,319-Xpos);
}
#else
if(DeviceCode==0x8989)
{
LCD_WriteReg(0x4e,Xpos);
LCD_WriteReg(0x4f,Ypos);
}
else
{
LCD_WriteReg(R32,Xpos);
LCD_WriteReg(R33,Ypos);
}
#endif
}
/*************************
//画点
//x:0~239
//y:0~319
//POINT_COLOR:此点的颜色
*************************/
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y);//设置光标位置
LCD_WR_REG(R34);//开始写入GRAM
LCD_WR_DATA(POINT_COLOR);
}
/*************************
//初始化lcd
//该初始化函数可以初始化各种ILI93XX液晶,但是其他函数是基于ILI9320的!!!
//在其他型号的驱动芯片上没有测试!
*************************/
void LCD_Init(void)
{
RCC->APB2ENR|=1<<3;//先使能外设PORTB时钟
RCC->APB2ENR|=1<<4;//先使能外设PORTC时钟
RCC->APB2ENR|=1<<0; //开启辅助时钟
JTAG_Set(SWD_ENABLE); //开启SWD
//PORTC6~10复用推挽输出
GPIOC->CRH&=0XFFFFF000;
GPIOC->CRH|=0X00000333;
GPIOC->CRL&=0X00FFFFFF;
GPIOC->CRL|=0X33000000;
GPIOC->ODR|=0X07C0;
//PORTB 推挽输出
GPIOB->CRH=0X33333333;
GPIOB->CRL=0X33333333;
GPIOB->ODR=0XFFFF;
delay_ms(50); // delay 50 ms
LCD_WriteReg(0x0000,0x0001);
delay_ms(50); // delay 50 ms
DeviceCode = LCD_ReadReg(0x0000);
if(DeviceCode==0x9325)
{
LCD_WriteReg(0x00E5,0x78F0);
LCD_WriteReg(0x0001,0x0100);
LCD_WriteReg(0x0002,0x0700);
LCD_WriteReg(0x0003,0x1030);
LCD_WriteReg(0x0004,0x0000);
LCD_WriteReg(0x0008,0x0202);
LCD_WriteReg(0x0009,0x0000);
LCD_WriteReg(0x000A,0x0000);
LCD_WriteReg(0x000C,0x0000);
LCD_WriteReg(0x000D,0x0000);
LCD_WriteReg(0x000F,0x0000);
//power on sequence VGHVGL
LCD_WriteReg(0x0010,0x0000);
LCD_WriteReg(0x0011,0x0007);
LCD_WriteReg(0x0012,0x0000);
LCD_WriteReg(0x0013,0x0000);
LCD_WriteReg(0x0007,0x0000);
//vgh
LCD_WriteReg(0x0010,0x1690);
LCD_WriteReg(0x0011,0x0227);
//delayms(100);
//vregiout
LCD_WriteReg(0x0012,0x009D); //0x001b
//delayms(100);
//vom amplitude
LCD_WriteReg(0x0013,0x1900);
//delayms(100);
//vom H
LCD_WriteReg(0x0029,0x0025);
LCD_WriteReg(0x002B,0x000D);
//gamma
LCD_WriteReg(0x0030,0x0007);
LCD_WriteReg(0x0031,0x0303);
LCD_WriteReg(0x0032,0x0003);// 0006
LCD_WriteReg(0x0035,0x0206);
LCD_WriteReg(0x0036,0x0008);
LCD_WriteReg(0x0037,0x0406);
LCD_WriteReg(0x0038,0x0304);//0200
LCD_WriteReg(0x0039,0x0007);
LCD_WriteReg(0x003C,0x0602);// 0504
LCD_WriteReg(0x003D,0x0008);
//ram
LCD_WriteReg(0x0050,0x0000);
LCD_WriteReg(0x0051,0x00EF);
LCD_WriteReg(0x0052,0x0000);
LCD_WriteReg(0x0053,0x013F);
LCD_WriteReg(0x0060,0xA700);
LCD_WriteReg(0x0061,0x0001);
LCD_WriteReg(0x006A,0x0000);
//
LCD_WriteReg(0x0080,0x0000);
LCD_WriteReg(0x0081,0x0000);
LCD_WriteReg(0x0082,0x0000);
LCD_WriteReg(0x0083,0x0000);
LCD_WriteReg(0x0084,0x0000);
LCD_WriteReg(0x0085,0x0000);
//
LCD_WriteReg(0x0090,0x0010);
LCD_WriteReg(0x0092,0x0600);
LCD_WriteReg(0x0007,0x0133);
LCD_WriteReg(0x00,0x0022);//
}
LCD_LED=1;//点亮背光
LCD_Clear(WHITE);
}
/*************************
//清屏函数
//Color:要清屏的填充色
*************************/
void LCD_Clear(u16 Color)
{
u32 index=0;
LCD_SetCursor(0x00,0x0000);//设置光标位置
LCD_WriteRAM_Prepare();//开始写GRANM
for(index=0;index<76800;index++)
{
LCD_WR_DATA(Color);
}
}
/*************************
//在指定区域内填充指定颜色
//区域大小:
// (xend-xsta)*(yend-ysta)
*************************/
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
{
u16 i,j;
u16 xlen=0;
#if USE_HORIZONTAL==1 //定义是否使用横屏 0,不使用.1,使用.
xlen=yend-ysta+1;
for(i=xsta;i<=xend;i++)
{
LCD_SetCursor(i,ysta); //设置光标位置
LCD_WriteRAM_Prepare();//开始写入GRAM
for(j=0;j<xlen;j++)
{
LCD_WR_DATA(color);//设置光标
}
}
#else
xlen=xend-xsta+1;
for(i=ysta;i<=yend;i++)
{
LCD_SetCursor(xsta,i); //设置光标位置
LCD_WriteRAM_Prepare();//开始写入GRAM
for(j=0;j<xlen;j++)
{
LCD_WR_DATA(color);//设置光标
}
}
#endif
}
/*************************
//画线
//x1,y1:起点坐标
//x2,y2:终点坐标
*************************/
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2)
{
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