?? tftlcd.c
字號:
#include "COMM.H"
#include "font.h"
//液晶顯示 淘寶超值27元的液晶
//加入了GRAM 讀寫的函數,可以讀取指定GRAM的內容了
//正點原子@SCUT
//2008/12/15
//V1.2
//修改了數字顯示函數TFT_ShowNum,可以支持自動識別數字范圍.
//擴充顯示范圍到u32類型
//-----------------TFT端口定義----------------
#define TFT_RS (1<<0) //數據/命令選擇端口 PB0
#define TFT_WR (1<<1) //數據端口 PB1
#define TFT_CS (1<<2) //片選端口 PB2
#define TFT_LED (1<<2) //TFT背光 PA2
#define TFT_RST (1<<3) //硬復位 PA3
#define TFT_RD (1<<4) //時鐘端口 PA4
#define TFT_RS_SET(x) GPIOB->ODR=(GPIOB->ODR&~TFT_RS)|(x ? TFT_RS:0)
#define TFT_WR_SET(x) GPIOB->ODR=(GPIOB->ODR&~TFT_WR)|(x ? TFT_WR:0)
#define TFT_CS_SET(x) GPIOB->ODR=(GPIOB->ODR&~TFT_CS)|(x ? TFT_CS:0)
#define TFT_LED_SET(x) GPIOA->ODR=(GPIOA->ODR&~TFT_LED) |(x ? TFT_LED:0)
#define TFT_RST_SET(x) GPIOA->ODR=(GPIOA->ODR&~TFT_RST)|(x ? TFT_RST:0)
#define TFT_RD_SET(x) GPIOA->ODR=(GPIOA->ODR&~TFT_RD) |(x ? TFT_RD:0)
//PC0~7,作為數據線
#define DATAOUT(x) GPIOC->ODR=(GPIOC->ODR&0xffffff00)|(x&0xff);//數據輸出
#define DATAIN GPIOC->IDR&0xff;//數據輸入
//畫筆顏色
u16 POINT_COLOR=RED;//默認紅色
u16 BACK_COLOR=WHITE;//背景顏色.默認為白色
/*------------------------液晶說明------------------------------
液晶型號位置
大小:320*240
像素:65K色
VCC 3.3V
VCCIO 2.7~3.3V
數據線操作電壓:3.3V
顏色排列:以一個十六位的數存放一個點的顏色 RGB:565 即:最高五位為紅色
灰階.中間六位為綠色灰階.最低五位為藍色灰階.
例如:0XF800 純紅色
0X07E0 純綠色
0X001F 純藍色
----------------------------------------------------------------*/
//寫8位數據函數
//用宏定義,提高速度.
#define TFT_WR_DATA(data){\
TFT_RS_SET(1);\
TFT_CS_SET(0);\
DATAOUT(data);\
TFT_WR_SET(0);\
TFT_WR_SET(1);\
TFT_CS_SET(1);\
TFT_RS_SET(0);\
}
//寫寄存器函數
void TFT_WR_REG(u8 data)
{
TFT_RS_SET(0);//寫地址
TFT_CS_SET(0);
DATAOUT(data);
TFT_WR_SET(0);
TFT_WR_SET(1);
TFT_CS_SET(1);
TFT_RS_SET(1);
}
//寫寄存器數據函數
//dbw:數據位數,1為16位,0為8位。
//index:寄存器編號
//val:值
//輸入:dbw 數據位數,1為16位,0為8位。
void TFT_WR_CMD(u8 dbw,u8 index,u16 val)
{
TFT_WR_REG(index);
if(dbw)TFT_WR_DATA(val>>8);
TFT_WR_DATA(val&0xff);
}
//寫16位數據函數
void TFT_WR_Data16(u16 val)
{
TFT_WR_DATA(val>>8);
TFT_WR_DATA(val&0xff);
}
//畫點
//x:0~239
//y:0~319
//POINT_COLOR:此點的顏色
void TFT_DrawPoint(u8 x,u16 y)
{
TFT_WR_CMD(0,0x2,x);//設置到原點
TFT_WR_CMD(1,0x3,y);
//TFT_WR_CMD(0,0x04,0xEF); //結束列數(0~239)
//TFT_WR_CMD(1,0x05,0x013F);//結束行數(0~319)
TFT_WR_REG(0x0E);
TFT_WR_Data16(POINT_COLOR);
}
u16 Screen_Data[756];
//讀取指定點的GRAM
unsigned int TFT_RD_GRAM(u8 x,u16 y)
{
u16 t;
TFT_WR_CMD(0,0x2,x);//設置到原點
TFT_WR_CMD(1,0x3,y);
TFT_WR_REG(0x0F);
GPIOC->CRL=0X88888888; //PC0-7 上拉輸入
GPIOC->ODR|=0X00FF; //全部輸出高
TFT_RS_SET(1);
TFT_CS_SET(0);
TFT_RD_SET(0);
TFT_RD_SET(1);
//丟棄第一個不確定的數
TFT_RD_SET(0);
TFT_RD_SET(1);
t=DATAIN;
t<<=8;
TFT_RD_SET(0);
TFT_RD_SET(1);
t+=DATAIN;
TFT_CS_SET(1);
TFT_RS_SET(0);
GPIOC->CRL=0X33333333; //PC0-7 輸出
GPIOC->ODR|=0X00FF; //全部輸出高
return t;
}
//從指定地址開始讀取 42*18大小的方塊
void READ_GRAM(u8 x,u16 y)
{
u8 t,i;
u16 temp;
for(t=0;t<18;t++)
{
for(i=0;i<42;i++)
{
temp=(u16)t*42+i;
Screen_Data[temp]=TFT_RD_GRAM(x+i,y+t);
}
}
}
//恢復指定地址的數據
void RECOVER_GRAM(u8 x,u16 y)
{
u8 t,i;
u16 temp;
for(t=0;t<18;t++)
{
for(i=0;i<42;i++)
{
temp=(u16)t*42+i;
POINT_COLOR=Screen_Data[temp];
TFT_DrawPoint(x+i,y+t);
}
}
}
//清屏函數
//全屏顯示單色
void TFT_CLEAR(u16 color)
{
u32 n;
TFT_WR_CMD(0,0x2,0);//設置到原點
TFT_WR_CMD(1,0x3,0);
TFT_WR_CMD(0,0x04,239); //結束列數(0~239)
TFT_WR_CMD(1,0x05,319);//結束行數(0~319)
TFT_WR_REG(0x0E);
for(n=0;n<76800;n++)TFT_WR_Data16(color);//顯示白色
SD_Init();//初始化SD卡,在意外拔出之后可以正常使用
}
//在指定區域內填充指定顏色
//區域大小:
// (xend-xsta)*(yend-ysta)
void TFT_Fill(u8 xsta,u16 ysta,u8 xend,u16 yend,u16 color)
{
u32 n;
TFT_WR_CMD(0,0x2,xsta);//設置到原點
TFT_WR_CMD(1,0x3,ysta);
TFT_WR_CMD(0,0x04,xend);//結束列數(0~239)
TFT_WR_CMD(1,0x05,yend);//結束行數(0~319)
TFT_WR_REG(0x0E);
n=(u32)(yend-ysta+1)*(xend-xsta+1);
while(n--)TFT_WR_Data16(color);//顯示所填充的顏色.
//恢復初始狀態
TFT_WR_CMD(0,0x2,0);//設置到原點
TFT_WR_CMD(1,0x3,0);
TFT_WR_CMD(0,0x04,239);//結束列數(0~239)
TFT_WR_CMD(1,0x05,319);//結束行數(0~319)
}
//畫線
//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);
}
}
}
//畫矩形
void TFT_DrawRectangle(u8 x1, u16 y1, u8 x2, u16 y2)
{
TFT_DrawLine(x1,y1,x2,y1);
TFT_DrawLine(x1,y1,x1,y2);
TFT_DrawLine(x1,y2,x2,y2);
TFT_DrawLine(x2,y1,x2,y2);
}
//在指定位置畫一個指定大小的圓
//(x,y):中心點
//r :半徑
void draw_circle(u8 x0,u16 y0,u8 r)
{
int a,b;
int di;
a=0;
b=r;
di=3-2*r; //判斷下個點位置的標志
while(a<=b)
{
TFT_DrawPoint(x0-b,y0-a); //3
TFT_DrawPoint(x0+b,y0-a); //0
TFT_DrawPoint(x0-a,y0+b); //1
TFT_DrawPoint(x0-b,y0-a); //7
TFT_DrawPoint(x0-a,y0-b); //2
TFT_DrawPoint(x0+b,y0+a); //4
TFT_DrawPoint(x0+a,y0-b); //5
TFT_DrawPoint(x0+a,y0+b); //6
TFT_DrawPoint(x0-b,y0+a);
a++;
/***使用Bresenham算法畫圓**/
if(di<0)di +=4*a+6;
else
{
di+=10+4*(a-b);
b--;
}
TFT_DrawPoint(x0+a,y0+b);
}
}
//畫一個觸摸點
//用來校準用的
void drow_touch_point(u8 x,u16 y)
{
TFT_DrawLine(x-12,y,x+13,y);//橫線
TFT_DrawLine(x,y-12,x,y+13);//豎線
TFT_DrawPoint(x+1,y+1);
TFT_DrawPoint(x-1,y+1);
TFT_DrawPoint(x+1,y-1);
TFT_DrawPoint(x-1,y-1);
draw_circle(x,y,6);//畫中心圈
}
//在指定位置顯示一個字符
//x:0~234
//y:0~308
//num:要顯示的字符:" "--->"~"
//size:字體大小 12/16
//mode:疊加方式(1)還是非疊加方式(0)
void TFT_ShowChar(u8 x,u16 y,u8 num,u8 size,u8 mode)
{
#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;
//設定一個字符所占的大小
//開辟空間
TFT_WR_CMD(0,0x00,0x04);
TFT_WR_CMD(0,0x2,x);//
TFT_WR_CMD(1,0x3,y);
TFT_WR_CMD(0,0x04,x+(size/2-1)); //結束列數(0~239)
TFT_WR_CMD(1,0x05,y+size-1);//結束行數(0~319)
TFT_WR_REG(0x0E);
num=num-' ';//得到偏移后的值
if(!mode) //非疊加方式
{
for(pos=0;pos<size;pos++)
{
if(size==12)temp=asc2_1206[num][pos];//調用1206字體
else temp=asc2_1608[num][pos]; //調用1608字體
for(t=0;t<size/2;t++)
{
if(temp&0x01)TFT_WR_Data16(POINT_COLOR);
else TFT_WR_Data16(BACK_COLOR);
temp>>=1;
}
}
}else//疊加方式
{
for(pos=0;pos<size;pos++)
{
if(size==12)temp=asc2_1206[num][pos];//調用1206字體
else temp=asc2_1608[num][pos]; //調用1608字體
for(t=0;t<size/2;t++)
{
if(temp&0x01)TFT_DrawPoint(x+t,y+pos);//畫一個點
temp>>=1;
}
}
}
//恢復窗體大小
TFT_WR_CMD(0,0x04,239);//結束列數
TFT_WR_CMD(1,0x05,319);//結束行數
}
//在指定位置顯示一個大字符
//30*60大小的
//num:0~9
//:/./C這三個字符
void TFT_ShowBigChar(u8 x,u16 y,u8 num)
{
u8 n,t;
u8 temp;
u8 t1,deadline;
TFT_WR_CMD(0,0x2,x);//設置到原點
TFT_WR_CMD(1,0x3,y);
TFT_WR_CMD(0,0x04,x+29);//結束列數(0~239)
TFT_WR_CMD(1,0x05,y+59); //結束行數(0~319)
if(num==':')t1=150;
else if(num=='.')t1=165;
else if(num=='C')t1=180;
else t1=15*num;
deadline=t1+15;
TFT_WR_REG(0x0E);
for(;t1<deadline;t1++)
{
for(n=0;n<16;n++)
{
temp=BIG_ASCII[t1][n];
for(t=0;t<8;t++)
{
if(temp&0x80) TFT_WR_Data16(POINT_COLOR);
else TFT_WR_Data16(BACK_COLOR);
temp<<=1;
if(((n%4)==3)&&t==5)break;
}
}
}
//恢復面板
TFT_WR_CMD(0,0x04,239);//結束列數(0~239)
TFT_WR_CMD(1,0x05,319); //結束行數(0~319)
}
//顯示一個按鈕,大小24*24
//0,>;1,<;
void TFT_ShowButton(u8 x,u16 y,u8 num)
{
u8 n,t;
u8 temp;
u8 t1,deadline;
TFT_WR_CMD(0,0x0,0x04);//掃描方式控制
TFT_WR_CMD(0,0x2,x);//設置到原點
TFT_WR_CMD(1,0x3,y);
TFT_WR_CMD(0,0x04,x+23);//結束列數(0~239)
TFT_WR_CMD(1,0x05,y+23); //結束行數(0~319)
t1=8*num;
deadline=t1+8;
TFT_WR_REG(0x0E);
for(;t1<deadline;t1++)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -