⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftlcd.c

📁 基于stm32的MP3播放器
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -