官方例程中显示不同大小的字符都是共用一个函数,即先指定字库、前景色和背景色,然后再将字符串及起始行列、对齐方式作为参数传送给字符串显示函数UTIL_LCD_DisplayStringAt(),如下图所示:8 T4 ^1 A( x, x8 G5 ~" V
在UTIL_LCD_DisplayStringAt()函数中也仅仅是处理好显示的起始位置后,依次将字符串逐个字符传递给后续函数UTIL_LCD_DisplayChar(refcolumn, Ypos, *Text)处理:
后续的DisplayChar()函数如下: /**4 b, o, W8 [1 o' k * @brief Displays one character in currently active layer.在当前活动层中显示一个字符。( S( v4 j: `/ C! ]: r * @param Xpos Start column address * @param Ypos Line where to display the character shape./ J* u8 H+ l0 `8 r * @param Ascii Character ascii code; U9 d' i/ j/ j6 q. V * This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E+ h; U- C7 z. T' M/ g */ void UTIL_LCD_DisplayChar(uint32_t Xpos, uint32_t Ypos, uint8_t Ascii)3 D( r z$ G* u( q3 \4 R { DrawChar(Xpos, Ypos, &DrawProp[DrawProp->LcdLayer].pFont->table[(Ascii-' ') *\5 o5 B/ p. n Y, l/ O3 ^- i DrawProp[DrawProp->LcdLayer].pFont->Height * ((DrawProp[DrawProp->LcdLayer].pFont->Width + 7) / 8)]);0 C# n# J3 N8 C" m J }: e" [4 A( S8 L" m0 ?! p, ]4 l 7 `. G( F f$ y* e$ y: w 在这个函数中也只是将之前指定的字库设置好,继续交给DrawChar()函数执行,DrawChar函数如下:; C- m* E* i ?( \! x: D1 H + s8 ?+ A( X3 ~& u* f /**# t5 n- Q6 C( r# c4 x! M * @brief Draws a character on LCD. * @param Xpos Line where to display the character shape * @param Ypos Start column address1 P8 t; E8 \9 J * @param pData Pointer to the character data */& d, E( L# H8 I) `: @+ m static void DrawChar(uint32_t Xpos, uint32_t Ypos, const uint8_t *pData), [" a" R4 o# `, f, C; o {3 p3 Q4 m n% t3 A uint32_t i = 0, j = 0, offset; uint32_t height, width; uint8_t *pchar;) s, b0 \$ y7 J9 D3 T$ w uint32_t line;9 g. V- K4 a3 |$ H7 T. ~ height = DrawProp[DrawProp->LcdLayer].pFont->Height; width = DrawProp[DrawProp->LcdLayer].pFont->Width; uint16_t rgb565[24]; uint32_t argb8888[24];" q) L. x, C2 B offset = 8 *((width + 7)/8) - width ; d8 m* t, ?0 w q4 ^ for(i = 0; i < height; i++) { pchar = ((uint8_t *)pData + (width + 7)/8 * i);0 Q" i) k/ @$ X% d! @3 W switch(((width + 7)/8)) {0 \1 A% f& o! ?3 I* `" v Y5 Y case 1:* C, e8 ^1 ^1 H6 X$ P* E line = pchar[0];0 S; E6 e& ^4 K6 o4 x) A* P/ { M- [* U break;- g9 d) Z/ z* f' V3 P- ^8 r: Q3 @ case 2: line = (pchar[0]<< 8) | pchar[1];; V2 ?+ G; n3 A2 d; \; W break; case 3: default: line = (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2];$ S3 a/ X" O% {& C g( v1 C break; } if(DrawProp[DrawProp->LcdLayer].LcdPixelFormat == LCD_PIXEL_FORMAT_RGB565)# y0 x, q$ w; [ {# F2 f; b- _% F% F+ I& v for (j = 0; j < width; j++) {0 r. s/ Z9 l) g8 U. G5 v if(line & (1 << (width- j + offset- 1))); s, K3 T( c, p2 Q% d1 j {5 O5 r7 g s, v; Q rgb565[j] = CONVERTARGB88882RGB565(DrawProp[DrawProp->LcdLayer].TextColor);, k% e- U' i+ {- L1 Y: U }) Z3 Q& C' J" p# s7 c7 U4 o; h else {3 a2 N; u+ a5 z# L. X% I+ D rgb565[j] = CONVERTARGB88882RGB565(DrawProp[DrawProp->LcdLayer].BackColor);/ H6 a: N# _; m2 n/ m0 {! s$ b } } UTIL_LCD_FillRGBRect(Xpos, Ypos++, (uint8_t*)&rgb565[0], width, 1);) ]4 `) q. a6 {) @, W1 w' f } else) b, w4 E# Y$ k { for (j = 0; j < width; j++) {& G1 q- s% U6 f. q* f- k# {! e% v if(line & (1 << (width- j + offset- 1)))( g' t" [5 L: o) | { argb8888[j] = DrawProp[DrawProp->LcdLayer].TextColor; } else { argb8888[j] = DrawProp[DrawProp->LcdLayer].BackColor;; `" M; z; k. p& J1 c9 u4 `% { }+ X- \: @# N& J8 A; b9 B } UTIL_LCD_FillRGBRect(Xpos, Ypos++, (uint8_t*)&argb8888[0], width, 1);; q2 E; p' C) q [ } }( h$ [: d$ j! T4 { } - u5 e. I+ d p3 Q; k0 p : k; M5 Z- R2 o( W' s2 S6 a 在这个函数中,将字库中的字模逐个点交给写矩形的函数,在屏幕中“画”出字符来。, o+ m* n7 T2 z! g 我好奇的是:为什么不使用画点的函数UTIL_LCD_SetPixel(),而使用画矩形的函数UTIL_LCD_FillRGBRect()?! {2 u0 Y2 w% h3 R* f: y |
《STM32CubeMX2 实战课程》学习笔记--课程1:STM32CubeMX2安装
STM32L562DK探索板——串口通讯测试成功
STM32L562DK探索板——再试串口通讯仍不成
M24LR-discovery测试小结
STM32L562DK探索板——串口通讯的再测试
STM32L562DK探索板——串口通讯的测试
STM32L562DK探索板——运动传感器测试
STM32L562DK探索板——继续深入了解Audio Play的工作流程
STM32L562DK探索板——触摸菜单实验之触摸测试
STM32L562DK探索板——触摸菜单实验之LED闪烁
微信公众号
手机版