文章目录
- 一.概要
- 二.TFT彩屏主要参数
- 三.TFT彩屏参考原理图
- 四.TFT彩屏模块接线说明
- 五.模块SPI通讯协议介绍
- 六.TFT彩屏模块显示
- 1.显示英文字符串
- 2.显示数字
- 3.显示中文
- 七.TFT彩屏实现图片显示
- 八.STM32单片机1.8寸 TFT LCD显示实验
- 1.硬件准备
- 2.软件工程
- 3.软件主要代码
- 4.实验效果
- 九.小结
一.概要
TFT-LCD,全称Thin Film Transistor Liquid Crystal Display,即薄膜晶体管液晶显示器,是多数液晶显示器的一种,使用薄膜晶体管技术改善影象品质。它在液晶显示屏的每一个像素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD 也被叫做真彩液晶显示器。
1.8寸TFT-LCD显示模块具有显示效果好、刷新速度要求低、接线方便、通用性强,性价比高等优点,可用于许多应用中:传感器监控和报警、温度监控器/风扇控制器等。
二.TFT彩屏主要参数
三.TFT彩屏参考原理图
模块原理图
四.TFT彩屏模块接线说明
接口为8针的单排插针,针间距为2.54mm。
TFT LCD彩屏模块与单片机要8根线就能连接
板子与1.8寸TFT彩屏用杜邦线连接:
板子GND-----彩屏GND
板子3V3-----彩屏VCC
板子PA1-----彩屏SCL
板子PA2-----彩屏SDA
板子PA6-----彩屏RES
板子PA3-----彩屏DC
板子PA4-----彩屏CS
板子PA5-----彩屏BL
五.模块SPI通讯协议介绍
SPI通讯时序
与常用的SPI协议不同的地方是:由于是只需要显示,故而将从机发送到主机的数据线(MISO)进
行了隐藏。
SCLK空闲时是低电平,当SCLK第一个下降沿时开始传输数据,使用GPAL=0, CPOL=0 ,按位传输,高位在前,低位在后。
写操作代码
void LCD_Writ_Bus(uint8_t dat)
{
uint8_t i;
LCD_CS_Clr();//CS拉低
for(i=0;i<8;i++)//总共8位数据
{
LCD_SCLK_Clr();//CLK拉低
if(dat&0x80)//如果需要输出高电平
{
LCD_MOSI_Set();//数据线置高
}
else
{
LCD_MOSI_Clr();//数据线置低
}
LCD_SCLK_Set();//CLK拉高
dat<<=1;//数据左移1位
}
LCD_CS_Set();//CS拉高
}
六.TFT彩屏模块显示
1.8寸TFT LCD彩屏是128x160像素的分辨率,我们可以理解为:水平方向分布了128个像素点,垂直方向分布了160个像素点。我们在画点的时候坐标Y的取值为0-159,坐标X的取值为0-127。
下图红色箭头的方向就是坐标递增的方向。
PCtoLCD2002 是专业的取字模软件,采用C语言和汇编语言两种格式,支持逐行、逐列、行列、列行四种取模方式,可以选择字体、大小、文字的长宽,自动生成你想要的字符,能生成字符字模,中文字模。
软件只需要几步就能轻松生成字符
1.显示英文字符串
程序中调用函数就可以实现:
LCD_ShowString(18,60,“HELLO WORLD”,BLUE,WHITE,16,0);//显示字符串“HELLO WORLD”
/******************************************************************************
函数说明:显示字符串
入口数据:x,y显示坐标
*p 要显示的字符串
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowString(uint16_t x,uint16_t y,const uint8_t *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
while(*p!='\0')
{
LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
x+=sizey/2;
p++;
}
}
多种大小的字体都已经有了,直接选择调用就可以。
2.显示数字
程序中调用函数就可以实现:
LCD_ShowIntNum(50,110,Distance,3,RED,WHITE,12);//显示变量数字值
/******************************************************************************
函数说明:显示整数变量
入口数据:x,y显示坐标
num 要显示整数变量
len 要显示的位数
fc 字的颜色
bc 字的背景色
sizey 字号
返回值: 无
******************************************************************************/
void LCD_ShowIntNum(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey)
{
uint8_t t,temp;
uint8_t enshow=0;
uint8_t sizex=sizey/2;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);
continue;
}else enshow=1;
}
LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);
}
}
多种大小的字体都已经有了,直接选择调用就可以。
3.显示中文
显示中文,主要涉及到一个中文字库的制作,操作如下:
取模软件配置:
常用的点阵大小有12x12、16x16、24x24等,每个点用0或1表示,0代表没有点,1代表有点。这样,每个汉字就可以通过一个二进制数组来表示。
例如汉字24x24点阵如下图显示
24*24点阵,所以一个汉字横向是24个点,纵向也是24个点。取模顺序是从低到高,即左上角第一个点作为最低位,然后逐行进行取模。
其中"光"字C语言数组如下:
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x20,0x18,0x02,0x40,0x18,0x06,0x80,0x18,0x03,0x80,0x19,0x01,0x00,0x99,0x00,0x00,0x98,0x10,0xFE,0xFF,0x3F,0x00,0x63,0x00,0x00,0x63,0x00,0x00,0x63,0x00,0x00,0x61,0x00,0x00,0x61,0x00,0x00,0x61,0x20,0x80,0x61,0x20,0x80,0x60,0x20,0x40,0x60,0x20,0x20,0x40,0x60,0x18,0xC0,0x3F,0x06,0x00,0x00,0x00,0x00,0x00,/“光”/
如下图所示,从左上角原点开始,每次取8个点作为1个字节内容(1个字节的内容低位在前,高位在后,假如某个字节的像素点是00000100,16进制就是0x20)。24个点,刚好是3个字节,从左往右依次类推,第一行就是0x00,0x00,0x00,第二行也是0x00,0x00,0x00,第三行就是0x00,0x18,0x00,第四行也是0x00,0x18,0x00,第五行就是0x20,0x18,0x02。
以此类推,24行数据都取完之后,就有上述的数组表格。
生成好的数组拷贝到程序的tfont24数组,前面再加中文字符“光”,就能直接调用函数显示中文了
const typFNT_GB24 tfont24[]={
"光",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x20,0x18,0x02,0x40,
0x18,0x06,0x80,0x18,0x03,0x80,0x19,0x01,0x00,0x99,0x00,0x00,0x98,0x10,0xFE,0xFF,
0x3F,0x00,0x63,0x00,0x00,0x63,0x00,0x00,0x63,0x00,0x00,0x61,0x00,0x00,0x61,0x00,
0x00,0x61,0x20,0x80,0x61,0x20,0x80,0x60,0x20,0x40,0x60,0x20,0x20,0x40,0x60,0x18,
0xC0,0x3F,0x06,0x00,0x00,0x00,0x00,0x00,/*"光",0*/
/* (24 X 24 , 宋体 )*/
"子",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0x0F,0x00,0x00,0x06,0x00,
0x00,0x01,0x00,0x80,0x00,0x00,0x60,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,
0x10,0xFE,0xFF,0x3F,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,
0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x80,0x19,0x00,0x00,
0x1E,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,/*"子",1*/
/* (24 X 24 , 宋体 )*/
"物",0x00,0x00,0x00,0x40,0x20,0x00,0xC0,0x20,0x00,0x40,0x30,0x00,0x58,0x10,0x00,0x48,
0xF0,0x3F,0x48,0xC8,0x24,0xF8,0x4B,0x26,0x44,0x44,0x26,0x44,0x22,0x22,0x42,0x20,
0x22,0x42,0x10,0x23,0x40,0x13,0x31,0xC0,0x08,0x31,0x70,0x84,0x31,0x4E,0x82,0x30,
0x44,0x40,0x30,0x40,0x20,0x10,0x40,0x10,0x10,0x40,0x08,0x10,0x40,0x84,0x1F,0x40,
0x02,0x0E,0x40,0x00,0x02,0x00,0x00,0x00,/*"物",2*/
/* (24 X 24 , 宋体 )*/
"联",0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x20,0x1C,0xFE,0x27,0x0C,0x08,0x61,0x04,0x08,
0x61,0x02,0x08,0x21,0x12,0x08,0xFD,0x3F,0xF8,0x81,0x01,0x08,0x81,0x01,0x08,0x81,
0x01,0x08,0x81,0x21,0xF8,0xFF,0x7F,0x08,0x81,0x01,0x08,0x81,0x02,0x08,0x85,0x02,
0x88,0x83,0x02,0x78,0x41,0x04,0x0C,0x41,0x0C,0x00,0x21,0x08,0x00,0x11,0x38,0x00,
0x09,0x70,0x00,0x07,0x00,0x00,0x00,0x00,/*"联",3*/
/* (24 X 24 , 宋体 )*/
};
LCD_ShowChinese(12,8,"光子物联",BLUE,WHITE,24,0);//显示中文光子物联,大小24*24点阵,取模软件配置:阴码,逐行式,24X24点阵,逆向,C51格式
/******************************************************************************
函数说明:显示汉字串
入口数据:x,y显示坐标
*s 要显示的汉字串
fc 字的颜色
bc 字的背景色
sizey 字号 可选 16 24 32
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
while(*s!=0)
{
if(sizey==12) LCD_ShowChinese12x12(x,y,s,fc,bc,sizey,mode);
else if(sizey==16) LCD_ShowChinese16x16(x,y,s,fc,bc,sizey,mode);
else if(sizey==24) LCD_ShowChinese24x24(x,y,s,fc,bc,sizey,mode);
else if(sizey==32) LCD_ShowChinese32x32(x,y,s,fc,bc,sizey,mode);
else return;
s+=2;
x+=sizey;
}
}
/******************************************************************************
函数说明:显示单个24x24汉字
入口数据:x,y显示坐标
*s 要显示的汉字
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChinese24x24(uint16_t x,uint16_t y,uint8_t *s,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
uint8_t i,j,m=0;
uint16_t k;
uint16_t HZnum;//汉字数目
uint16_t TypefaceNum;//一个字符所占字节大小
uint16_t x0=x;
TypefaceNum=(sizey/8+((sizey%8)?1:0))*sizey;
HZnum=sizeof(tfont24)/sizeof(typFNT_GB24); //统计汉字数目
for(k=0;k<HZnum;k++)
{
if ((tfont24[k].Index[0]==*(s))&&(tfont24[k].Index[1]==*(s+1)))
{
LCD_Address_Set(x,y,x+sizey-1,y+sizey-1);
for(i=0;i<TypefaceNum;i++)
{
for(j=0;j<8;j++)
{
if(!mode)//非叠加方式
{
if(tfont24[k].Msk[i]&(0x01<<j))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizey==0)
{
m=0;
break;
}
}
else//叠加方式
{
if(tfont24[k].Msk[i]&(0x01<<j)) LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizey)
{
x=x0;
y++;
break;
}
}
}
}
}
continue; //查找到对应点阵字库立即退出,防止多个汉字重复取模带来影响
}
}
七.TFT彩屏实现图片显示
Image2Lcdv2.9 是一款简单实用的图片转LCD显示工具软件,它能使你把各种来源的图片转换成特定的数据格式以用来匹配单片机系统所需要的显示数据格式。
为适应128*160这款TFT-LCD,需更改配置如下
打开图片文件,生成.c文件
拷贝图片生成的.c文件中的数组到程序中pic.h文件中的gImage_1数组
调用图片显示函数实现图片的显示
LCD_ShowPicture(0,0,128,160,gImage_1);//显示图片,通过Image2Lcd 2.9转换图片成C语言数组放入gImage_1
/******************************************************************************
函数说明:显示图片
入口数据:x,y起点坐标
length 图片长度
width 图片宽度
pic[] 图片数组
返回值: 无
******************************************************************************/
void LCD_ShowPicture(uint16_t x,uint16_t y,uint16_t length,uint16_t width,const uint8_t pic[])
{
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++)
{
LCD_WR_DATA8(pic[k*2]);
LCD_WR_DATA8(pic[k*2+1]);
k++;
}
}
}
八.STM32单片机1.8寸 TFT LCD显示实验
1.硬件准备
STLINK接STM32F103C8T6小系统板,STLINK接电脑USB口。
板子与1.8寸TFT彩屏用杜邦线连接:
板子GND-----彩屏GND
板子3V3-----彩屏VCC
板子PA1-----彩屏SCL
板子PA2-----彩屏SDA
板子PA6-----彩屏RES
板子PA3-----彩屏DC
板子PA4-----彩屏CS
板子PA5-----彩屏BL
2.软件工程
打开STM32CubeMX软件,新建工程
Part Number处输入STM32F103C8,再双击就创建新的工程
配置下载口引脚
配置外部晶振引脚
配置系统主频
LCD控制引脚配置成输出
配置工程文件名,保存路径,KEIL5工程输出方式
生成工程
用Keil5打开工程
添加代码
驱动引脚配置
中文字库文件修改
添加显示代码
3.软件主要代码
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t Distance=0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
LCD_Init();//LCD初始化
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LCD_ShowChinese(12,8,"光子物联",BLUE,WHITE,24,0);//显示中文光子物联,//取模软件配置:阴码,逐行式,24X24点阵,逆向,C51格式
LCD_ShowString(18,60,"HELLO WORLD",BLUE,WHITE,16,0);//显示字符串
LCD_ShowIntNum(50,110,Distance,3,RED,WHITE,12);//显示数字
Distance++;
HAL_Delay(200);//等待200ms
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/******************************************************************************
函数说明:显示字符串
入口数据:x,y显示坐标
*p 要显示的字符串
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowString(uint16_t x,uint16_t y,const uint8_t *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
while(*p!='\0')
{
LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);
x+=sizey/2;
p++;
}
}
/******************************************************************************
函数说明:显示单个字符
入口数据:x,y显示坐标
num 要显示的字符
fc 字的颜色
bc 字的背景色
sizey 字号
mode: 0非叠加模式 1叠加模式
返回值: 无
******************************************************************************/
void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode)
{
uint8_t temp,sizex,t,m=0;
uint16_t i,TypefaceNum;//一个字符所占字节大小
uint16_t x0=x;
sizex=sizey/2;
TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;
num=num-' '; //得到偏移后的值
LCD_Address_Set(x,y,x+sizex-1,y+sizey-1); //设置光标位置
for(i=0;i<TypefaceNum;i++)
{
if(sizey==12)temp=ascii_1206[num][i]; //调用6x12字体
else if(sizey==16)temp=ascii_1608[num][i]; //调用8x16字体
else if(sizey==24)temp=ascii_2412[num][i]; //调用12x24字体
else if(sizey==32)temp=ascii_3216[num][i]; //调用16x32字体
else return;
for(t=0;t<8;t++)
{
if(!mode)//非叠加模式
{
if(temp&(0x01<<t))LCD_WR_DATA(fc);
else LCD_WR_DATA(bc);
m++;
if(m%sizex==0)
{
m=0;
break;
}
}
else//叠加模式
{
if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);//画一个点
x++;
if((x-x0)==sizex)
{
x=x0;
y++;
break;
}
}
}
}
}
4.实验效果
显示中文,英文,数字
显示图片
九.小结
TFT-LCD(薄膜晶体管液晶显示屏)主要应用在消费电子领域,其中包括智能手机、平板电脑、笔记本电脑、电视机等,这种显示屏因其轻薄、省电和高性能的特点而受到青睐。学会用STM32驱动TFT-LCD,能让产品显的更加高端美观。