:TFT-作为人们日常生活中常见的屏幕类型之一,受众非常广泛。,,等等都离不开他的身影。可以说学会了TFT-LCD模块是嵌入式开发驱动开发技能之一,也是嵌入式开发调试配置的重要手段和技能!()
STM32F103C8T6;2.4寸TFT-LCD(240×320)
()
()液晶显示屏是薄膜晶体管状液晶显示屏,即。TFT每个像素都有液晶,每个像素都可以通过点脉冲直接控制,因此每个节点都相对独立,可以连续控制,不仅可以提高显示屏的反应速度,还可以准确控制显示色阶,。
TFT液晶显示屏是、、、,但也有比较和的不足。TFT液晶技术加速了手机彩屏的发展。许多新一代彩屏手机支持6536色显示,有些甚至支持16万色显示。TFT对比度高,色彩丰富的优点很重要。
市面上的TFT-LCD有需要的类型(),市场上常见的芯片驱动有:ILI9341/ ILI9325/ RM68042/ RM68021/ ILI9320/ ILI9328/ LGDP4531/ LGDP4535/ SPFD5408/ SSD1289/ 1505/ B505/ C505/ NT35310/ NT35510 等。
笔者所用的TFTLCD驱动芯片为,这里就以ILI以9341为例()。
ILI9341液晶控制器自带显存,其显存总尺寸为 (240*320*18/8),即 18 显存量在位模式下(26万色)。 ,ILI9341 采用 存储颜色数据的格式(),此时 ILI9341的 18 位数据线与 MCU 的 16 位数据线和 LCD GRAM 如图所示 所示:
这样 MCU 的 16 位数据,,,。值越大,表示该。另外,特别注意 ILI9341 所有指令都是 8 位的(),除读写外,还有参数 GRAM 的时候是 16 位置和其他操作参数 8 位,这个和 ILI9320 当驱动器不同时,必须注意。
不同的TFT-LCD模块的引脚可能引脚可能不同LCD硬件通信方式不同。TFTLCD通信方式有:,,LVDS、EDP、MIPI等。()
笔者这块模块采用了,所以下一步就是SPI下的TFT-LCD驱动是解释。
二、SPI简介
是由通信协议 (),即串行外围设备接口,是一种高速全双工通信总线。广泛应用于 、等设备与 MCU 通信速度高的场合。
2.1SPI通讯系统
SPI 通讯使用及,3 条总线分别为 ,片选线为 ,其功能介绍如下:
,常称为,也为 、,以下用 表示。当有多个 SPI 从设备与 SPI 主机相连时,设备的其它信号线 SCK、MOSI 及 MISO同时并联到相同的 SPI 总线上,即无论有多少个从设备,;而每个从设备都有独立的这一条 NSS 信号线,本信号线独占主机的一个引脚,即有多少个从设备,就有多少条片选信号线。
,它使用,当主机要选择从设备时,把该从设备的 NSS 信号线设置为,该从设备即,即,接着主机开始与被选中的从设备。所以 SPI 通讯以 NSS 线置低电平为开始信号,以NSS 线被拉高作为结束信号。()
。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如 STM32 的 ,两个设备之间通讯时,通讯速率受。
。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。 ()
。主机从这条信线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。 ()。
2.2 SPI时序图
①、,串行时钟空闲状态为低电平。 ②、,串行时钟空闲状态为高电平,此时可以通过配置时钟相位(CPHA)来选择具 体的传输协议。 ③、,串行时钟的第一个跳变沿(上升沿或下降沿)采集数据。 ④、,串行时钟的第二个跳变沿(上升沿或下降沿)采集数据。
三、CubexMX配置
();
四、代码实现与实验效果
4.1 TFT-LCD基础的初始化
以下代码读者朋友可以参考各自文本,不同类型的TFT-LCD屏幕的初始化写入的数据可能不同,但是主要还是对那几个功能寄存器写入对应的数值。
/****************************************************************************
* 名 称:void SPIv_WriteData(u8 Data)
* 功 能:STM32_模拟SPI写一个字节数据底层函数
* 入口参数:Data
* 出口参数:无
* 说 明:STM32_模拟SPI读写一个字节数据底层函数
****************************************************************************/
//void SPIv_WriteData(u8 Data)
//{
// unsigned char i=0;
// for(i=8;i>0;i--)
// {
// if(Data&0x80)
// {
// LCD_SDA_SET; //????
// }
// else
// {
// LCD_SDA_CLR;
// }
// LCD_SCL_CLR;
// LCD_SCL_SET;
// Data<<=1;
// }
//}
void SPIv_WriteData(u8 Data)
{
SPI_WriteByte(&Data, 1);
}
/****************************************************************************
* 名 称:Lcd_WriteIndex(u8 Index)
* 功 能:向液晶屏写一个8位指令
* 入口参数:Index 寄存器地址
* 出口参数:无
* 说 明:调用前需先选中控制器,内部函数
****************************************************************************/
void Lcd_WriteIndex(u8 Index)
{
LCD_CS_CLR;
LCD_RS_CLR;
SPIv_WriteData(Index);
LCD_CS_SET;
}
/****************************************************************************
* 名 称:Lcd_WriteData(u8 Data)
* 功 能:向液晶屏写一个8位数据
* 入口参数:dat 寄存器数据
* 出口参数:无
* 说 明:向控制器指定地址写入数据,内部函数
****************************************************************************/
void Lcd_WriteData(u8 Data)
{
LCD_CS_CLR;
LCD_RS_SET;
SPIv_WriteData(Data);
LCD_CS_SET;
}
/****************************************************************************
* 名 称:void LCD_WriteReg(u8 Index,u16 Data)
* 功 能:写寄存器数据
* 入口参数:Index,Data
* 出口参数:无
* 说 明:本函数为组合函数,向Index地址的寄存器写入Data值
****************************************************************************/
void LCD_WriteReg(u8 Index,u16 Data)
{
Lcd_WriteIndex(Index);
Lcd_WriteData_16Bit(Data);
}
/****************************************************************************
* 名 称:void Lcd_WriteData_16Bit(u16 Data)
* 功 能:向液晶屏写一个16位数据
* 入口参数:Data
* 出口参数:无
* 说 明:向控制器指定地址写入一个16位数据
****************************************************************************/
void Lcd_WriteData_16Bit(u16 Data)
{
LCD_CS_CLR;
LCD_RS_SET;
Lcd_WriteData(Data>>8);
Lcd_WriteData(Data);
LCD_CS_SET;
}
/****************************************************************************
* 名 称:void Lcd_Reset(void)
* 功 能:液晶硬复位函数
* 入口参数:无
* 出口参数:无
* 说 明:液晶初始化前需执行一次复位操作
****************************************************************************/
void Lcd_Reset(void)
{
LCD_RST_CLR;
HAL_Delay(100);
LCD_RST_SET;
HAL_Delay(50);
}
void Lcd_Init(void)
{
Lcd_Reset(); //Reset before LCD Init.
//2.2inch TM2.2-G2.2 Init 20171020
Lcd_WriteIndex(0x11);
Lcd_WriteData(0x00);
Lcd_WriteIndex(0xCF);
Lcd_WriteData(0X00);
Lcd_WriteData(0XC1);
Lcd_WriteData(0X30);
Lcd_WriteIndex(0xED);
Lcd_WriteData(0X64);
Lcd_WriteData(0X03);
Lcd_WriteData(0X12);
Lcd_WriteData(0X81);
Lcd_WriteIndex(0xE8);
Lcd_WriteData(0X85);
Lcd_WriteData(0X11);
Lcd_WriteData(0X78);
Lcd_WriteIndex(0xF6);
Lcd_WriteData(0X01);
Lcd_WriteData(0X30);
Lcd_WriteData(0X00);
Lcd_WriteIndex(0xCB);
Lcd_WriteData(0X39);
Lcd_WriteData(0X2C);
Lcd_WriteData(0X00);
Lcd_WriteData(0X34);
Lcd_WriteData(0X05);
Lcd_WriteIndex(0xF7);
Lcd_WriteData(0X20);
Lcd_WriteIndex(0xEA);
Lcd_WriteData(0X00);
Lcd_WriteData(0X00);
Lcd_WriteIndex(0xC0);
Lcd_WriteData(0X20);
Lcd_WriteIndex(0xC1);
Lcd_WriteData(0X11);
Lcd_WriteIndex(0xC5);
Lcd_WriteData(0X31);
Lcd_WriteData(0X3C);
Lcd_WriteIndex(0xC7);
Lcd_WriteData(0XA9);
Lcd_WriteIndex(0x3A);
Lcd_WriteData(0X55);
Lcd_WriteIndex(0x36);
#if USE_HORIZONTAL
Lcd_WriteData(0xE8);//横屏参数
#else
Lcd_WriteData(0x48);//竖屏参数
#endif
Lcd_WriteIndex(0xB1);
Lcd_WriteData(0X00);
Lcd_WriteData(0X18);
Lcd_WriteIndex(0xB4);
Lcd_WriteData(0X00);
Lcd_WriteData(0X00);
Lcd_WriteIndex(0xF2);
Lcd_WriteData(0X00);
Lcd_WriteIndex(0x26);
Lcd_WriteData(0X01);
Lcd_WriteIndex(0xE0);
Lcd_WriteData(0X0F);
Lcd_WriteData(0X17);
Lcd_WriteData(0X14);
Lcd_WriteData(0X09);
Lcd_WriteData(0X0C);
Lcd_WriteData(0X06);
Lcd_WriteData(0X43);
Lcd_WriteData(0X75);
Lcd_WriteData(0X36);
Lcd_WriteData(0X08);
Lcd_WriteData(0X13);
Lcd_WriteData(0X05);
Lcd_WriteData(0X10);
Lcd_WriteData(0X0B);
Lcd_WriteData(0X08);
Lcd_WriteIndex(0xE1);
Lcd_WriteData(0X00);
Lcd_WriteData(0X1F);
Lcd_WriteData(0X23);
Lcd_WriteData(0X03);
Lcd_WriteData(0X0E);
Lcd_WriteData(0X04);
Lcd_WriteData(0X39);
Lcd_WriteData(0X25);
Lcd_WriteData(0X4D);
Lcd_WriteData(0X06);
Lcd_WriteData(0X0D);
Lcd_WriteData(0X0B);
Lcd_WriteData(0X33);
Lcd_WriteData(0X37);
Lcd_WriteData(0X0F);
Lcd_WriteIndex(0x29);
}
以上代码为下常见的代码,其中不同驱动芯片下的会不同,基本一致的函数有:
//define LCD PIN
#define LCD_CS_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_SET)
#define LCD_CS_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET)
#define LCD_RS_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET)
#define LCD_RS_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET)
#define LCD_SDA_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET)
#define LCD_SDA_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET)
#define LCD_SCL_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET)
#define LCD_SCL_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET)
#define LCD_RST_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET)
#define LCD_RST_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET)
#define LCD_LED_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
#define LCD_LED_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
4.2 SPI函数重写
因为笔者采用了去使用,所以需要去。
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
uint8_t SPI_WriteByte(uint8_t *TxData,uint16_t size);
/* USER CODE END Includes */
/* USER CODE BEGIN 1 */
uint8_t SPI_WriteByte(uint8_t *TxData,uint16_t size)
{
return HAL_SPI_Transmit(&hspi2,TxData,size,1000);
}
/* USER CODE END 1 */
4.3 TFT-LCD显示的基础函数
/*************************************************
函数名:LCD_Set_XY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(u16 Xpos, u16 Ypos)
{
Lcd_WriteIndex(0x2A);
Lcd_WriteData_16Bit(Xpos);
Lcd_WriteIndex(0x2B);
Lcd_WriteData_16Bit(Ypos);
Lcd_WriteIndex(0x2c);
}
/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点
返回值:无
*************************************************/
//设置显示窗口
void Lcd_SetRegion(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
{
Lcd_WriteIndex(0x2A);
Lcd_WriteData_16Bit(xStar);
Lcd_WriteData_16Bit(xEnd);
Lcd_WriteIndex(0x2B);
Lcd_WriteData_16Bit(yStar);
Lcd_WriteData_16Bit(yEnd);
Lcd_WriteIndex(0x2c);
}
/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:xy坐标和颜色数据
返回值:无
*************************************************/
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{
Lcd_SetXY(x,y);
Lcd_WriteData_16Bit(Data);
}
/*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色COLOR
返回值:无
*************************************************/
void Lcd_Clear(u16 Color)
{
unsigned int i;
Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);
LCD_CS_CLR;
LCD_RS_SET;
for(i=0;i<X_MAX_PIXEL*Y_MAX_PIXEL;i++)
{
// Lcd_WriteData_16Bit(Color);
SPIv_WriteData(Color>>8);
SPIv_WriteData(Color);
}
LCD_CS_SET;
}
#ifndef __LCD_H
#define __LCD_H
#include "main.h"
#define u8 unsigned char
#define u16 unsigned int
/用户配置区///
//支持横竖屏快速定义切换
#define USE_HORIZONTAL 0 //定义是否使用横屏 0,不使用.1,使用.
//-----------------------------SPI 总线配置--------------------------------------//
#define USE_HARDWARE_SPI 0 //1:Enable Hardware SPI;0:USE Soft SPI
//-------------------------屏幕物理像素设置--------------------------------------//
#define LCD_X_SIZE 240
#define LCD_Y_SIZE 320
#if USE_HORIZONTAL//如果定义了横屏
#define X_MAX_PIXEL LCD_Y_SIZE
#define Y_MAX_PIXEL LCD_X_SIZE
#else
#define X_MAX_PIXEL LCD_X_SIZE
#define Y_MAX_PIXEL LCD_Y_SIZE
#endif
//
#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define WHITE 0xffff
#define BLACK 0x0000
#define YELLOW 0xFFE0
#define GRAY0 0xEF7D //灰色0 3165 00110 001011 00101
#define GRAY1 0x8410 //灰色1 00000 000000 00000
#define GRAY2 0x4208 //灰色2 1111111111011111
//define LCD PIN
#define LCD_CS_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_SET)
#define LCD_CS_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET)
#define LCD_RS_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET)
#define LCD_RS_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET)
#define LCD_SDA_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET)
#define LCD_SDA_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET)
#define LCD_SCL_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET)
#define LCD_SCL_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET)
#define LCD_RST_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET)
#define LCD_RST_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET)
#define LCD_LED_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
#define LCD_LED_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
void Lcd_Reset(void);
void Lcd_WriteIndex(u8 Index);
void Lcd_WriteData(u8 Data);
void Lcd_WriteReg(u8 Index,u8 Data);
u16 Lcd_ReadReg(u8 LCD_Reg);
void Lcd_Reset(void);
void Lcd_Init(void);
void Lcd_Clear(u16 Color);
void Lcd_SetXY(u16 x,u16 y);
void Gui_DrawPoint(u16 x,u16 y,u16 Data);
unsigned int Lcd_ReadPoint(u16 x,u16 y);
void Lcd_SetRegion(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd);
void Lcd_WriteData_16Bit(u16 Data);
#endif
4.4 TFT-LCD显示的API函数
#ifndef __LCDAPI_H
#define __LCDAPI_H
#include "main.h"
#define u8 unsigned char
#define u16 unsigned int
void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc);
void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color);
void Gui_box(u16 x, u16 y, u16 w, u16 h,u16 bc);
void Gui_box2(u16 x,u16 y,u16 w,u16 h, u8 mode);
void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2);
void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2);
void Gui_DrawFont_GBK16(u16 x, u16 y, u16 fc, u16 bc, u8 *s);
void Gui_DrawFont_GBK24(u16 x, u16 y, u16 fc, u16 bc, u8 *s);
void Gui_DrawFont_Num32(u16 x, u16 y, u16 fc, u16 bc, u16 num);
void LCD_DrawPoint(u16 x,u16 y);
unsigned long oled_pow(u8 m,u8 n);
void LCD_Showdecimal(u8 x,u8 y,float num,u8 z_len,u8 f_len,u8 size2);
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 mode);
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2);
void showhanzi(unsigned int x,unsigned int y,unsigned char index);
void showimage(const unsigned char *p);
void LCD_ShowNum(u16 x,u16 y,unsigned long num,u8 len);
void picture();
#endif
4.4.1 TFT-LCD显示字符和汉字的API函数
笔者这里写了一个,。
LCD的汉字与字符显示与OLED类似,也是需要去的,。
笔者这里的取字模方式:
//display 16 ziti
void Gui_DrawFont_GBK16(u16 x, u16 y, u16 fc, u16 bc, u8 *s)
{
unsigned char i,j;
unsigned short k,x0;
x0=x;
while(*s)
{
if((*s) < 128)
{
k=*s;
if (k==13)
{
x=x0;
y+=16;
}
else
{
if (k>32) k-=32; else k=0;
for(i=0;i<16;i++)
for(j=0;j<8;j++)
{
if(asc16[k*16+i]&(0x80>>j)) Gui_DrawPoint(x+j,y+i,fc);
else
{
if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
}
}
x+=8;
}
s++;
}
else
{
for (k=0;k<hz16_num;k++)
{
if ((hz16[k].Index[0]==*(s))&&(hz16[k].Index[1]==*(s+1)))
{
for(i=0;i<16;i++)
{
for(j=0;j<8;j++)
{
if(hz16[k].Msk[i*2]&(0x80>>j)) Gui_DrawPoint(x+j,y+i,fc);
else {
if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
}
}
for(j=0;j<8;j++)
{
if(hz16[k].Msk[i*2+1]&(0x80>>j)) Gui_DrawPoint(x+j+8,y+i,fc);
else
{
if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);
}
}
}
}
}
s+=2;x+=16;
}
}
}
//display 24 ziti
void Gui_DrawFont_GBK24(u16 x, u16 y, u16 fc, u16 bc, u8 *s)
{
unsigned char i,j;
unsigned short k;
while(*s)
{
if( *s < 0x80 )
{
k=*s;
if (k>32) k-=32; else k=0;
for(i=0;i<16;i++)
for(j=0;j<8;j++)
{
if(asc16[k*16+i]&(0x80>>j))
Gui_DrawPoint(x+j,y+i,fc);
else
{
if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
}
}
s++;x+=8;
}
else
{
for (k=0;k<hz24_num;k++)
{
if ((hz24[k].Index[0]==*(s))&&(hz24[k].Index[1]==*(s+1)))
{
for(i=0;i<24;i++)
{
for(j=0;j<8;j++)
{
if(hz24[k].Msk[i*3]&(0x80>>j))
Gui_DrawPoint(x+j,y+i,fc);
else
{
if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);
}
}
for(j=0;j<8;j++)
{
if(hz24[k].Msk[i*3+1]&(0x80>>j)) Gui_DrawPoint(x+j+8,y+i,fc);
else {
if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);
}
}
for(j=0;j<8;j++)
{
if(hz24[k].Msk[i*3+2]&(0x80>>j))
Gui_DrawPoint(x+j+16,y+i,fc);
else
{
if (fc!=bc) Gui_DrawPoint(x+j+16,y+i,bc);
}
}
}
}
}
s+=2;x+=24;
}
}
}
//Font display 24 and 16
Gui_DrawFont_GBK24(0,0,GREEN,WHITE,"»ì·Ö¾ÞÊÞÁúijij");
Gui_DrawFont_GBK16(0,30,BLUE,WHITE,"»ì·Ö¾ÞÊÞÁúijij");
//string display
Gui_DrawFont_GBK16(0,50,BLACK,WHITE,"black sneak");
4.4.2 TFT-LCD显示数字和含小数的API函数
动态的数字显示和含有小数的数字显示也是日常嵌入式开发中经常会遇到的,学会使用该API函数也是至关重要的。
void LCD_ShowNum(u16 x,u16 y,unsigned long num,u8 len)
{
u8 t,temp;
u8 enshow=0;
num=(u16)num;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
LCD_ShowChar(x+8*t,y,' ',1);
continue;
}else enshow=1;
}
LCD_ShowChar(x+8*t,y,temp+48,1);
}
}
void LCD_Showdecimal(u8 x,u8 y,float num,u8 z_len,u8 f_len,u8 size2)
{
u8 t,temp;
u8 enshow;
int z_temp,f_temp;
z_temp=(int)num;
//????
for(t=0;t<z_len;t++)
{
temp=(z_temp/oled_pow(10,z_len-t-1))%10;
if(enshow==0 && t<(z_len-1))
{
if(temp==0)
{
LCD_ShowChar(x+(size2/2)*t,y,' ',size2);
continue;
}
else
enshow=1;
}
LCD_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
//小数点
LCD_ShowChar(x+(size2/2)*(z_len),y,'.',size2);
f_temp=(int)((num-z_temp)*(oled_pow(10,f_len)));
//小数部分
for(t=0;t<f_len;t++)
{
temp=(f_temp/oled_pow(10,f_len-t-1))%10;
LCD_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2);
}
}
4.4.3 TFT-LCD特殊字符或数码管API显示函数
一般特殊的字符或是数码管等也时通过取模软件进行特殊取模以呈现的效果,这里给大家介绍一个类似数码管数字的显示API函数,可以以后作为时钟显示使用。
void Gui_DrawFont_Num32(u16 x, u16 y, u16 fc, u16 bc, u16 num)
{
unsigned char i,j,k,c;
//lcd_text_any(x+94+i*42,y+34,32,32,0x7E8,0x0,sz32,knum[i]);
// w=w/8;
for(i=0;i<32;i++)
{
for(j=0;j<4;j++)
{
c=*(sz32+num*32*4+i*4+j);
for (k=0;k<8;k++)
{
if(c&(0x80>>k)) Gui_DrawPoint(x+j*8+k,y+i,fc);
else {
if (fc!=bc) Gui_DrawPoint(x+j*8+k,y+i,bc);
}
}
}
}
}
4.4.4 TFT-LCD图片显示API函数
TFT-LCD图片显示需要使用到,需要该软件的读者朋友,可以评论留言邮箱。
由于MCU的显存通常有限,特别时C8T6等最小系统板的存储更是有限。如果之后,编译出现如下:
//显示图片
void showimage(const unsigned char *p)
{//??128*128 ??
int i;
unsigned char picH,picL;
// Lcd_Clear(WHITE); //?? ->1
Address_set(100,100,219,219);
for(i=0;i<120*120;i++)
{
picL=*(p+i*2); //??????
picH=*(p+i*2+1);
Lcd_WriteData_16Bit(picH<<8|picL);
}
}
该函数的内参,也是需要读者朋友去根据自己取模的图片大小去设置的,很简单,相信有点C基础的都可以去使用。
4.4.4 main函数
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
Lcd_Init();
LCD_LED_SET;//ͨ¹ýIO¿ØÖƱ³¹âÁ
LCD_RST_SET;
Lcd_Clear(WHITE);
// LCD_RST_SET;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//Font display 24 and 16
Gui_DrawFont_GBK24(0,0,GREEN,WHITE,"混分巨兽龙某某");
Gui_DrawFont_GBK16(0,30,BLUE,WHITE,"混分巨兽龙某某");
//string display
Gui_DrawFont_GBK16(0,50,BLACK,WHITE,"black sneak");
//Number display
LCD_ShowNum(0,180,z,4);
LCD_Showdecimal(0,200,t,2,2,16);
t += 0.01;
z += 1;
//special thing display
for(n = 0;n <10 ;n++)
{
Gui_DrawFont_Num32(0,100,RED,WHITE,num[n]);
if(n == 10)
{
n = 0;
}
}
//PNG display
picture();
}
/* USER CODE END 3 */
TFT-LCD各种显示
六、代码开源
读者这里提供是显示代码,如果需要其他尺寸大小和芯片驱动的LCD代码可以,。
https://pan.baidu.com/s/1tNzOOUUK7ioekmVSy5TqYA yi93