前言
本文是基于F407ZGT6的HAL库方式来驱动的,目前学的是最基础的东西,只是简单的在屏幕上显示ASCII字符和汉字,其他的功能暂时还没学到。写这篇文章是怕以后要使用的时候又忘记怎么驱动的了,又要去翻资料,花大量时间。错误的地方欢迎大家指正,谢谢!
一、ST7789V2
1. 基本介绍
ST7789V2是一个单芯片控制器/驱动器的262k色,图形型TFT-LCD。它由720条源极线和320栅极线驱动电路组成。该芯片可以直接连接到外部微处理器,并接受8位/9位/16位/18位并行接口。显示数据可以存储在240x320x18位的片上显示数据RAM中。它可以在没有外部操作时钟的情况下进行显示数据RAM读写操作,以降低功耗。此外,由于驱动液晶所需的集成电源电路,可以制造一个具有最少组件的显示系统。
2. 特点
显示分辨率: 240*RGB (H) *320(V),
帧内存大小:240x320x18位= 1,382,400位。
各种显示数据输入格式的可编程像素颜色格式(颜色深度):
12位/像素:RGB=(444)
16位/像素:RGB=(565)
18位/像素:RGB=(666)
地址控制:地址计数器设置用于写入和读取的显示数据RAM的地址。数据按像素级写入到驱动器的RAM矩阵中。根据数据格式,收集一个或两个像素的数据(RGB6-6-6位)。一旦这个像素数据信息完成,“RAM上的写访问”就会被激活。RAM的位置由地址指针进行定位。地址范围为X=0到X=239(Efh)和Y=0到Y=319(13Fh)。不允许使用这些范围之外的地址。在写入RAM之前,必须定义一个要写入的窗口。该窗口可通过命令寄存器进行编程,XS,YS指定开始地址,XE,YE指定结束地址。例如,整个显示内容将被写入,窗口由以下值定义:XS=0(0h)YS=0(0h)和XE=239(Efh)、YE=319(13Fh)。
在垂直寻址模式(MV=1)中,Y地址在每个字节之后递增,在最后一个Y地址(Y=YE)之后,Y绕到YS,X递增以地址下一列。在水平寻址模式(MV=0)中,X地址在每个字节之后递增,在最后一个X地址(X=XE)之后,X绕到XS,Y递增以处理下一行。在每个最后一个地址(X=XE和Y=YE)之后,地址指针环绕到地址(X=XS和Y=YS)。
3.引脚
3.1 电源引脚
3.2 接口逻辑引脚
DCX引脚为数据/命令发送选择引脚,当DCX为低电平时,单片机发送的是命令,DCX为高电平时发送的是数据。
4. 电压参数
5. 屏幕显存地址排列
当我们设置屏幕正常显示时,如下图,屏幕长240Columns,高320lines,左上角为屏幕显存地址的起点00,以第一行为例,地址先是从左往右自增1,增加到最右边0Z时,在增加一个地址就到了第二行的10,也就是说x从X0开始自增,x每增加240,x归零,y加一。也可以看成是在本子上写字,一行从左到右写满240个字再从下一行最左边开始写,直至写完320行。
要想设置成上述的描述,需要发送内存数据索引控制命令(0x36)来设置,具体见下下图,显示屏的具体初始化后面的程序会有详细的注释。
下图就是内存数据索引控制命令,发送该命令后紧跟的数据就是设置显示屏显示的方向,模式,颜色格式和屏幕刷新方式等,我们写入数据0x00就是按上图的方式来显示。
6. SPI驱动步骤
上图是我的ST7789V2的原理图,LCD背光阴极LEDK1-LEDK4已经接地了,LCD背光阳极LEDA接上单片机PWM输出就可以控制屏幕亮度了,但是由于还没有学到PWM,所以此处直接接固定的3.3V,即让Q2导通,让PE6输出一个低电平Q2就导通了,3.3V电压就送到了LEDA脚。
1)设置PE6输出低电平,让LCD背光阳极接到3.3V;
2)LCD硬件复位(HardWareReset);
3)LCD退出睡眠模式 (SleepOut);
3)设置LCD为正常显示(NormalDisplayModeOn);
4)关闭反转显示(DisplayInversionOff);
5)设置显示方向为从左到右,从上到下(MemdataAccessControl);
6)设置显示的像素格式(SetPixelFormat);
7)打开LCD显示(DisplayOn);
以上就完成了LCD显示的初始化,若想要整屏显示一个颜色,则写一个函数将屏幕的240*320个像素点全部设置为同一个颜色就可以了。程序放在后面部分。
每次上电后,需先整屏刷屏,再去显示我们想要显示的文字,数据等,不然上一次上电显示的内容还在。
二、字模提取
1. 字符取模
1.1基本设置
上方导航窗口点击“模式“,选择字符模式,字体默认宋体,字宽和字高均设置为16
点击上图中的”选项“按钮将弹出下面的对话框,以下设置根据我的硬件和后续的编程有关,具体还不是很清楚,清楚了再来补充。
1.2 字模选项设置
点阵格式设置为阴码,取模方式设置为行列式,点阵和索引均设置为16,取模走向为逆向,输出数制为十六进制,输出选项三项都勾选上,像素大小设置为8,格式设为C51格式,自定义格式默认即可,设置完了点击确定即可。
1.3 设置和获取字模
在下图中第一步的矩形区域中输入自己要显示的字符,然后点击后方的生成字模,就会在下方生成字模对应的数据,然后就可以将数据复制到程序中使用了
2.获取ASCII字模
2.1 进入英文字模获取
点击下图中文本图标,弹出生成字库对话框
2.2 生成assic库字模
在下图中的对话框中点击“生成英文点阵字库”,接着会弹出另存为对话框,先将保存类型设置为所有文件,再将文件名设置为ascii.txt或者.c文件也可以。然后点击保存即可。
2.3 生成的ASCII字库
打开生成的txt字库文件大致如下
三、F407ZGT6
要驱动ST7789V2显示屏,需使用(硬件)SPI的通信方式,其中还有片选引脚CS,故开始前还需写SPI和GPIO的驱动文件才能去驱动显示屏。
1. CubeMX配置
先按第一部分的硬件原理图配置CubeMX。配置时钟和调试接口就不贴图了。
1.1 SPI配置
先按下图将SPI配置为全双工主机模式,参数部分只需要将分频系数改为16,其他的不用动,因为通过查手册我们可以知道,ST7789读数据的最小周期是150ns,也就是说通信SPI的最大频率不能超过150ns对应的频率6.67MHz,这里设置16分频是满足要求的最快的频率了。
在NVIC中勾选上中断使能,再去DMA Setting中设置DMA,把SPI1_RX和SPI1_TX都添加上,DMA的参数默认就行。
1.2 GPIO配置
根据原理图配置以下GPIO,输出电平和输出速度均设为High,因为复位脚和片选脚都是低电平生效,所以初始化先将它们设置为高电平。
1.3 工程配置
按下图设置生成对应外设的头文件和源文件,即可生成工程。
2. 程序部分
2.1 gpio.c
还需在gpio.h中声明以下函数,只需声明函数的头文件后面都没有贴了,自己创建一个头文件声明供外部调用的函数就行
/* USER CODE BEGIN 2 */
void Write_7789_CS(unsigned char status)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, status?GPIO_PIN_SET:GPIO_PIN_RESET);
}
void Write_7789_DCX(unsigned char status)
{
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, status?GPIO_PIN_SET:GPIO_PIN_RESET);
}
void Write_7789_RST(unsigned char status)
{
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_15, status?GPIO_PIN_SET:GPIO_PIN_RESET);
}
void Write_7789_BACK(unsigned char status)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_6, status?GPIO_PIN_SET:GPIO_PIN_RESET);
}
/* USER CODE END 2 */
2.2 errno.h
下述代码中会用到errno.h中的错误返回值,先贴上
#ifndef __ERRNO_H
#define __ERRNO_H
#define ESUCCESS 0
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
#define EDEADLK 35 /* Resource deadlock would occur */
#define ENAMETOOLONG 36 /* File name too long */
#define ENOLCK 37 /* No record locks available */
#endif /* __ERRNO_H */
2.3 drv_spi.c
#include "stm32f4xx_hal.h"
#include "errno.h"
#include "spi.h"
static void TranmistFinish_Wait(void);
static void ReceiveFinish_Wait(void);
static unsigned char txcpltflag = 0;
static unsigned char rxcpltflag = 0;
/* spi中断方式发送 */
int SPI_TransmitData(unsigned char *wbuf,unsigned int length)
{
if(length > 0xFFFFFFFF) return -EINVAL;
if(NULL == wbuf) return -EINVAL;
unsigned len_init = length;
if(length < 10)
{
HAL_StatusTypeDef status = HAL_SPI_Transmit_IT(&hspi1,wbuf,length);
if(HAL_OK != status) return -EIO;
TranmistFinish_Wait();
}
else
{
while(length)
{
unsigned size = 0;
if(length > 0xFFFF)
size = 0xFFFF;
else
size = length;
HAL_StatusTypeDef status = HAL_SPI_Transmit_DMA(&hspi1,wbuf,length);
if(HAL_OK != status) return -EIO;
TranmistFinish_Wait();
length -= size;
}
}
return len_init;
}
/* spi中断方式接收 */
int SPI_ReceiveData(unsigned char *rbuf,unsigned int length)
{
if(length > 0xFFFFFFFF) return -EINVAL;
if(NULL == rbuf) return -EINVAL;
unsigned len_init = length;
if(length < 10)
{
HAL_StatusTypeDef status = HAL_SPI_Receive_IT(&hspi1,rbuf,length);
if(HAL_OK != status) return -EIO;
ReceiveFinish_Wait();
}
else
{
while(length)
{
unsigned size = 0;
if(length > 0xFFFF)
size = 0xFFFF;
else
size = length;
HAL_StatusTypeDef status = HAL_SPI_Receive_DMA(&hspi1,rbuf,length);
if(HAL_OK != status) return -EIO;
ReceiveFinish_Wait();
length -= size;
}
}
return len_init;
}
/* 等待数据发送完成 */
static void TranmistFinish_Wait(void)
{
while(!txcpltflag);
txcpltflag = 0;
}
/* 等待数据接收完成 */
static void ReceiveFinish_Wait(void)
{
while(!rxcpltflag);
rxcpltflag = 0;
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if(hspi == &hspi1)
{
txcpltflag = 1;
}
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
if(hspi == &hspi1)
{
rxcpltflag = 1;
}
}
2.4 drv_st7789.h
先头文件是因为源文件中要用到头文件中定义的结构体。
#ifndef __DRV_ST7789_H
#define __DRV_ST7789_H
//Receive or continue send
#define SoftwareReset (0x01) //No Parameter
#define ReadDisplayID (0x04) //4 Parameter,first is dummy data
#define ReadDisplayStatus (0x09) //5 Parameter,first is dummy data
#define ReadDisplayPowerMode (0x0A) //2 Parameter,first is dummy data
#define ReadDisplayMADCTL (0x0B) //2 Parameter,first is dummy data
#define ReadDisplayPixelFormat (0x0C) //2 Parameter,first is dummy data
#define SleepIn (0x10) //No Parameter
#define SleepIOut (0x11) //No Parameter
#define PartialDisplayModeOn (0x12) //No Parameter
#define NormalDisplayModeOn (0x13) //No Parameter
#define DisplayInversionOff (0x20) //No Parameter
#define DisplayInversionOn (0x21) //No Parameter
#define DisplayOff (0x28) //No Parameter
#define DisplayOn (0x29) //No Parameter
#define ColumnAddressSet (0x2A) //need to send 4 Bytes Column Address
#define RowAddressSet (0x2B) //need to send 4 Bytes Row Address
#define MemoryWrite (0x2C) //need to send data from MCU to frame memory
#define MemoryRead (0x2E) //n Parameter from frame memory to MCU
#define MemoryDataAccessControl (0x36) //need to send one Byte to d defines read/ write scanning direction of frame memory
#define IdleModeOff (0x38) //No Parameter
#define IdleModeOn (0x39) //No Parameter
#define InterfacePixelFormat (0x3A) //need to send 1 Byte to define the format of RGB picture data
typedef struct DisplayDev{
char *name; //名字
void *FBBase; //显存
unsigned short Xre; //x方向分辨率
unsigned short Yre; //y方向分辨率
unsigned int dsize; //显存的数据个数
unsigned short Bpp; //数据格式(12/16/18位)
int (*Init)(struct DisplayDev *ptd); //初始化
int (*ShowOn)(void); //开启显示
int (*ShowOff)(void); //关闭显示
int (*SetWindows)(struct DisplayDev *ptd,unsigned short Xs,unsigned short Xe,
unsigned short Ys,unsigned short Ye); //设置窗口显示
int (*SetPixel)(struct DisplayDev *ptd,unsigned short wx,unsigned short wy,unsigned short color); //设置显示的像素格式
int (*Flush)(struct DisplayDev *ptd); //将显存FBBase中的数据写到st7789中
}DisplayDevice;
DisplayDevice *GetST7789V2_Addr(void);
void Display_Clear(unsigned short color);
#endif
2.5 drv_st7789.c
#include "drv_st7789.h"
#include "drv_spi.h"
#include "gpio.h"
#include "errno.h"
#include <stdio.h>
static int WriteCommandNoAck(unsigned char cmd);
static int WriteCommandAck(unsigned char cmd);
static int WriteData(unsigned char *wbuf,unsigned int length);
static int ReadData(unsigned char *rbuf,unsigned int length);
static int MemdataAccessControl(unsigned char mode);
static int SetPixelFormat(unsigned char data);
static int ST7789_Init(struct DisplayDev *ptd);
static int ST7789_ShowOn(void);
static int ST7789_ShowOff(void);
static int ST7789_SetWindows(struct DisplayDev *ptd,unsigned short Xs,unsigned short Xe,
unsigned short Ys,unsigned short Ye);
static int ST7789_SetPixel(struct DisplayDev *ptd,unsigned short wx,unsigned short wy,unsigned short color);
static int ST7789_Flush(struct DisplayDev *ptd);
static DisplayDevice st7789v2 = {
.name = "st7789v2",
.FBBase = NULL,
.Xre = 240,
.Yre = 360,
.dsize = 0,
.Bpp = 16,
.Init = ST7789_Init,
.ShowOn = ST7789_ShowOn,
.ShowOff = ST7789_ShowOff,
.SetWindows = ST7789_SetWindows,
.SetPixel = ST7789_SetPixel,
.Flush = ST7789_Flush
};
/* 获取st7789v2的结构体地址 */
DisplayDevice *GetST7789V2_Addr(void)
{
return &st7789v2;
}
/* 清屏函数 */
void Display_Clear(unsigned short color)
{
unsigned short xbuf[240] = {0};
for(unsigned char i=0;i<240;i++)
{
xbuf[i] = color;
}
st7789v2.FBBase = (unsigned short *)xbuf;
for(unsigned short i=0;i<320;i++)
{
st7789v2.SetWindows(&st7789v2,0,240,i,i+1);
st7789v2.Flush(&st7789v2);
}
}
/* 无返回值且发送之后无需发数据的命令用这个写寄存器的函数 */
static int WriteCommandNoAck(unsigned char cmd)
{
Write_7789_CS(0);
Write_7789_DCX(0);
int ret = SPI_TransmitData(&cmd,1);
Write_7789_DCX(1);
Write_7789_CS(1);
if(ret != 1) return -EIO;
return ESUCCESS;
}
/* 有返回值或者要接着发送数据的命令用这个写寄存器的函数 */
static int WriteCommandAck(unsigned char cmd)
{
Write_7789_DCX(0);
int ret = SPI_TransmitData(&cmd,1);
Write_7789_DCX(1);
if(ret != 1) return -EIO;
return ESUCCESS;
}
/* 写入数据函数 */
static int WriteData(unsigned char *wbuf,unsigned int length)
{
int ret = SPI_TransmitData(wbuf,length);
if(ret != length) return -EIO;
return (int)length;
}
/* 读取数据函数 */
static int ReadData(unsigned char *rbuf,unsigned int length)
{
int ret = SPI_ReceiveData(rbuf,length);
if(ret != length) return -EIO;
return (int)length;
}
/* ST7789V2硬件复位 */
static int HardWareReset(void)
{
Write_7789_RST(0); //显示屏RST引脚低电平复位
HAL_Delay(150); //复位时间需大于120ms
Write_7789_RST(1);
HAL_Delay(5); //复位后需间隔5ms才能进行通信
return ESUCCESS;
}
/* 读显示屏ID */
static int ReaddisplayID(void)
{
unsigned int ID = 0;
unsigned char data[4] = {0};
Write_7789_CS(0);
WriteCommandAck(ReadDisplayID);
ReadData(data,4);
Write_7789_CS(1);
ID = (data[1] << 16) | (data[2] << 8) | (data[3]);
return (int)ID;
}
/* 显存数据访问控制 */
static int MemdataAccessControl(unsigned char mode)
{
Write_7789_CS(0);
/* 假设传进来的命令是0x00,就是将显示屏设置为从左到右,从上到下显示
数据地址是x++,x加完一行了,y加1,x变成0开始继续下一行的x地址++ */
WriteCommandAck(MemoryDataAccessControl);
int ret = WriteData(&mode,1);
Write_7789_CS(1);
if(ret != 1) return -EIO;
return ESUCCESS;
}
/* ST7789V2初始化 */
static int ST7789_Init(struct DisplayDev *ptd)
{
if(NULL == ptd) return -EINVAL;
// unsigned id = ReaddisplayID(); //读取显示屏ID
// printf("ST7789V2 ID:0x%x\r\n",id);
Write_7789_BACK(0); //开启显示屏背光
/* 1.硬件复位 */
if(HardWareReset() != ESUCCESS) return -EIO;
/* 2.退出睡眠模式 */
if(WriteCommandNoAck(SleepIOut) != ESUCCESS) return -EIO;
/* 3.设置为正常显示模式 */
if(WriteCommandNoAck(NormalDisplayModeOn) != ESUCCESS) return -EIO;
/* 4.关闭反转显示,即如果是数据0显示白色时,开启反转则数据1显示白色 */
if(WriteCommandNoAck(DisplayInversionOff) != ESUCCESS) return -EIO;
/* 5.设置显示格式为从左到右,从上到下,地址x自增等 */
if(MemdataAccessControl(0x00) != ESUCCESS) return -EIO;
/* 6.设置像素格式为16-bit/pixel: RGB=(565) */
if(SetPixelFormat(16) != ESUCCESS) return -EIO;
/* 7.开启显示 */
if(WriteCommandNoAck(DisplayOn) != ESUCCESS) return -EIO;
return ESUCCESS;
}
/* ST7789V2开显示 */
static int ST7789_ShowOn(void)
{
int ret = WriteCommandNoAck(DisplayOn);
if(ret != ESUCCESS) return -EIO;
return ESUCCESS;
}
/* ST7789V2关显示 */
static int ST7789_ShowOff(void)
{
int ret = WriteCommandNoAck(DisplayOff);
if(ret != ESUCCESS) return -EIO;
return ESUCCESS;
}
/* ST7789V2设置窗口显示 */
static int ST7789_SetWindows(struct DisplayDev *ptd,unsigned short Xs,unsigned short Xe,
unsigned short Ys,unsigned short Ye)
{
if(NULL == ptd) return -EINVAL;
/* 假如我们设置x的范围为0-8,那x分辨率就是0-8,也就是有9位了,但分辨率都是8的倍数,
9-1=8就是8的倍数了,所以这里先减一再将数据发送给ST7789 */
unsigned short wXe = Xe - 1;
unsigned short wYe = Ye - 1;
unsigned char xbuf[4] = {Xs >> 8, Xs, wXe >> 8 , wXe};
unsigned char ybuf[4] = {Ys >> 8, Ys, wYe >> 8 , wYe};
Write_7789_CS(0);
/* 先发送写入x坐标地址的命令 */
if(ESUCCESS != WriteCommandAck(ColumnAddressSet)) return -EIO;
/* 发送x坐标地址顺序:先发送16位的x起始地址,高位在前,同理再发送x结束地址 */
if(WriteData(xbuf,4) != 4) return -EIO;
/* 发送写入y坐标地址的命令 */
if(ESUCCESS != WriteCommandAck(RowAddressSet)) return -EIO;
/* 发送y坐标地址顺序:先发送16位的y起始地址,高位在前,同理再发送y结束地址 */
if(WriteData(ybuf,4) != 4) return -EIO;
Write_7789_CS(1);
/* 假如传进来的x坐标起始结束地址为0和8,y坐标起始结束地址为0和16 */
ptd->Xre = Xe - Xs; //计算x轴分辨率,这时还是用传进来的值:8-0才等于8(分辨率才是8的倍数)
ptd->Yre = Ye - Ys; //计算y轴分辨率,这时还是用传进来的值:16-0才等于16(分辨率才是16的倍数)
ptd->dsize = ptd->Xre * ptd->Yre * ptd->Bpp/8;//计算显存的数据个数,Bpp表示显存中一个数据有多少位
return ESUCCESS;
}
/* 设置ST7789V2的显示像素格式 */
static int SetPixelFormat(unsigned char data)
{
unsigned char format = 0x55;
if(data == 12)
{
/* 0x53表示12-bit/pixel: RGB=( ) */
format = 0x53;
}
else if(data == 16)
{
/* 0x55表示16-bit/pixel: RGB=(565) */
format = 0x55;
}
else if(data == 18)
{
/* 0x66表示18-bit/pixel: RGB=(666) */
format = 0x66;
}
Write_7789_CS(0);
WriteCommandAck(InterfacePixelFormat);
int ret = WriteData(&format,1);
Write_7789_CS(1);
if(ret != 1) return -EIO;
return ESUCCESS;
}
/* 将显存FBBase中的数据写入到ST7789V2 */
static int ST7789_Flush(struct DisplayDev *ptd)
{
if(NULL == ptd) return -ENODEV;
if(NULL == ptd->FBBase) return -ENODEV;
Write_7789_CS(0);
WriteCommandAck(MemoryWrite);
int ret = WriteData(ptd->FBBase,ptd->dsize);
Write_7789_CS(1);
if(ret != ptd->dsize) return -EIO;
return ESUCCESS;
}
/* 设置ST7789单个像素点的颜色 */
static int ST7789_SetPixel(struct DisplayDev *ptd,unsigned short wx,unsigned short wy,unsigned short color)
{
if(NULL == ptd) return -ENODEV;
unsigned short *buf = (unsigned short *)ptd->FBBase;
buf += wy * ptd->Xre + wx;
*buf = color;
return ESUCCESS;
}
2.6 ascii.c
将字模提取软件生成的ASCII字库放进来,并把生成的16*16和32*32位的汉字字库也放进来,再写对应的接口函数
/* ascii字库 */
static unsigned char ascii[128][16] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",2*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",3*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",4*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",5*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",6*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",7*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",8*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",9*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",10*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",11*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",12*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",13*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",14*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",15*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",16*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",17*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",18*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",19*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",20*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",21*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",22*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",23*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",24*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",25*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",26*/
{0x00,0xFE,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x00,0x00},/*" ",27*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",28*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",29*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",30*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"", 31*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",32*/
{0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x08,0x08,0x00,0x00},/*"!",33*/
{0x00,0x48,0x24,0x24,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",34*/
{0x00,0x00,0x00,0x48,0x48,0x48,0x7E,0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x00,0x00},/*"#",35*/
{0x00,0x00,0x10,0x3C,0x52,0x52,0x12,0x1C,0x30,0x50,0x50,0x52,0x52,0x3C,0x10,0x10},/*"$",36*/
{0x00,0x00,0x00,0x22,0x25,0x15,0x15,0x0D,0x2A,0x58,0x54,0x54,0x52,0x22,0x00,0x00},/*"%",37*/
{0x00,0x00,0x00,0x0C,0x12,0x12,0x12,0x0A,0x76,0x25,0x29,0x19,0x91,0x6E,0x00,0x00},/*"&",38*/
{0x00,0x06,0x04,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",39*/
{0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00},/*"(",40*/
{0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00},/*")",41*/
{0x00,0x00,0x00,0x00,0x08,0x08,0x6B,0x1C,0x1C,0x6B,0x08,0x08,0x00,0x00,0x00,0x00},/*"*",42*/
{0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x00,0x00,0x00,0x00},/*"+",43*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x04,0x04,0x02},/*",",44*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"-",45*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x06,0x00,0x00},/*".",46*/
{0x00,0x00,0x40,0x20,0x20,0x20,0x10,0x10,0x08,0x08,0x08,0x04,0x04,0x02,0x02,0x00},/*"/",47*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},/*"0",48*/
{0x00,0x00,0x00,0x10,0x1C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00},/*"1",49*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x40,0x20,0x10,0x08,0x04,0x42,0x7E,0x00,0x00},/*"2",50*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x40,0x20,0x18,0x20,0x40,0x42,0x42,0x3C,0x00,0x00},/*"3",51*/
{0x00,0x00,0x00,0x20,0x30,0x30,0x28,0x24,0x24,0x22,0xFE,0x20,0x20,0xF8,0x00,0x00},/*"4",52*/
{0x00,0x00,0x00,0x7E,0x02,0x02,0x02,0x1E,0x22,0x40,0x40,0x42,0x22,0x1C,0x00,0x00},/*"5",53*/
{0x00,0x00,0x00,0x18,0x24,0x02,0x02,0x3A,0x46,0x42,0x42,0x42,0x44,0x38,0x00,0x00},/*"6",54*/
{0x00,0x00,0x00,0x7E,0x42,0x20,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x00,0x00},/*"7",55*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},/*"8",56*/
{0x00,0x00,0x00,0x1C,0x22,0x42,0x42,0x42,0x62,0x5C,0x40,0x40,0x24,0x18,0x00,0x00},/*"9",57*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00},/*":",58*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08},/*";",59*/
{0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00},/*"<",60*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00},/*"=",61*/
{0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00},/*">",62*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x46,0x20,0x10,0x10,0x10,0x00,0x18,0x18,0x00,0x00},/*"?",63*/
{0x00,0x00,0x00,0x1C,0x22,0x5A,0x55,0x55,0x55,0x55,0x55,0x3A,0x42,0x3C,0x00,0x00},/*"@",64*/
{0x00,0x00,0x00,0x08,0x08,0x18,0x14,0x14,0x24,0x3C,0x22,0x42,0x42,0xE7,0x00,0x00},/*"A",65*/
{0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x1E,0x22,0x42,0x42,0x42,0x22,0x1F,0x00,0x00},/*"B",66*/
{0x00,0x00,0x00,0x7C,0x42,0x42,0x01,0x01,0x01,0x01,0x01,0x42,0x22,0x1C,0x00,0x00},/*"C",67*/
{0x00,0x00,0x00,0x1F,0x22,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1F,0x00,0x00},/*"D",68*/
{0x00,0x00,0x00,0x3F,0x42,0x12,0x12,0x1E,0x12,0x12,0x02,0x42,0x42,0x3F,0x00,0x00},/*"E",69*/
{0x00,0x00,0x00,0x3F,0x42,0x12,0x12,0x1E,0x12,0x12,0x02,0x02,0x02,0x07,0x00,0x00},/*"F",70*/
{0x00,0x00,0x00,0x3C,0x22,0x22,0x01,0x01,0x01,0x71,0x21,0x22,0x22,0x1C,0x00,0x00},/*"G",71*/
{0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00},/*"H",72*/
{0x00,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"I",73*/
{0x00,0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x0F},/*"J",74*/
{0x00,0x00,0x00,0x77,0x22,0x12,0x0A,0x0E,0x0A,0x12,0x12,0x22,0x22,0x77,0x00,0x00},/*"K",75*/
{0x00,0x00,0x00,0x07,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x42,0x7F,0x00,0x00},/*"L",76*/
{0x00,0x00,0x00,0x77,0x36,0x36,0x36,0x36,0x36,0x2A,0x2A,0x2A,0x2A,0x6B,0x00,0x00},/*"M",77*/
{0x00,0x00,0x00,0xE3,0x46,0x46,0x4A,0x4A,0x52,0x52,0x52,0x62,0x62,0x47,0x00,0x00},/*"N",78*/
{0x00,0x00,0x00,0x1C,0x22,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x22,0x1C,0x00,0x00},/*"O",79*/
{0x00,0x00,0x00,0x3F,0x42,0x42,0x42,0x42,0x3E,0x02,0x02,0x02,0x02,0x07,0x00,0x00},/*"P",80*/
{0x00,0x00,0x00,0x1C,0x22,0x41,0x41,0x41,0x41,0x41,0x41,0x4D,0x32,0x1C,0x60,0x00},/*"Q",81*/
{0x00,0x00,0x00,0x3F,0x42,0x42,0x42,0x3E,0x12,0x12,0x22,0x22,0x42,0xC7,0x00,0x00},/*"R",82*/
{0x00,0x00,0x00,0x7C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x42,0x42,0x3E,0x00,0x00},/*"S",83*/
{0x00,0x00,0x00,0x7F,0x49,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00},/*"T",84*/
{0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00},/*"U",85*/
{0x00,0x00,0x00,0xE7,0x42,0x42,0x22,0x24,0x24,0x14,0x14,0x18,0x08,0x08,0x00,0x00},/*"V",86*/
{0x00,0x00,0x00,0x6B,0x2A,0x2A,0x2A,0x2A,0x2A,0x36,0x14,0x14,0x14,0x14,0x00,0x00},/*"W",87*/
{0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xE7,0x00,0x00},/*"X",88*/
{0x00,0x00,0x00,0x77,0x22,0x22,0x14,0x14,0x08,0x08,0x08,0x08,0x08,0x1C,0x00,0x00},/*"Y",89*/
{0x00,0x00,0x00,0x7E,0x21,0x20,0x10,0x10,0x08,0x04,0x04,0x42,0x42,0x3F,0x00,0x00},/*"Z",90*/
{0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00},/*"[",91*/
{0x00,0x00,0x02,0x04,0x04,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x40,0x40},/*"\",92*/
{0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00},/*"]",93*/
{0x00,0x18,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",94*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF},/*"_",95*/
{0x00,0x06,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",96*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x30,0x2C,0x22,0x32,0x6C,0x00,0x00},/*"a",97*/
{0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x1A,0x26,0x42,0x42,0x42,0x26,0x1A,0x00,0x00},/*"b",98*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x02,0x02,0x02,0x44,0x38,0x00,0x00},/*"c",99*/
{0x00,0x00,0x00,0x00,0x60,0x40,0x40,0x7C,0x42,0x42,0x42,0x42,0x62,0xDC,0x00,0x00},/*"d",100*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x02,0x42,0x3C,0x00,0x00},/*"e",101*/
{0x00,0x00,0x00,0x00,0x30,0x48,0x08,0x3E,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"f",102*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x22,0x22,0x1C,0x02,0x3C,0x42,0x42,0x3C},/*"g",103*/
{0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x3A,0x46,0x42,0x42,0x42,0x42,0xE7,0x00,0x00},/*"h",104*/
{0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x0E,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"i",105*/
{0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x1E},/*"j",106*/
{0x00,0x00,0x00,0x00,0x03,0x02,0x02,0x72,0x12,0x0A,0x0E,0x12,0x22,0x77,0x00,0x00},/*"k",107*/
{0x00,0x00,0x00,0x08,0x0E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},/*"l",108*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x92,0x92,0x92,0x92,0x92,0xB7,0x00,0x00},/*"m",109*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x46,0x42,0x42,0x42,0x42,0xE7,0x00,0x00},/*"n",110*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00},/*"o",111*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x26,0x42,0x42,0x42,0x26,0x1A,0x02,0x07},/*"p",112*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x64,0x42,0x42,0x42,0x64,0x58,0x40,0xE0},/*"q",113*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x4C,0x04,0x04,0x04,0x04,0x1F,0x00,0x00},/*"r",114*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x42,0x02,0x3C,0x40,0x42,0x3E,0x00,0x00},/*"s",115*/
{0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x3E,0x08,0x08,0x08,0x08,0x48,0x30,0x00,0x00},/*"t",116*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x42,0x42,0x42,0x42,0x62,0xDC,0x00,0x00},/*"u",117*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00},/*"v",118*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x91,0x52,0x5A,0x2A,0x24,0x24,0x00,0x00},/*"w",119*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x24,0x18,0x18,0x18,0x24,0x76,0x00,0x00},/*"x",120*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x08,0x08,0x06},/*"y",121*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x22,0x10,0x08,0x08,0x44,0x7E,0x00,0x00},/*"z",122*/
{0x00,0xC0,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x20,0xC0,0x00},/*"{",123*/
{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},/*"|",124*/
{0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x04,0x04,0x04,0x04,0x04,0x03,0x00},/*"}",125*/
{0x04,0x5A,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",126*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/*" ",127*/
};
/* 16*16汉字字库 */
unsigned char xiaochijing[6][16] = {
{0x00,0x02,0x04,0x04,0xE0,0x20,0x28,0x28,0x24,0x27,0xE4,0x24,0x04,0x04,0x04,0x00},
{0x02,0x02,0x02,0x02,0x3F,0x22,0x22,0x22,0x22,0x22,0x3F,0x22,0x02,0x02,0x02,0x02},/*"冲",0*/
{0x10,0x10,0x10,0xF8,0x88,0x84,0x82,0x80,0xFF,0x80,0x40,0x40,0x20,0x10,0x0C,0x03},
{0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x01,0x02,0x04,0x18,0x60},/*"矢",1*/
{0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0x30,0x0E,0x22,0x22,0x3A,0x26,0x12,0x08,0x06},
{0x00,0x0F,0x08,0x0F,0x08,0x0F,0x00,0x00,0x3F,0x21,0x21,0x21,0x29,0x11,0x01,0x01},/*"昴",2*/
};
/* 32*32汉字字库 */
unsigned char dachijing[16][32] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x80,0x80,0xC0,0x40,0x60,0x30,0x10,0x08,0x04,0x00,0x80,0xC0,0x20,0x18,0x00},
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0xFF,0x80,0x80,0x80,0x80,0x80,0xFF,0x30,0x30,0x31,0x33,0x31,0x30,0x18,0x18,0x18,0x0C,0x0C,0x06,0x03,0x01,0x80,0x00,0x00,0x00},
{0x00,0x00,0x01,0x03,0x01,0x01,0x01,0xFF,0x01,0x01,0x01,0x01,0x01,0xFF,0x18,0x18,0x58,0x98,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x1E,0x0C,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x00,0x00,0x00,0x00,0x30,0x7F,0x00,0x00,0x00,0x00,0x03,0x06,0x0C,0x1C,0x18,0x18,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"赤",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x18,0x04,0x00},
{0x00,0x00,0x08,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x08,0x08,0x0C,0x0C,0x0C,0x06,0x06,0x03,0x01,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x08,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"井",1*/
{0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x20,0x18,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x30,0x08,0x00},
{0x00,0x00,0x00,0x00,0xFF,0x80,0x80,0x80,0xFF,0xE0,0xB0,0x98,0x8C,0x86,0x83,0x80,0x00,0xFF,0x30,0x10,0x18,0x18,0x18,0x0C,0x0C,0x06,0x03,0x01,0x00,0x00,0x00,0x00},
{0x00,0x00,0x80,0xFE,0x03,0x01,0x01,0x01,0xFF,0x05,0x09,0x11,0x21,0xC1,0x81,0x00,0x10,0x3F,0x18,0x18,0x0C,0xFE,0x04,0x00,0x00,0x00,0x80,0x82,0xFC,0xF0,0x20,0x00},
{0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x18,0x3F,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x3C,0x08,0x00,0x00,0x02,0x07,0x03,0x03,0x03,0x01,0x01,0x01,0x01,0x00,0x00,0x00},/*"秀",2*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"一",3*/
};
unsigned char *GetASCIIBuffer(const char c)
{
return &ascii[c][0];
}
unsigned char *GetxiaochiAddr(unsigned char addr)
{
return &xiaochijing[addr][0];
}
unsigned char *GetdachiAddr(unsigned char addr)
{
return &dachijing[addr][0];
}
2.7 font.c
#include "font.h"
#include "drv_st7789.h"
#include<string.h>
/* 显示8**16的单个ASCII字符函数 */
void ShowChar(char c,unsigned short x,unsigned short y,unsigned short color)
{
DisplayDevice *st7789 = GetST7789V2_Addr();
st7789->SetWindows(st7789,x,x+8,y,y+16);
unsigned short wbuf[128] = {0};
st7789->FBBase = (unsigned short *)wbuf;
unsigned char *fbuf = GetASCIIBuffer(c);
unsigned char i =0;
for(unsigned char y=0;y<16;y++)
{
for(unsigned char x=0;x<8;x++)
{
if((fbuf[y] & (0x01 << x)) != 0)
wbuf[i] = color;
// st7789->SetPixel(st7789,x,y,color);
else
wbuf[i] = ~color;
// st7789->SetPixel(st7789,x,y,~color);
i++;
}
}
st7789->Flush(st7789);
}
/* 显示多个ASCII字符函数 */
void ShowString(char *wbuf,unsigned short x,unsigned short y,unsigned short color)
{
if(NULL == wbuf) return;
while(*wbuf != 0)
{
ShowChar(*wbuf,x,y,color);
x += 8;
if(x>240)
{
x = 0;
y++;
if(y > 320)
y = 0;
}
wbuf++;
}
}
/* 显示半个16*16的汉字函数 */
void ShowChinese16Half(unsigned char data,unsigned short x,unsigned short y,unsigned short color)
{
DisplayDevice *st7789 = GetST7789V2_Addr();
st7789->SetWindows(st7789,x,x+8,y,y+16);
unsigned short wbuf[128] = {0};
st7789->FBBase = (unsigned short *)wbuf;
unsigned char *buf = GetxiaochiAddr(data);
unsigned char i = 0;
for(unsigned char y=0;y<16;y++)
{
for(unsigned char x=0;x<8;x++)
{
if((*buf & (0x01 << x)) != 0)
wbuf[i] = color;
else
wbuf[i] = ~color;
i++;
}
buf++;
}
st7789->Flush(st7789);
}
/* 显示1/4个32*32的汉字函数 */
void ShowChinese32Quarter(unsigned char data,unsigned short x,unsigned short y,unsigned short color)
{
DisplayDevice *st7789 = GetST7789V2_Addr();
st7789->SetWindows(st7789,x,x+8,y,y+32);
unsigned short wbuf[256] = {0};
st7789->FBBase = (unsigned short *)wbuf;
unsigned char *buf = GetdachiAddr(data);
unsigned char i = 0;
for(unsigned char y=0;y<32;y++)
{
for(unsigned char x=0;x<8;x++)
{
if((*buf & (0x01 << x)) != 0)
wbuf[i] = color;
else
wbuf[i] = ~color;
i++;
}
buf++;
}
st7789->Flush(st7789);
}
2.8 font.h
#ifndef __FONT_LIB_H
#define __FONT_LIB_H
unsigned char *GetASCIIBuffer(const char c);
unsigned char *GetxiaochiAddr(unsigned char addr);
unsigned char *GetdachiAddr(unsigned char addr);
void ShowChar( char c,unsigned short x,unsigned short y,unsigned short color);
void ShowString(char *wbuf,unsigned short x,unsigned short y,unsigned short color);
void ShowChinese16Half(unsigned char data,unsigned short x,unsigned short y,unsigned short color);
void ShowChinese32Quarter(unsigned char data,unsigned short x,unsigned short y,unsigned short color);
#endif
2.9 app_st7789_test.c
将里面的测试函数声明后在主函数中调用
#include "stm32f4xx_hal.h"
#include "drv_st7789.h"
#include "errno.h"
#include "font.h"
#include "app.h"
void app_st7789_test(void)
{
DisplayDevice *st7789 = GetST7789V2_Addr();
int ret = st7789->Init(st7789);
if(ret != ESUCCESS) return;
Display_Clear(0xFFFF);
/* 从(0,0)开始显示字符串 */
ShowString("Hello World!",0,0,0X0000);
/* 从(0,16)开始显示字符串 */
ShowString("123456789",0,16,0x0000);
unsigned char ch = 96;
/* 从(96,48)开始显示汉字 */
for(int i=0;i<6;i++)
{
ShowChinese16Half(i,ch,48,0x0000);
ch += 8;
}
ch = 64;
/* 从(64,72)开始显示汉字 */
for(int i=0;i<16;i++)
{
ShowChinese32Quarter(i,ch,72,0x0000);
ch += 8;
}
while(1)
{
}
}
2.10 测试结果
如下图,按照我们的程序在指定位置显示了字符串和汉字