仅供大家学习交流。
/*******************************************
2.4寸 QVGA显示驱动
**********************************************/
#include "fsmc_sram.h"
#include "tftlcd.h"
#include "font.h"
#define Bank1_LCD_D ((uint32_t)0x60020000) //disp Data ADDR
#define Bank1_LCD_C ((uint32_t)0x60000000) //disp Reg ADDR
unsigned long color1=0;
//void MUC_Init();
void LCD_Init(void);
void LCD_WR_REG(unsigned int index);
void LCD_WR_CMD(unsigned int index,unsigned int val);
void LCD_WR_Data(unsigned int val);
void LCD_WR_Data_8(unsigned int val);
void LCD_test(void);
void LCD_clear(unsigned int p);
void ini(void);
void lcd_wr_zf(unsigned int a, unsigned int b, unsigned int a1,unsigned int b1, unsigned int d,unsigned int e, unsigned char g, unsigned char *f);
void lcd_wr_pixel(unsigned int a, unsigned int b, unsigned int e) ;
unsigned char *num_pub(unsigned int a);
unsigned int color[]={0xf800,0x07e0,0x001f,0xffe0,0x0000,0xffff,0x07ff,0xf81f};
extern unsigned char zm9[];
extern unsigned char zm8[];
extern unsigned char zm7[];
extern unsigned char zm6[];
extern unsigned char zm5[];
extern unsigned char zm4[];
extern unsigned char zm3[];
extern unsigned char zm2[];
extern unsigned char zm1[];
extern unsigned char zm0[];
extern unsigned char a1[];
extern unsigned char a2[];
extern unsigned char zf2[];
extern unsigned char zf3[];
u16 POINT_COLOR=RED; //默认红色
unsigned int LCD_RD_data(void);
extern void lcd_rst(void);
extern void Delay(__IO uint32_t nCount);
//写寄存器地址函数
void LCD_WR_REG(unsigned int index)
{
*(__IO uint16_t *) (Bank1_LCD_C)= index;
}
//写寄存器数据函数
//输入:dbw 数据位数,1为16位,0为8位。
void LCD_WR_CMD(unsigned int index,unsigned int val)
{
*(__IO uint16_t *) (Bank1_LCD_C)= index;
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
unsigned int LCD_RD_data(void){
unsigned int a=0;
//a=(*(__IO uint16_t *) (Bank1_LCD_D)); //Dummy
//a= *(__IO uint16_t *) (Bank1_LCD_D); //H
//a=a<<8;
a=*(__IO uint16_t *) (Bank1_LCD_D); //L
return(a);
}
//写16位数据函数
void LCD_WR_Data(unsigned int val)
{
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
void LCD_WR_Data_8(unsigned int val)
{
*(__IO uint16_t *) (Bank1_LCD_D)= val;
}
//初始化函数
void LCD_Init(void)
{
lcd_rst();
LCD_WR_CMD(0x00E3, 0x3008); // Set internal timing
LCD_WR_CMD(0x00E7, 0x0012); // Set internal timing
LCD_WR_CMD(0x00EF, 0x1231); // Set internal timing
LCD_WR_CMD(0x0000, 0x0001); // Start Oscillation
LCD_WR_CMD(0x0001, 0x0100); // set SS and SM bit
LCD_WR_CMD(0x0002, 0x0700); // set 1 line inversion
LCD_WR_CMD(0x0003, 0x1030); // set GRAM write direction and BGR=0,262K colors,1 transfers/pixel.
LCD_WR_CMD(0x0004, 0x0000); // Resize register
LCD_WR_CMD(0x0008, 0x0202); // set the back porch and front porch
LCD_WR_CMD(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0]
LCD_WR_CMD(0x000A, 0x0000); // FMARK function
LCD_WR_CMD(0x000C, 0x0000); // RGB interface setting
LCD_WR_CMD(0x000D, 0x0000); // Frame marker Position
LCD_WR_CMD(0x000F, 0x0000); // RGB interface polarity
//Power On sequence
LCD_WR_CMD(0x0010, 0x0000); // SAP, BT[3:0], AP, DSTB, SLP, STB
LCD_WR_CMD(0x0011, 0x0007); // DC1[2:0], DC0[2:0], VC[2:0]
LCD_WR_CMD(0x0012, 0x0000); // VREG1OUT voltage
LCD_WR_CMD(0x0013, 0x0000); // VDV[4:0] for VCOM amplitude
Delay(200); // Dis-charge capacitor power voltage
LCD_WR_CMD(0x0010, 0x1690); // SAP, BT[3:0], AP, DSTB, SLP, STB
LCD_WR_CMD(0x0011, 0x0227); // R11h=0x0221 at VCI=3.3V, DC1[2:0], DC0[2:0], VC[2:0]
Delay(50); // Delay 50ms
LCD_WR_CMD(0x0012, 0x001C); // External reference voltage= Vci;
Delay(50); // Delay 50ms
LCD_WR_CMD(0x0013, 0x1800); // R13=1200 when R12=009D;VDV[4:0] for VCOM amplitude
LCD_WR_CMD(0x0029, 0x001C); // R29=000C when R12=009D;VCM[5:0] for VCOMH
LCD_WR_CMD(0x002B, 0x000D); // Frame Rate = 91Hz
Delay(50); // Delay 50ms
LCD_WR_CMD(0x0020, 0x0000); // GRAM horizontal Address
LCD_WR_CMD(0x0021, 0x0000); // GRAM Vertical Address
// ----------- Adjust the Gamma Curve ----------//
LCD_WR_CMD(0x0030, 0x0007);
LCD_WR_CMD(0x0031, 0x0302);
LCD_WR_CMD(0x0032, 0x0105);
LCD_WR_CMD(0x0035, 0x0206);
LCD_WR_CMD(0x0036, 0x0808);
LCD_WR_CMD(0x0037, 0x0206);
LCD_WR_CMD(0x0038, 0x0504);
LCD_WR_CMD(0x0039, 0x0007);
LCD_WR_CMD(0x003C, 0x0105);
LCD_WR_CMD(0x003D, 0x0808);
//------------------ Set GRAM area ---------------//
LCD_WR_CMD(0x0050, 0x0000); // Horizontal GRAM Start Address
LCD_WR_CMD(0x0051, 0x00EF); // Horizontal GRAM End Address
LCD_WR_CMD(0x0052, 0x0000); // Vertical GRAM Start Address
LCD_WR_CMD(0x0053, 0x013F); // Vertical GRAM Start Address
LCD_WR_CMD(0x0060, 0xA700); // Gate Scan Line
LCD_WR_CMD(0x0061, 0x0001); // NDL,VLE, REV
LCD_WR_CMD(0x006A, 0x0000); // set scrolling line
//-------------- Partial Display Control ---------//
LCD_WR_CMD(0x0080, 0x0000);
LCD_WR_CMD(0x0081, 0x0000);
LCD_WR_CMD(0x0082, 0x0000);
LCD_WR_CMD(0x0083, 0x0000);
LCD_WR_CMD(0x0084, 0x0000);
LCD_WR_CMD(0x0085, 0x0000);
//-------------- Panel Control -------------------//
LCD_WR_CMD(0x0090, 0x0010);
LCD_WR_CMD(0x0092, 0x0000);
LCD_WR_CMD(0x0093, 0x0003);
LCD_WR_CMD(0x0095, 0x0110);
LCD_WR_CMD(0x0097, 0x0000);
LCD_WR_CMD(0x0098, 0x0000);
LCD_WR_CMD(0x0007, 0x0133); // 262K color and display ON
//ini();
LCD_WR_CMD(32, 0);
LCD_WR_CMD(33, 0x013F);
*(__IO uint16_t *) (Bank1_LCD_C)= 34;
for(color1=0;color1<76800;color1++)
{
LCD_WR_Data(0xffff);
}
color1=0;
//while(1);
}
//+++++++++++++++++++++++LCD写字符子程序
void lcd_wr_pixel(unsigned int a, unsigned int b, unsigned int e)
// X, Y,颜色
{
// LCD_WR_CMD(0x02,a);
// LCD_WR_CMD(0x03,b);
// LCD_WR_CMD(0x04,239);
// LCD_WR_CMD(0x05,319);
// LCD_WR_REG(0x0E);
LCD_WR_CMD(0x20, a);
LCD_WR_CMD(0x21, b);
LCD_WR_Data(e);
}
void TFT_CLEAR(u8 x,u16 y,u8 len,u16 wid)
{
u32 n,temp;
LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address
LCD_WR_CMD(0x0051, x+len-1); // Horizontal GRAM End Address
LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address
LCD_WR_CMD(0x0053, y+wid-1); // Vertical GRAM Start Address
LCD_WR_REG(34);
//LCD_WR_CMD(0,0x2,x);//设置到原点
//LCD_WR_CMD(1,0x3,y);
//LCD_WR_CMD(0,0x04,x+len-1);//结束列数(0~239)
//LCD_WR_CMD(1,0x05,y+wid-1);//结束行数(0~319)
//LCD_WR_REG(0x0E);
temp=(u32)len*wid;
for(n=0;n<temp;n++)LCD_WR_Data(0xffff);//显示白色
}
//画点
//x:0~239
//y:0~319
//POINT_COLOR:此点的颜色
void TFT_DrawPoint(u8 x,u16 y)
{
LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address
LCD_WR_CMD(0x0051, 0x00EF); // Horizontal GRAM End Address
LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address
LCD_WR_CMD(0x0053, 0x013F); // Vertical GRAM Start Address
LCD_WR_CMD(32, x); // Horizontal GRAM Start Address
LCD_WR_CMD(33, y); // Vertical GRAM Start Address
LCD_WR_REG(34);
//LCD_WR_CMD(0,0x2,x);//设置到原点
//LCD_WR_CMD(1,0x3,y);
//LCD_WR_CMD(0,0x04,0xEF); //结束列数(0~239)
//LCD_WR_CMD(1,0x05,0x013F);//结束行数(0~319)
//(0x0E);
LCD_WR_Data(POINT_COLOR);
//POINT_COLOR++;
}
//取绝对值函数
//位宽:32bit
u32 abs(s32 res)
{
if(res<0)return -res;
else return res;
}
//画线
//x1,y1:起点坐标
//x2,y2:终点坐标
void TFT_DrawLine(u8 x1, u16 y1, u8 x2, u16 y2)
{
u16 x, y, t;
if((x1==x2)&&(y1==y2))TFT_DrawPoint(x1, y1);
else if(abs(y2-y1)>abs(x2-x1))//斜率大于1
{
if(y1>y2)
{
t=y1;
y1=y2;
y2=t;
t=x1;
x1=x2;
x2=t;
}
for(y=y1;y<y2;y++)//以y轴为基准
{
x=(u32)(y-y1)*(x2-x1)/(y2-y1)+x1;
TFT_DrawPoint(x, y);
}
}
else //斜率小于等于1
{
if(x1>x2)
{
t=y1;
y1=y2;
y2=t;
t=x1;
x1=x2;
x2=t;
}
for(x=x1;x<x2;x++)//以x轴为基准
{
y =(u32)(x-x1)*(y2-y1)/(x2-x1)+y1;
TFT_DrawPoint(x,y);
}
}
}
//6*12大小
//在指定位置显示一个字符
//x:0~234
//y:0~308
//num:要显示的字符:" "--->"~"
void TFT_ShowChar(u8 x,u16 y,u8 num)
{
#define MAX_CHAR_POSX 232
#define MAX_CHAR_POSY 304
u8 temp;
u8 pos,t;
if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return;
//设定一个字符所占的大小
//开辟空间
//
LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address
LCD_WR_CMD(0x0051, x+5); // Horizontal GRAM End Address
LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address
LCD_WR_CMD(0x0053, y+11); // Vertical GRAM Start Address
LCD_WR_CMD(32, x);
LCD_WR_CMD(33, y);
LCD_WR_REG(34);
//LCD_WR_CMD(0,0x2,x);//
//LCD_WR_CMD(1,0x3,y);
//LCD_WR_CMD(0,0x04,x+5); //结束列数(0~239)
//LCD_WR_CMD(1,0x05,y+11);//结束行数(0~319)
//LCD_WR_REG(0x0E);
num=num-' ';//得到偏移后的值
for(pos=0;pos<12;pos++)
{
temp=asc2_1206[num][pos];
for(t=0;t<6;t++)
{
if(temp&0x01)LCD_WR_Data(POINT_COLOR);
else LCD_WR_Data(0xffff);//白色
temp>>=1;
}
}
}
//m^n函数
u32 mypow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示一个数字
//x,y:起点坐标
//num:数值(0~65536);
void TFT_ShowNum(u8 x,u16 y,u32 num)
{
u32 res;
u8 t=0,t1=0;
res=num;
if(!num)TFT_ShowChar(x,y,'0');//显示0
while(res) //得到数字长度
{
res/=10;
t++;
}
t1=t;
while(t) //显示数字
{
res=mypow(10,t-1);
TFT_ShowChar(x+(t1-t)*6,y,(num/res)%10+'0');
t--;
}
}
//显示字符串
//x,y:起点坐标
//*p:字符串起始地址
void TFT_ShowString(u8 x,u16 y,const u8 *p)
{
while(*p!='\0')
{
if(x>MAX_CHAR_POSX){x=0;y+=12;}
if(y>MAX_CHAR_POSY){y=x=0;TFT_CLEAR(0,0,240,320);}
TFT_ShowChar(x,y,*p);
x+=6;
p++;
}
}
//显示一副图片
//x,y:图片起始位置
//lenth:图片的宽度(0~240)
//wide: 图片高度(0~320)
//*p:图片首地址
//不带范围判断
void TFT_ShowBmp(u8 x,u16 y,u8 lenth,u16 wide,const u8 *p)
{
u32 size,temp;
//开辟窗口
LCD_WR_CMD(0x0050, x); // Horizontal GRAM Start Address
LCD_WR_CMD(0x0051, (u16)x+lenth-1); // Horizontal GRAM End Address
LCD_WR_CMD(0x0052, y); // Vertical GRAM Start Address
LCD_WR_CMD(0x0053, y+wide-1); // Vertical GRAM Start Address
LCD_WR_REG(34);
//LCD_WR_CMD(0,0x2,x);//起始坐标
//LCD_WR_CMD(1,0x3,y);
//LCD_WR_CMD(0,0x04,(u16)x+lenth-1);//结束列数(0~239)
//LCD_WR_CMD(1,0x05,y+wide-1); //结束行数(0~319)
//LCD_WR_REG(0x0E);
temp=(u32)lenth*wide*2;
for(size=0;size<temp;size++)LCD_WR_Data_8(p[size]);
}