一.简介
TFTLCD显示屏时一个功能相对强大,用途十分广泛的一个显示屏,有些TFTLCD显示屏还兼具了触摸的功能。本次我们在这里介绍TFTLCD显示屏的基于SPI驱动的用法,TFTLCD显示屏市面上常用的有许多不同种的驱动芯片,其驱动方式也主要分为SPI与FSMC驱动,因为我手上的板子是stm32f103c8t6,没有fsmc接口,在此只介绍基于SPI驱动的方式的例程。实验硬件介绍
- stm32f103c8t6最小系统
- TFTLCD显示屏(ILI9341)
注意此处的ILI9341是我采用的TFTLCD显示屏的驱动芯片,各位购置的TFTLCD显示屏也有可能是别的驱动芯片的,这里需要参考自己购买的原理图。不同驱动芯片的命令地址很有可能有区别,这里要注意。如果是采用的ILI9341的驱动芯片就可以直接参考本文。下面我们开始软件程序部分的介绍。
软件采用的是STM32CUBEIDE,作为意法半导体官方提供的IDE,其功能强大,集成度非常之高,采用基于HAL库的编程(省事,不用自己写初始化)。
二.CUBEMX配置
首先我们使用CUBEMX这个软件进行初始化配置,在这里我用的是STM32CUBEIDE里面自带的cubemx软件进行配置与初始化代码生成。时钟树配置如下:
这里优先是能HSE为外部晶振
这里有个骚操作,就是使用HSE之后直接在后面的框里输一个72。cubemx会自动计算。
SPI这里采用的是硬件SPI,有硬件SPI或者IIC或者FSMC的前提下一定是使用硬件的接口而不是采用软件模拟的方式。
SPI的配置如下,没有截到的部分就是按默认就行。这里SPI是当作主机来使用,所以配置的时候要注意。为了方便调试,我也使能了一个串口方便调试并进行了串口重定向,STM32CUBEIDE串口重定向的相关问题各位可以移步专栏下有专门的博客介绍。在这里要注意一个点,因为TFTLCD屏有一个背光的IO,我们需要使能这个IO才可以点亮我们的显示屏,然后接口上还有一个未选的IO,呢个也要打开。
初始化部分到此就介绍完毕,生成代码就好。下面是软件代码部分
三.程序
lcd.c
代码里的注释乱码了,编码格式有点问题,笔记本上没有notepad++,后续再修改
#include "lcd.h"
#include "main.h"
/****************************************************************************
* �� �ƣ�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;
// }
//}
extern SPI_HandleTypeDef hspi1;
uint8_t SPI_WriteByte(uint8_t *TxData,uint16_t size)
{
return HAL_SPI_Transmit(&hspi1,TxData,size,1000);
}
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);
}
/*************************************************
��������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;
}
lcd.h
这里要注意LCD尺寸大小,我这里lcd是240*320的lcd,并且这里要注意后面关于IO的修改,本次采用硬件SPI所以有关SPI的除片选外可以注释掉,背光IO要根据自己的原理图或需求修改
#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_9,GPIO_PIN_SET)
#define LCD_RS_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,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_8,GPIO_PIN_SET)
#define LCD_RST_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,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)
#define LCD_LED_SET HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET)
#define LCD_LED_CLR HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,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
lcdAPI.c
(这个里面主要封装了一系列lcd显示用到的API)
#include "LCDAPI.h"
#include "lcd.h"
#include "font.h"
#include "oledfont.h"
#include "bmp.h"
u16 BACK_COLOR, POINT_COLOR;
//��ILI93xx����������ΪGBR��ʽ��������д���ʱ��ΪRGB��ʽ��
//ͨ���ú���ת��
//c:GBR��ʽ����ɫֵ
//����ֵ��RGB��ʽ����ɫֵ
u16 LCD_BGR2RGB(u16 c)
{
u16 r,g,b,rgb;
b=(c>>0)&0x1f;
g=(c>>5)&0x3f;
r=(c>>11)&0x1f;
rgb=(b<<11)+(g<<5)+(r<<0);
return(rgb);
}
void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc)
{//Bresenham�㷨
unsigned short a,b;
int c;
a=0;
b=R;
c=3-2*R;
while (a<b)
{
Gui_DrawPoint(X+a,Y+b,fc); // 7
Gui_DrawPoint(X-a,Y+b,fc); // 6
Gui_DrawPoint(X+a,Y-b,fc); // 2
Gui_DrawPoint(X-a,Y-b,fc); // 3
Gui_DrawPoint(X+b,Y+a,fc); // 8
Gui_DrawPoint(X-b,Y+a,fc); // 5
Gui_DrawPoint(X+b,Y-a,fc); // 1
Gui_DrawPoint(X-b,Y-a,fc); // 4
if(c<0) c=c+4*a+6;
else
{
c=c+4*(a-b)+10;
b-=1;
}
a+=1;
}
if (a==b)
{
Gui_DrawPoint(X+a,Y+b,fc);
Gui_DrawPoint(X+a,Y+b,fc);
Gui_DrawPoint(X+a,Y-b,fc);
Gui_DrawPoint(X-a,Y-b,fc);
Gui_DrawPoint(X+b,Y+a,fc);
Gui_DrawPoint(X-b,Y+a,fc);
Gui_DrawPoint(X+b,Y-a,fc);
Gui_DrawPoint(X-b,Y-a,fc);
}
}
//���ߺ�����ʹ��Bresenham �����㷨
void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color)
{
int dx, // difference in x's
dy, // difference in y's
dx2, // dx,dy * 2
dy2,
x_inc, // amount in pixel space to move during drawing
y_inc, // amount in pixel space to move during drawing
error, // the discriminant i.e. error i.e. decision variable
index; // used for looping
Lcd_SetXY(x0,y0);
dx = x1-x0;//����x����
dy = y1-y0;//����y����
if (dx>=0)
{
x_inc = 1;
}
else
{
x_inc = -1;
dx = -dx;
}
if (dy>=0)
{
y_inc = 1;
}
else
{
y_inc = -1;
dy = -dy;
}
dx2 = dx << 1;
dy2 = dy << 1;
if (dx > dy)//x�������y���룬��ôÿ��x����ֻ��һ���㣬ÿ��y���������ɸ���
{//���ߵĵ�������x���룬��x���������
// initialize error term
error = dy2 - dx;
// draw the line
for (index=0; index <= dx; index++)//Ҫ���ĵ������ᳬ��x����
{
//����
Gui_DrawPoint(x0,y0,Color);
// test if error has overflowed
if (error >= 0) //�Ƿ���Ҫ����y����ֵ
{
error-=dx2;
// move to next line
y0+=y_inc;//����y����ֵ
} // end if error overflowed
// adjust the error term
error+=dy2;
// move to the next pixel
x0+=x_inc;//x����ֵÿ�λ������1
} // end for
} // end if |slope| <= 1
else//y�����x�ᣬ��ÿ��y����ֻ��һ���㣬x�����ɸ���
{//��y����������
// initialize error term
error = dx2 - dy;
// draw the line
for (index=0; index <= dy; index++)
{
// set the pixel
Gui_DrawPoint(x0,y0,Color);
// test if error overflowed
if (error >= 0)
{
error-=dy2;
// move to next line
x0+=x_inc;
} // end if error overflowed
// adjust the error term
error+=dx2;
// move to the next pixel
y0+=y_inc;
} // end for
} // end else |slope| > 1
}
void Gui_box(u16 x, u16 y, u16 w, u16 h,u16 bc)
{
Gui_DrawLine(x,y,x+w,y,0xEF7D);
Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);
Gui_DrawLine(x,y+h,x+w,y+h,0x2965);
Gui_DrawLine(x,y,x,y+h,0xEF7D);
Gui_DrawLine(x+1,y+1,x+1+w-2,y+1+h-2,bc);
}
void Gui_box2(u16 x,u16 y,u16 w,u16 h, u8 mode)
{
if (mode==0) {
Gui_DrawLine(x,y,x+w,y,0xEF7D);
Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);
Gui_DrawLine(x,y+h,x+w,y+h,0x2965);
Gui_DrawLine(x,y,x,y+h,0xEF7D);
}
if (mode==1) {
Gui_DrawLine(x,y,x+w,y,0x2965);
Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xEF7D);
Gui_DrawLine(x,y+h,x+w,y+h,0xEF7D);
Gui_DrawLine(x,y,x,y+h,0x2965);
}
if (mode==2) {
Gui_DrawLine(x,y,x+w,y,0xffff);
Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xffff);
Gui_DrawLine(x,y+h,x+w,y+h,0xffff);
Gui_DrawLine(x,y,x,y+h,0xffff);
}
}
/**************************************************************************************
��������: ����Ļ��ʾһ��İ�ť��
�� ��: u16 x1,y1,x2,y2 ��ť�����ϽǺ����½�����
�� ��: ��
**************************************************************************************/
void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2)
{
Gui_DrawLine(x1, y1, x2,y1, GRAY2); //H
Gui_DrawLine(x1+1,y1+1,x2,y1+1, GRAY1); //H
Gui_DrawLine(x1, y1, x1,y2, GRAY2); //V
Gui_DrawLine(x1+1,y1+1,x1+1,y2, GRAY1); //V
Gui_DrawLine(x1, y2, x2,y2, WHITE); //H
Gui_DrawLine(x2, y1, x2,y2, WHITE); //V
}
/**************************************************************************************
��������: ����Ļ��ʾһ���µİ�ť��
�� ��: u16 x1,y1,x2,y2 ��ť�����ϽǺ����½�����
�� ��: ��
**************************************************************************************/
void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2)
{
Gui_DrawLine(x1, y1, x2,y1, WHITE); //H
Gui_DrawLine(x1, y1, x1,y2, WHITE); //V
Gui_DrawLine(x1+1,y2-1,x2,y2-1, GRAY1); //H
Gui_DrawLine(x1, y2, x2,y2, GRAY2); //H
Gui_DrawLine(x2-1,y1+1,x2-1,y2, GRAY1); //V
Gui_DrawLine(x2 ,y1 ,x2,y2, GRAY2); //V
}
//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;
}
}
}
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);
}
}
}
}
}
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
Lcd_WriteIndex(0x2a);
Lcd_WriteData(x1>>8);
Lcd_WriteData(x1);
Lcd_WriteData(x2>>8);
Lcd_WriteData(x2);
Lcd_WriteIndex(0x2b);
Lcd_WriteData(y1>>8);
Lcd_WriteData(y1);
Lcd_WriteData(y2>>8);
Lcd_WriteData(y2);
Lcd_WriteIndex(0x2C);
}
//??
//POINT_COLOR:?????
void LCD_DrawPoint(u16 x,u16 y)
{
Address_set(x,y,x,y);//??????
Lcd_WriteData_16Bit(POINT_COLOR);
}
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 mode)
{
u8 temp;
u8 pos,t;
u16 x0=x;
u16 colortemp=POINT_COLOR;
if(x>LCD_X_SIZE-16||y>LCD_Y_SIZE-16)return;
//????
num=num-' ';//???????
Address_set(x,y,x+8-1,y+16-1); //??????
if(mode) //?????
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(u16)num*16+pos]; //??1608??
for(t=0;t<8;t++)
{
if(temp&0x01)POINT_COLOR=colortemp;
else POINT_COLOR=WHITE;
Lcd_WriteData_16Bit(POINT_COLOR);
temp>>=1;
x++;
}
x=x0;
y++;
}
}else//????
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(u16)num*16+pos]; //??1608??
for(t=0;t<8;t++)
{
if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//????
temp>>=1;
}
}
}
POINT_COLOR=colortemp;
}
unsigned long oled_pow(u8 m,u8 n)
{
unsigned long result=1;
while(n--)result*=m;
return result;
}
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);
}
}
void showhanzi(unsigned int x,unsigned int y,unsigned char index)
{
unsigned char i,j;
unsigned char *temp=hanzi;
Address_set(x,y,x+31,y+31); //��������
temp+=index*128;
for(j=0;j<128;j++)
{
for(i=0;i<8;i++)
{
if((*temp&(1<<i))!=0)
{
Lcd_WriteData_16Bit(POINT_COLOR);
}
else
{
Lcd_WriteData_16Bit(WHITE);
}
}
temp++;
}
}
//��ʾͼƬ
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);
}
}
//??2???
//x,y :????
//len :?????
//color:??
//num:??(0~4294967295);
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 picture()
{
showimage(gImage_new);
}
lcdAPI.h
#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
除此之外我们还需要一个字库文件专门用来存放字库信息,中文字库因为特殊性所以只能是用哪个的时候利用取字模软件去取。字库文件在这里不再显示。同理,如果要显示图片也需要利用取字模软件提取。
main函数初始化部分一定记得添加关于LCD的初始化代码。LCD_LED_SET就是打开LCD背光进行显示的命令。这里就需要自己修改对应的IO,相关代码再LCD.h文件中。
main.c
/* USER CODE BEGIN 2 */
Lcd_Init();
LCD_LED_SET;//ͨ��IO���Ʊ����
LCD_RST_SET;
Lcd_Clear(YELLOW);
/* USER CODE END 2 */
结尾
参考链接(这个博主对于底层的一些讲的很清晰。我的代码也是再其基础上进行了一些修改)
最后就是广告时间啦,有需要嵌入式/计算机视觉等相关指导的同学可以私信联系,该例程后续会发布在gitee上。