编译器说明
1. Toolchain : MDK-ARM Community Version: 5.36.0.0(Kile V5)
2. Encoding : Encode in UTF-8 without signature
3. Device Specific Packs : Keil.STM32F1xx_DFP.2.3.0.pack
4. C/C++ Preprocessor Symbols : STM32F10X_HD,USE_STDPERIPH_DRIVER
USE_STDPERIPH_DRIVER :允许使用标准外设驱动
STM32F10X_HD :STM32F10x大容量产品
5. Chip Type :ARM Cortex-M3 STM32F103RET6, 72MHZ, Flash:512KByte, ROM:64KByte, LQFP144
6. 在stm32hf10x.h文件中HSE_VALUE为外部高速振荡器,默认8MHZ。此值必须与硬件保持一致。
例程说明
1. STM32F103xx OLED旋转显示图片。
2. 显示图片可实现0度旋转、90度旋转、180度旋转、270度旋转。
3. 提供两种图片取模方式的显示。
一、镜像显示说明
镜像前后图片显示的宽和高保持不变
不管何种镜像方式显示,图片的横坐标都要完全显示
不管何种镜像方式显示,需要先处理完一列的纵坐标,然后再处理横坐标
当图片的高度不为8的整数倍时,只需要显示完图片的实际高度即可,多余部分不用显示
原图显示原理。先显示完第一列,在显示第二例,依次类推直到最后一列;先显示第一列第一个像素,然后纵坐标加1,显示第一列第二个像素,依次类推直到显示完第一列最后一个像素;然后横坐标加一,纵坐标回归原始值,开始显示第二列第一个像素,显示第二列第二个像素,依次类推直到显示完第二列最后一个像素,按照此规律显示完最后一列最后一个像素。
二、旋转显示说明
横轴为图片实际宽度,纵轴为图片显示宽度,图片显示宽度大于等于图片实际宽度。
按列显示,先显示第一列,在显示第二列,以此类推,每显示列中的一个像素纵轴加一,横轴不变,直到纵轴加的数量等于图片显示宽度为止,然后横轴加一,纵轴重设为初始值,开始显示第二列,依次类推,直到显示完最后一列。
90度显示 :纵轴为图片实际高度,横轴为图片显示宽度,图片显示宽度大于等于图片实际宽度。行显示,先显示第一行,在显示第二行,以此类推,每显示行中的一个像素横轴加一,纵轴不变,直到横轴加的数量等于图片显示宽度为止,然后纵轴加一,横轴重设为初始值,开始显示第二行,依次类推,直到显示完最后一行。
三、数据结构和宏定义
/* 液晶显示方向 (0)竖屏 (1)横屏 */
#define LCD_SHOW_DIR (0)
#if ( LCD_SHOW_DIR == 0 )
#define LCD_PHY_SIZE_WIDTH_MAX (320)
#define LCD_PHY_SIZE_HEIGHT_MAX (480)
#else
#define LCD_PHY_SIZE_WIDTH_MAX (480)
#define LCD_PHY_SIZE_HEIGHT_MAX (320)
#endif
/* 镜像模式 */
typedef enum
{
MIR_MODE_NORMAL = 0, /* 正常模式(0度) */
MIR_MODE_LEFT_RIGHT = 1, /* 左右镜像(90度) */
MIR_MODE_LEFT_RIGHT_UP_DOWN = 2, /* 左右上下镜像(180度) */
MIR_MODE_UP_DOWN = 3, /* 上下镜像(270度) */
MIR_MODE_MAX
}eMirrorMode;
/* 旋转模式 */
typedef enum
{
ROTAT_MODE_DEG_0 = 0, /* 旋转0度 */
ROTAT_MODE_DEG_90 = 1, /* 旋转90度 */
ROTAT_MODE_DEG_180 = 2, /* 旋转180度 */
ROTAT_MODE_DEG_270 = 3, /* 旋转270度 */
ROTAT_MODE_MAX
}eRotateMode;
/* 显示模式 */
typedef enum
{
DIS_MODE_NORMAL = 0, /* 正常模式 */
DIS_MODE_OPPOSITE = 1, /* 反显示 */
DIS_MODE_MAX
}eDisMode;
/* 字节对齐 */
#pragma pack(1)
typedef struct app_lcd
{
u16 xWidth; /* 宽度 */
u16 yHeight; /* 高度 */
u32 ID; /* ID */
u8 ShowDir; /* 显示方向 */
u16 BackColor; /* 背景色 */
u16 ForeColor; /* 前景色 */
eDisMode DisplayMode; /* 显示模式 */
eMirrorMode MirrorMode; /* 镜像模式 */
eRotateMode RotateMode; /* 旋转模式 */
}LCD_DeviceTypeDef, * pLCD_DeviceTypeDef, * LCD_DeviceTypeDef_t, pLCD_DeviceTypeDef_t;
#pragma pack()
LCD_DeviceTypeDef AppDevLCD =
{
.xWidth = LCD_PHY_SIZE_WIDTH_MAX,
.yHeight = LCD_PHY_SIZE_HEIGHT_MAX,
.ID = 0,
.ShowDir = LCD_SHOW_DIR,
.BackColor = WHITE,
.ForeColor = BLACK,
.DisplayMode = DIS_MODE_NORMAL,
.MirrorMode = MIR_MODE_NORMAL,
.RotateMode = ROTAT_MODE_DEG_0
};
四、显示的ASCII、中文、图片点阵库
ASCII点阵库
/****************************************************************************************************
(0) !(1) "(2) #(3) $(4) %(5) &(6) '(7) ((8) )(9) *(10) +(11) ,(12) -(13) .(14) /(15)
0(16) 1(17) 2(18) 3(19) 4(20) 5(21) 6(22) 7(23) 8(24) 9(25) :(26) ;(27) <(28) =(29) >(30) ?(31)
@(32) A(33) B(34) C(35) D(36) E(37) F(38) G(39) H(40) I(41) J(42) K(43) L(44) M(45) N(46) O(47)
P(48) Q(49) R(50) S(51) T(52) U(53) V(54) W(55) X(56) Y(57) Z(58) [(59) \(60) ](61) ^(62) _(63)
`(64) a(65) b(66) c(67) d(68) e(69) f(70) g(71) h(72) i(73) j(74) k(75) l(76) m(77) n(78) o(79)
p(80) q(81) r(82) s(83) t(84) u(85) v(86) w(87) x(88) y(89) z(90) {(91) |(92) }(93) ~(94)
* ASCII常规字符集:
* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
*
* 1. PCtoLCD2018.exe : 宋体 + 阴码 + 逐列式 + 逆向(低位在前) + C51格式 + 等比缩放
* 2. 英文长宽点阵集(6x12),字宽(12),字高(12)
****************************************************************************************************/
const unsigned char ASCII_FONT_1206[95][12] =
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x7C,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x03,0x00,0x00,0x00},/*""",2*/
{0x90,0x00,0xFC,0x03,0x90,0x00,0xFC,0x03,0x90,0x00,0x00,0x00},/*"#",3*/
{0x18,0x01,0x24,0x02,0xFE,0x07,0x44,0x02,0x88,0x01,0x00,0x00},/*"$",4*/
{0x38,0x00,0x44,0x03,0xF8,0x00,0xD0,0x01,0x2C,0x02,0xC0,0x01},/*"%",5*/
{0xC0,0x01,0x38,0x02,0xE4,0x02,0x18,0x01,0xE0,0x02,0x20,0x01},/*"&",6*/
..............................
};
/****************************************************************************************************
* ASCII常规字符集:
* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
*
* 1. PCtoLCD2018.exe : 宋体 + 阴码 + 逐列式 + 逆向(低位在前) + C51格式 + 等比缩放
* 2. 英文长宽点阵集(6x16),字宽(16),字高(16)
****************************************************************************************************/
const unsigned char ASCII_FONT_1608[95][16] =
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x10,0x00,0x0C,0x00,0x02,0x00,0x10,0x00,0x0C,0x00,0x02,0x00,0x00,0x00},/*""",2*/
..............................
};
/****************************************************************************************************
* ASCII常规字符集:
* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
*
* 1. PCtoLCD2018.exe : 宋体 + 阴码 + 逐列式 + 逆向(低位在前) + C51格式 + 等比缩放
* 2. 英文长宽点阵集(12x24),字宽(24),字高(24)
****************************************************************************************************/
const unsigned char ASCII_FONT_2412[95][36] =
{
{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,0x00,0x00,0x00,0x00,0x00},/*" ",0*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x77,0x1C,0xF0,0x0F,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x60,0x00,0x00,0x30,0x00,0x00,0x1C,0x00,0x00,0x8C,0x00,0x00,0x60,0x00,0x00,0x30,0x00,0x00,0x1C,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00},/*""",2*/
..............................
};
中文点阵库
/* (16 X 16 , 宋体 ) */
const unsigned char ChineseDemo[10][54] =
{
// 岑(0) 凌(1) 盛(2) 羽(3) 汉(4) 字(5) 显(6) 示(7) 例(8) 程(9)
{0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x02,0x00,0x0E,0x02,0x00,0x08,0x01,0x00,0x08,0x05,0x00,0x88,0x04,0x00,0x48,0x04,0x00,0xB0,0x04,0x00,0x2F,0x07,0x00,0x48,0xC4,0x00,0x88,0x34,0x00,0x08,0x0D,0x00,0x08,0x01,0x00,0x1E,0x03,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"岑",0*/
{0x00,0x00,0x00,0x02,0x04,0x00,0x0C,0x7C,0x00,0x18,0x07,0x00,0xE0,0x00,0x01,0x38,0x22,0x01,0x20,0x11,0x01,0xA0,0x88,0x00,0x44,0x86,0x00,0x24,0x4B,0x00,0x3F,0x32,0x00,0x24,0x52,0x00,0x44,0xCC,0x00,0xA4,0x86,0x00,0xA4,0x80,0x00,0xA0,0x81,0x01,0x00,0x00,0x00,0x00,0x00,0x00},/*"凌",1*/
{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x86,0x00,0x80,0x81,0x00,0x7C,0xFC,0x00,0x24,0x84,0x00,0x24,0x86,0x00,0xC4,0xFB,0x00,0x24,0x86,0x00,0x04,0x85,0x00,0x1F,0xF9,0x00,0xE4,0x84,0x00,0xC5,0x84,0x00,0x36,0xFD,0x00,0x14,0x82,0x00,0x04,0x82,0x00,0x80,0x03,0x00,0x00,0x00,0x00},/*"盛",2*/
..............................
};
图片点阵库
//Img2Lcd.exe ==> 垂直扫描 + 单色 + 字节内像素数据反序(低位在前)
const unsigned char Image_Tree_43x47[258] =
{
0X00,0X00,0X00,0X80,0X00,0X00,0X00,0X00,0X00,0XC0,0X00,0X00,0X00,0X00,0X00,0XE0,
0X00,0X00,0X00,0X00,0X20,0XF0,0X00,0X00,0X00,0X00,0X30,0XF8,0X00,0X00,0X00,0X00,
0X38,0XFC,0X00,0X00,0X00,0X08,0X3C,0XFE,0X00,0X00,0X00,0X0C,0X3E,0XFF,0X00,0X00,
0X00,0X0E,0XBF,0XFF,0X00,0X00,0X00,0X8F,0XFF,0XFF,0X00,0X00,0X80,0XCF,0XFF,0XFF,
..............................
};
//Img2Lcd.exe ==> 垂直扫描 + 单色 + 字节内像素数据反序(低位在前)
const unsigned char gImage_P2P_73x44[438] =
{
0X80,0X01,0X00,0X00,0X00,0X00,0XE0,0X01,0X00,0X00,0X00,0X00,0X78,0X00,0X00,0X00,
0X00,0X00,0X3C,0X00,0X00,0X00,0X00,0X00,0X27,0X00,0X00,0X00,0X00,0X00,0X27,0X30,
0X00,0X00,0X00,0X00,0X3C,0X78,0X00,0X00,0X00,0X00,0X78,0XFC,0X00,0X00,0X00,0X00,
0XE0,0XFD,0X00,0X00,0X00,0X00,0X80,0X79,0X00,0X00,0X00,0X00,0X00,0X30,0X00,0X00,
..............................
};
五、显示公共函数
/* 加操作 */
static void vHandler_Inc(u16 * pDat, u8 n)
{
*pDat += n;
}
/* 减操作 */
static void vHandler_Sub(u16 * pDat, u8 n)
{
*pDat -= n;
}
/* 获取字符数据源地址 */
static void vGet_CharSrc(u8 chr, u8 charSize, u8 ** pSrc)
{
switch (charSize)
{
case ASCII_FONT_TYPE_1206 :
*pSrc = (u8 *)(&ASCII_FONT_1206[chr - ' ']);
break;
case ASCII_FONT_TYPE_1608 :
*pSrc = (u8 *)(&ASCII_FONT_1608[chr - ' ']);
break;
case ASCII_FONT_TYPE_2412 :
*pSrc = (u8 *)(&ASCII_FONT_2412[chr - ' ']);
break;
default: *pSrc = NULL; break;
}
}
六、显示ASCII常规字符串
/* 显示字符 */
static void vTFT_Display_Char(u16 x, u16 y, u8 chr, u8 charSize, eDisMode disMode)
{
u8 charByte = 0, k = 0, i = 0;
u8 dat = 0, * pSrcDat = NULL;
u16 y0 = 0;
//获取字符数据源地址
vGet_CharSrc(chr, charSize, &pSrcDat);
if (pSrcDat == NULL)
{
return;
}
y0 = y;// 原始纵坐标
// 字符点阵占用字节数
charByte = ((charSize >> 3) + ((charSize & 0x07) ? 1 : 0)) * (charSize >> 1);
// 遍历字符点阵数据
for(k = 0; k < charByte; ++k)
{
dat = pSrcDat[k];
for(i = 0; i < 8; ++i)
{
// 显示有效范围
if ((x < AppDevLCD.xWidth) && (y < AppDevLCD.yHeight))
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (disMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
}
y++;// 纵坐标自加
if (abs(y - y0) == charSize)//纵坐标偏移量等于字符点阵高度
{
y = y0;
x++;
break;
}
}
}
}
/* 显示字符串 */
void vTFT_Display_String(u16 x, u16 y, u8 * pStr, u8 strSize)
{
/* 显示模式越界 */
if (AppDevLCD.DisplayMode >= DIS_MODE_MAX)
{
return;
}
//显示ASCII常规字符
while ((*pStr >= ' ') && (*pStr <= '~'))
{
/* 剩余纵轴小于字体高度 */
if (y > (AppDevLCD.yHeight - strSize))
{
return;
}
/* 剩余的横纵小于字体宽度 换行显示 */
if (x > (AppDevLCD.xWidth - (strSize >> 1)))
{
y += strSize;
x = 0;
}
vTFT_Display_Char(x, y, *pStr, strSize, AppDevLCD.DisplayMode);
x += (strSize >> 1);
pStr++;
}
}
七、镜像显示公共函数/* 获取横纵轴的操作 */
static void vGet_xyHandler_Mirror(eMirrorMode mode, void (** xHand)(u16 * x, u8 n), void (** yHand)(u16 * y, u8 n))
{
switch (mode)
{
case MIR_MODE_NORMAL:
{
*xHand = &vHandler_Inc;
*yHand = &vHandler_Inc;
}
break;
case MIR_MODE_LEFT_RIGHT:
{
*xHand = &vHandler_Sub;
*yHand = &vHandler_Inc;
}
break;
case MIR_MODE_LEFT_RIGHT_UP_DOWN:
{
*xHand = &vHandler_Sub;
*yHand = &vHandler_Sub;
}
break;
case MIR_MODE_UP_DOWN:
{
*xHand = &vHandler_Inc;
*yHand = &vHandler_Sub;
}
break;
default: break;
}
}
八、显示ASCII常规字符串(带镜像)
/* 显示字符(带镜像) */
static void vTFT_DisplayChar_Mirror(u16 x, u16 y, u8 chr, u8 charSize, eDisMode disMode, eMirrorMode mirMode)
{
u8 charByte = 0, k = 0, i = 0;
u8 dat = 0, * pSrcDat = NULL;
void (* xHandler)(u16 * x0, u8 n) = NULL;
void (* yHandler)(u16 * y0, u8 n) = NULL;
u16 y0 = 0;
u8 count = 0;
//横纵坐标的操作
vGet_xyHandler_Mirror(mirMode, &xHandler, &yHandler);
//获取字符数据源地址
vGet_CharSrc(chr, charSize, &pSrcDat);
if (pSrcDat == NULL)
{
return;
}
//显示ASCII常规字符
y0 = y;
// 字符点阵占用字节数
charByte = ((charSize >> 3) + ((charSize & 0x07) ? 1 : 0)) * (charSize >> 1);
// 遍历字符点阵数据
for(k = 0; k < charByte; ++k)
{
dat = pSrcDat[k];
for(i = 0; i < 8; ++i)
{
// 显示有效范围
if ((x < AppDevLCD.xWidth) && (y < AppDevLCD.yHeight))
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (disMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
}
count++;
yHandler(&y, 1);//纵坐标处理
if (count == charSize)
{
y = y0;
count = 0;
xHandler(&x, 1);//横坐标处理
break;
}
}
}
}
/* 显示字符串(带镜像) */
void vTFT_DisplayString_Mirror(u16 x, u16 y, u8 * pStr, u8 strSize)
{
/* 显示模式越界 镜像模式越界 */
if ((AppDevLCD.DisplayMode >= DIS_MODE_MAX) || (AppDevLCD.MirrorMode >= MIR_MODE_MAX))
{
return;
}
//显示ASCII常规字符
while ((*pStr >= ' ') && (*pStr <= '~'))
{
/* 剩余纵轴小于字体高度 */
if (y > (AppDevLCD.yHeight - strSize))
{
return;
}
/* 剩余的横纵小于字体宽度 换行显示 */
if (x > (AppDevLCD.xWidth - (strSize >> 1)))
{
y += strSize;
x = 0;
}
vTFT_DisplayChar_Mirror(x, y, *pStr, strSize, AppDevLCD.DisplayMode, AppDevLCD.MirrorMode);
x += strSize >> 1;
pStr++;
}
}
九、旋转显示公共函数
/* 获取横纵轴的操作 */
static void vGet_xyHandler_Rotate(eRotateMode mode, void (** prevHand)(u16 * prev, u8 n), void (** backHand)(u16 * back, u8 n))
{
switch(mode)
{
case ROTAT_MODE_DEG_0:
{
*prevHand = &vHandler_Inc;
*backHand = &vHandler_Inc;
}
break;
case ROTAT_MODE_DEG_90:
{
*prevHand = &vHandler_Sub;
*backHand = &vHandler_Inc;
}
break;
case ROTAT_MODE_DEG_180:
{
*prevHand = &vHandler_Sub;
*backHand = &vHandler_Sub;
}
break;
case ROTAT_MODE_DEG_270:
{
*prevHand = &vHandler_Inc;
*backHand = &vHandler_Sub;
}
break;
default : break;
}
}
十、显示ASCII常规字符串(带旋转)
/* 显示字符(带旋转) */
void vTFT_DisplayChar_Rotate(u16 x, u16 y, u8 chr, u8 charSize, eRotateMode rotateMode)
{
void (* prevHandler)(u16 * prev, u8 n) = NULL;
void (* backHandler)(u16 * back, u8 n) = NULL;
u16 k = 0, j = 0, i = 0, n = 0;
u16 * xyPrev = NULL; //前半部分
u16 * xyBack = NULL; //后半部分
u16 xyPrevInitVal = 0;
u16 charByte = 0;
u8 dat = 0, * pSrcDat = NULL;
u8 count = 0;
//获取字符数据源地址
vGet_CharSrc(chr, charSize, &pSrcDat);
if (pSrcDat == NULL)
{
return;
}
/* 前后部分值处理 xy初始值 间隔值处理 */
if((ROTAT_MODE_DEG_0 == rotateMode) || (ROTAT_MODE_DEG_180 == rotateMode))
{
xyPrev = &y; //先处理纵轴
xyBack = &x; //后处理横纵
xyPrevInitVal = y;
}
else
{
xyPrev = &x;
xyBack = &y;
xyPrevInitVal = x;
}
/* 前后部分处理,x y坐标变化 */
vGet_xyHandler_Rotate(rotateMode, &prevHandler, &backHandler);
// 字符点阵占用字节数
charByte = ((charSize >> 3) + ((charSize & 0x07) ? 1 : 0)) * (charSize >> 1);
// 遍历字符点阵数据
for(k = 0; k < charByte; ++k)
{
dat = pSrcDat[k];
for(i = 0; i < 8; ++i)
{
// 显示有效范围
if ((x < AppDevLCD.xWidth) && (y < AppDevLCD.yHeight))
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (AppDevLCD.DisplayMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
}
count++;//高度计数
prevHandler(xyPrev, 1);//前部分处理
if (count == charSize)
{
count = 0;
*xyPrev = xyPrevInitVal;//赋初值
backHandler(xyBack, 1);//后部分处理
break;
}
}
}
}
/* 显示字符串(带旋转) */
void vTFT_DisplayString_Rotate(u16 x, u16 y, u8 * pStr, u8 strSize)
{
/* 旋转模式越界 */
if (AppDevLCD.RotateMode >= ROTAT_MODE_MAX)
{
return;
}
//显示ASCII常规字符
while ((*pStr >= ' ') && (*pStr <= '~'))
{
/* 剩余纵轴小于字体高度 */
if (y > (AppDevLCD.yHeight - strSize))
{
return;
}
/* 剩余的横纵小于字体宽度 换行显示 */
if (x > (AppDevLCD.xWidth - (strSize >> 1)))
{
y += strSize;
x = 0;
}
vTFT_DisplayChar_Rotate(x, y, *pStr, strSize, AppDevLCD.RotateMode);
x += (strSize >> 1);
pStr++;
}
}
十一、显示中文字符串(带镜像)
/* 显示中文字符(带镜像) */
static void vTFT_DisplayChineseChar_Mirror(u16 x, u16 y, u16 xWidth, u16 yHeight, const u8 * pData)
{
void (* xHandler)(u16 * x0, u8 n) = NULL;
void (* yHandler)(u16 * y0, u8 n) = NULL;
u16 y0 = 0;
u16 yMax = 0;
u8 dat = 0;
u16 count = 0;
u16 k = 0, j = 0, n = 0, i = 0;
//横纵坐标的操作
vGet_xyHandler_Mirror(AppDevLCD.MirrorMode, &xHandler, &yHandler);
y0 = y;// 原始纵坐标
//高度
yMax = (yHeight >> 3) + ((yHeight & 0x07) ? 1 : 0);
for(k = 0; k < xWidth; k++)
{
for(j = 0; j < yMax; j++)
{
dat = pData[n++];
for(i = 0; i < 8; i++)
{
if ((y < AppDevLCD.yHeight) && (x < AppDevLCD.xWidth))
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (AppDevLCD.DisplayMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
}
count++;
yHandler(&y, 1);//纵坐标处理
if (count == yHeight)
{
y = y0;
count = 0;
xHandler(&x, 1);//横坐标处理
break;
}
}
}
}
}
/* 显示中文字符串(带镜像) */
void vTFT_Display_ChineseString_Mirror(u16 x, u16 y, u16 xWidth, u16 yHeight, u8 * pData, u16 num)
{
u16 i = 0;
u8 charByte = 0;
u8 * pMem = pData;
//镜像模式越界
if ((!num) || (AppDevLCD.MirrorMode >= MIR_MODE_MAX))
{
return;
}
// 字符点阵占用字节数
charByte = ((yHeight >> 3) + ((yHeight & 0x07) ? 1 : 0)) * xWidth;
for (i = 0; i < num; ++i)
{
/* 剩余纵轴小于字体高度 */
if (y > (AppDevLCD.yHeight - yHeight))
{
return;
}
/* 剩余的横纵小于字体宽度 换行显示 */
if (x > (AppDevLCD.xWidth - xWidth))
{
y += yHeight;
x = 0;
}
pMem = pData + (charByte * i);
vTFT_DisplayChineseChar_Mirror(x, y, xWidth, yHeight, pMem);
x += xWidth;
}
}
十二、显示中文字符串(带旋转)
/* 显示中文字符(带旋转) */
static void vTFT_Display_ChineseChar_Rotate(u16 x, u16 y, u16 xWidth, u16 yHeight, const u8 * pData)
{
void (* prevHandler)(u16 * prev, u8 n) = NULL;
void (* backHandler)(u16 * back, u8 n) = NULL;
u16 k = 0, j = 0, i = 0, n = 0;
u16 * xyPrev = NULL; //前半部分
u16 * xyBack = NULL; //后半部分
u16 xyPrevInitVal = 0;
u16 charByte = 0;
u8 dat = 0, * pSrcDat = NULL;
u8 count = 0;
u16 yMax = 0;
/* 前后部分值处理 xy初始值 */
if((ROTAT_MODE_DEG_0 == AppDevLCD.RotateMode) || (ROTAT_MODE_DEG_180 == AppDevLCD.RotateMode))
{
xyPrev = &y; //先处理纵轴
xyBack = &x; //后处理横纵
xyPrevInitVal = y;
}
else
{
xyPrev = &x;
xyBack = &y;
xyPrevInitVal = x;
}
/* 前后部分处理,x y坐标变化 */
vGet_xyHandler_Rotate(AppDevLCD.RotateMode, &prevHandler, &backHandler);
//高度
yMax = (yHeight >> 3) + ((yHeight & 0x07) ? 1 : 0);
for(k = 0; k < xWidth; k++)
{
for(j = 0; j < yMax; j++)
{
dat = pData[n++];
for(i = 0; i < 8; i++)
{
if ((y < AppDevLCD.yHeight) && (x < AppDevLCD.xWidth))
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (AppDevLCD.DisplayMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
}
count++;//高度计数
prevHandler(xyPrev, 1);//前部分处理
if (count == yHeight)
{
count = 0;
*xyPrev = xyPrevInitVal;//赋初值
backHandler(xyBack, 1);//后部分处理
break;
}
}
}
}
}
/* 显示中文字符串(带旋转) */
void vTFT_Display_ChineseString_Rotate(u16 x, u16 y, u16 xWidth, u16 yHeight, const u8 * pData, u16 num)
{
u16 i = 0;
u8 charByte = 0;
u8 * pMem = (u8 * )pData;
//镜像模式越界
if ((!num) || (AppDevLCD.RotateMode >= ROTAT_MODE_MAX))
{
return;
}
// 字符点阵占用字节数
charByte = ((yHeight >> 3) + ((yHeight & 0x07) ? 1 : 0)) * xWidth;
for (i = 0; i < num; ++i)
{
/* 剩余纵轴小于字体高度 */
if (y > (AppDevLCD.yHeight - yHeight))
{
return;
}
/* 剩余的横纵小于字体宽度 换行显示 */
if (x > (AppDevLCD.xWidth - xWidth))
{
y += yHeight;
x = 0;
}
pMem = (u8 * )pData + (charByte * i);
vTFT_Display_ChineseChar_Rotate(x, y, xWidth, yHeight, pMem);
x += xWidth;
}
}
十三、显示图片(带镜像)
/* 显示图片(带镜像) */
void vTFT_ShowPicture_Mirror(u16 x, u16 y, u16 xWidth, u16 yHeight, const u8 * pImage)
{
void (* xHandler)(u16 * x0, u8 n) = NULL;
void (* yHandler)(u16 * y0, u8 n) = NULL;
u16 k = 0, j = 0, i = 0, n = 0;
u16 yMax = 0;
u16 y0 = 0;
u16 y1 = 0;
u8 dat = 0;
u16 count = 0;
//镜像模式越界
if (MIR_MODE_MAX <= AppDevLCD.MirrorMode )
{
return;
}
//横纵坐标的操作
vGet_xyHandler_Mirror(AppDevLCD.MirrorMode , &xHandler, &yHandler);
//图片高度
yMax = (yHeight >> 3) + ((yHeight & 0x07) ? 1 : 0);
//原始纵坐标
y0 = y;
//图片宽度
for(k = 0; k < xWidth; k++)
{
for(j = 0; j < yMax; j++)
{
dat = pImage[n++];
for(i = 0; i < 8; i++)
{
if ((y < AppDevLCD.yHeight) && (x < AppDevLCD.xWidth))
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (AppDevLCD.DisplayMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
}
count++;
yHandler(&y, 1);//纵坐标处理
if (count == yHeight)
{
y = y0;
count = 0;
xHandler(&x, 1);//横坐标处理
break;
}
}
}
}
}
十四、显示图片(带旋转)
/* 显示图片(带旋转) */
void vTFT_ShowPicture_Rotate(u16 x, u16 y, u16 xWidth, u16 yHeight, const u8 * pImage)
{
void (* prevHandler)(u16 * prev, u8 n) = NULL;
void (* backHandler)(u16 * back, u8 n) = NULL;
u16 k = 0, j = 0, i = 0, n = 0;
u16 * xyPrev = NULL; //前半部分
u16 * xyBack = NULL; //后半部分
u16 xyPrevInitVal = 0;
u16 charByte = 0;
u8 dat = 0, * pSrcDat = NULL;
u8 count = 0;
u16 yMax = 0;
/* 旋转模式越界 */
if (AppDevLCD.RotateMode >= ROTAT_MODE_MAX)
{
return;
}
/* 前后部分值处理 xy初始值 */
if((ROTAT_MODE_DEG_0 == AppDevLCD.RotateMode) || (ROTAT_MODE_DEG_180 == AppDevLCD.RotateMode))
{
xyPrev = &y; //先处理纵轴
xyBack = &x; //后处理横纵
xyPrevInitVal = y;
}
else
{
xyPrev = &x;
xyBack = &y;
xyPrevInitVal = x;
}
/* 前后部分处理,x y坐标变化 */
vGet_xyHandler_Rotate(AppDevLCD.RotateMode, &prevHandler, &backHandler);
//高度
yMax = (yHeight >> 3) + ((yHeight & 0x07) ? 1 : 0);
//图片宽度
for(k = 0; k < xWidth; k++)
{
for(j = 0; j < yMax; j++)
{
dat = pImage[n++];
for(i = 0; i < 8; i++)
{
if ((dat >> i) & 0x01)//低位在前
{
vTFT_DrawPoint(x, y, AppDevLCD.ForeColor);//正常模式
}
else if (AppDevLCD.DisplayMode & DIS_MODE_OPPOSITE)
{
vTFT_DrawPoint(x, y, AppDevLCD.BackColor);//反显模式
}
count++;//高度计数
prevHandler(xyPrev, 1);//前部分处理
if (count == yHeight)
{
count = 0;
*xyPrev = xyPrevInitVal;//赋初值
backHandler(xyBack, 1);//后部分处理
break;
}
}
}
}
}
十五、例程测试代码
extern const unsigned char Image_Tree_43x47[258];
extern const unsigned char gImage_P2P_73x44[438];
extern const unsigned char ChineseDemo[10][54];
/* TFT初始化 */
void vLCD_Init(void)
{
vInit_LCD_GPIO();
vInit_FSMC();
vTFT_Write_Factory_Parameter();
AppDevLCD.ID = ulLCD_Read_ID();
vTFT_Display_Dir(LCD_SHOW_DIR);
vTFT_Clear_Screen(WHITE);
vShow_DeviceTFT_Info();
AppDevLCD.ForeColor = BLUE;
AppDevLCD.BackColor = BLACK;
AppDevLCD.DisplayMode = DIS_MODE_NORMAL;
AppDevLCD.MirrorMode = MIR_MODE_NORMAL;
AppDevLCD.RotateMode = ROTAT_MODE_DEG_0;
// 显示字符串
vTFT_Display_String(270, 7, (u8 *)"Sys Res", ASCII_FONT_TYPE_1206);
AppDevLCD.DisplayMode = DIS_MODE_OPPOSITE;
AppDevLCD.ForeColor = YELLOW;
vTFT_Display_String(160, 5, (u8 *)"System Resets", ASCII_FONT_TYPE_1608);
AppDevLCD.ForeColor = RED;
AppDevLCD.DisplayMode = DIS_MODE_NORMAL;
vTFT_Display_String(0, 0, (u8 *)"System Resets", ASCII_FONT_TYPE_2412);
vTFT_DrawLine(0, 30, AppDevLCD.xWidth, 30, BLUE);
// 显示字符串(镜像)
AppDevLCD.ForeColor = BLUE;
AppDevLCD.BackColor = BLACK;
AppDevLCD.DisplayMode = DIS_MODE_NORMAL;
vTFT_DisplayString_Mirror(10, 35, (u8 * )"Resets Clock", ASCII_FONT_TYPE_1608);
AppDevLCD.MirrorMode = MIR_MODE_LEFT_RIGHT;
vTFT_DisplayString_Mirror(160, 35, (u8 * )"Resets Clock", ASCII_FONT_TYPE_1608);
AppDevLCD.MirrorMode = MIR_MODE_UP_DOWN;
vTFT_DisplayString_Mirror(10, 70, (u8 * )"Resets Clock", ASCII_FONT_TYPE_1608);
AppDevLCD.MirrorMode = MIR_MODE_LEFT_RIGHT_UP_DOWN;
vTFT_DisplayString_Mirror(160, 70, (u8 * )"Resets Clock", ASCII_FONT_TYPE_1608);
vTFT_DrawLine(0, 75, AppDevLCD.xWidth, 75, YELLOW);
//显示字符串(旋转)
AppDevLCD.RotateMode = ROTAT_MODE_DEG_0;
vTFT_DisplayString_Rotate(10, 80, (u8 * )"Resets system", ASCII_FONT_TYPE_1608);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_90;
vTFT_DisplayString_Rotate(170, 85, (u8 * )"Resets system", ASCII_FONT_TYPE_1608);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_180;
vTFT_DisplayString_Rotate(15, 115, (u8 * )"Resets system", ASCII_FONT_TYPE_1608);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_270;
vTFT_DisplayString_Rotate(155, 110, (u8 * )"Resets system", ASCII_FONT_TYPE_1608);
vTFT_DrawLine(0, 120, AppDevLCD.xWidth, 120, RED);
// 显示中文(镜像)
AppDevLCD.ForeColor = RED;
AppDevLCD.MirrorMode = MIR_MODE_NORMAL;
vTFT_Display_ChineseString_Mirror(10, 130, 18, 18, (u8 *)ChineseDemo[1], 7);
AppDevLCD.MirrorMode = MIR_MODE_UP_DOWN;
vTFT_Display_ChineseString_Mirror(170, 145, 18, 18, (u8 *)ChineseDemo[1], 7);
AppDevLCD.MirrorMode = MIR_MODE_LEFT_RIGHT;
vTFT_Display_ChineseString_Mirror(25, 155, 18, 18, (u8 *)ChineseDemo[1], 7);
AppDevLCD.MirrorMode = MIR_MODE_LEFT_RIGHT_UP_DOWN;
vTFT_Display_ChineseString_Mirror(185, 170, 18, 18, (u8 *)ChineseDemo[1], 7);
vTFT_DrawLine(0, 180, AppDevLCD.xWidth, 180, RED);
// 显示中文(旋转)
AppDevLCD.ForeColor = BLUE;
AppDevLCD.RotateMode = ROTAT_MODE_DEG_0;
vTFT_Display_ChineseString_Rotate(10, 190, 18, 18, (const u8 *)ChineseDemo[1], 7);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_90;
vTFT_Display_ChineseString_Rotate(185, 190, 18, 18, (const u8 *)ChineseDemo[1], 7);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_180;
vTFT_Display_ChineseString_Rotate(25, 230, 18, 18, (const u8 *)ChineseDemo[1], 7);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_270;
vTFT_Display_ChineseString_Rotate(165, 230, 18, 18, (const u8 *)ChineseDemo[1], 7);
vTFT_DrawLine(0, 240, AppDevLCD.xWidth, 240, RED);
AppDevLCD.ForeColor = BLACK;
AppDevLCD.MirrorMode = MIR_MODE_NORMAL;
vTFT_ShowPicture_Mirror(10, 250, 43, 47, Image_Tree_43x47);
AppDevLCD.MirrorMode = MIR_MODE_UP_DOWN;
vTFT_ShowPicture_Mirror(80, 295, 43, 47, Image_Tree_43x47);
AppDevLCD.MirrorMode = MIR_MODE_LEFT_RIGHT;
vTFT_ShowPicture_Mirror(210, 250, 43, 47, Image_Tree_43x47);
AppDevLCD.MirrorMode = MIR_MODE_LEFT_RIGHT_UP_DOWN;
vTFT_ShowPicture_Mirror(280, 295, 43, 47, Image_Tree_43x47);
AppDevLCD.ForeColor = RED;
AppDevLCD.RotateMode = ROTAT_MODE_DEG_0;
vTFT_ShowPicture_Rotate(0, 310, 73, 44, gImage_P2P_73x44);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_90;
vTFT_ShowPicture_Rotate(140, 300, 73, 44, gImage_P2P_73x44);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_180;
vTFT_ShowPicture_Rotate(220, 360, 73, 44, gImage_P2P_73x44);
AppDevLCD.RotateMode = ROTAT_MODE_DEG_270;
vTFT_ShowPicture_Rotate(240, 370, 73, 44, gImage_P2P_73x44);
vTFT_DrawLine(0, 375, AppDevLCD.xWidth, 375, RED);
AppDevLCD.ForeColor = BLUE;
vTFT_Display_String(10, 380, (u8 *)"1 ASCII String", ASCII_FONT_TYPE_1608);
vTFT_Display_String(170, 380, (u8 *)"2 String Mirror", ASCII_FONT_TYPE_1608);
AppDevLCD.ForeColor = RED;
vTFT_Display_String(10, 405, (u8 *)"3 String Rotate", ASCII_FONT_TYPE_1608);
vTFT_Display_String(170, 405, (u8 *)"4 Chinese Mirror", ASCII_FONT_TYPE_1608);
AppDevLCD.ForeColor = GREEN;
vTFT_Display_String(10, 430, (u8 *)"5 Chinese Rotate", ASCII_FONT_TYPE_1608);
vTFT_Display_String(170, 430, (u8 *)"6 Pictrue Mirror", ASCII_FONT_TYPE_1608);
AppDevLCD.ForeColor = BLACK;
vTFT_Display_String(10, 455, (u8 *)"7 Pictrue Rotate", ASCII_FONT_TYPE_1608);
}
————————————————
版权声明:本文为CSDN博主「凌盛羽」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Ceosat/article/details/127679253
|
|