|
官方例程中显示不同大小的字符都是共用一个函数,即先指定字库、前景色和背景色,然后再将字符串及起始行列、对齐方式作为参数传送给字符串显示函数UTIL_LCD_DisplayStringAt(),如下图所示: , f) k, v: I7 f: n# ^7 _! C
在UTIL_LCD_DisplayStringAt()函数中也仅仅是处理好显示的起始位置后,依次将字符串逐个字符传递给后续函数UTIL_LCD_DisplayChar(refcolumn, Ypos, *Text)处理:- @7 q( i) h# U6 k7 ] [7 K
后续的DisplayChar()函数如下: /** * @brief Displays one character in currently active layer.在当前活动层中显示一个字符。1 Y$ h; H' K; Z V * @param Xpos Start column address4 C! f/ ~: g9 N* Q * @param Ypos Line where to display the character shape.% F& R. O$ t6 T6 w" Z* I# q * @param Ascii Character ascii code2 w& Z5 A! Z0 T7 [6 j * This parameter must be a number between Min_Data = 0x20 and Max_Data = 0x7E */8 l4 U4 Y" k3 j0 | void UTIL_LCD_DisplayChar(uint32_t Xpos, uint32_t Ypos, uint8_t Ascii) e$ v+ n$ e q { DrawChar(Xpos, Ypos, &DrawProp[DrawProp->LcdLayer].pFont->table[(Ascii-' ') *\ T8 o& _$ M3 l6 {% u6 x DrawProp[DrawProp->LcdLayer].pFont->Height * ((DrawProp[DrawProp->LcdLayer].pFont->Width + 7) / 8)]); }5 i; z6 h) S0 a& D! Y 7 V8 [1 N( V* `! t% H/ U! S 在这个函数中也只是将之前指定的字库设置好,继续交给DrawChar()函数执行,DrawChar函数如下: 4 T) Z! i C4 l; [& | /**) N: l; m" w- I3 U2 E2 Z. c; } * @brief Draws a character on LCD.% W9 R1 Y* o, Y1 ^0 N+ |7 b * @param Xpos Line where to display the character shape, Q2 e5 q) b& w+ T) } * @param Ypos Start column address$ _7 f8 b9 s& _ Q. S- m * @param pData Pointer to the character data */ static void DrawChar(uint32_t Xpos, uint32_t Ypos, const uint8_t *pData) {. S$ r( }9 V8 c8 t9 S uint32_t i = 0, j = 0, offset; uint32_t height, width;0 j0 p, F0 ?, }$ T: r" h uint8_t *pchar; uint32_t line;# C+ y! m5 l& s- M5 L9 r 6 W5 m' B2 o( W/ ~* A7 G' y! o( F height = DrawProp[DrawProp->LcdLayer].pFont->Height;( z6 p I8 g t) d6 V; ] width = DrawProp[DrawProp->LcdLayer].pFont->Width;) v, P4 U/ a' M/ d- K+ m u2 @ uint16_t rgb565[24];0 y& }9 s% A4 N( D2 k% I; ^) Z8 B uint32_t argb8888[24]; 0 P) O0 T/ E- i' P( s; b- A offset = 8 *((width + 7)/8) - width ; ! o$ G- z' W" A" a7 c* ]: R- t for(i = 0; i < height; i++) {; T. p% s0 C/ l3 h. }2 Q# B R pchar = ((uint8_t *)pData + (width + 7)/8 * i); switch(((width + 7)/8)), S6 o% g8 J! O1 y; Q { + E. j r# x2 q c6 C" }! w& { case 1:" V _7 O8 `& K0 `, F, \: I line = pchar[0];/ E$ ^; n# e" ~& Y break; case 2:7 s, S) o" |1 e3 @% O2 F# {2 f line = (pchar[0]<< 8) | pchar[1];* v y/ t: ~2 g break; 1 f2 Q) X6 I h' f" w7 t case 3:- P! I9 U) @, M6 H default: line = (pchar[0]<< 16) | (pchar[1]<< 8) | pchar[2]; t V9 L/ |* w- `& _$ O break;* B! X. B% S5 H; v* |: d }) r& N, {; u8 L. u$ c : O$ Q' `/ @7 h* X ` ] if(DrawProp[DrawProp->LcdLayer].LcdPixelFormat == LCD_PIXEL_FORMAT_RGB565): z2 J6 Z6 s$ j, |. [ {1 D: h* B+ A2 g/ I+ W) @ for (j = 0; j < width; j++) {" |# |" o2 G9 _" h7 k' Z/ k' K if(line & (1 << (width- j + offset- 1))) { rgb565[j] = CONVERTARGB88882RGB565(DrawProp[DrawProp->LcdLayer].TextColor);/ E4 S/ A1 [5 W9 p( P }" z4 Z* H8 q8 A6 M8 o* t else { rgb565[j] = CONVERTARGB88882RGB565(DrawProp[DrawProp->LcdLayer].BackColor);. E- N. ~( u( |4 J5 N% D3 T$ N } }% ?( K1 C7 ~. x6 Z* T/ v* h+ ? UTIL_LCD_FillRGBRect(Xpos, Ypos++, (uint8_t*)&rgb565[0], width, 1); }9 ]" s. Q, _- L, ~ L0 a: B( f else {* X( b r: n( x: R" r$ ~! [ P3 Q for (j = 0; j < width; j++)2 w( c6 V: k' G! ^ {/ O$ U2 |/ k3 }; i! r if(line & (1 << (width- j + offset- 1))) { argb8888[j] = DrawProp[DrawProp->LcdLayer].TextColor;$ F3 |" V4 D6 o% d8 n% F v3 j } else" }+ c7 p1 g( O { argb8888[j] = DrawProp[DrawProp->LcdLayer].BackColor; }( O& ]- x+ R! _- g6 K$ n0 \ } UTIL_LCD_FillRGBRect(Xpos, Ypos++, (uint8_t*)&argb8888[0], width, 1); } }0 t& o, J1 @. b) L7 a! ^8 q; x2 h }6 N% P! ]6 j$ K; q $ I" l5 ^7 ~% u 在这个函数中,将字库中的字模逐个点交给写矩形的函数,在屏幕中“画”出字符来。 我好奇的是:为什么不使用画点的函数UTIL_LCD_SetPixel(),而使用画矩形的函数UTIL_LCD_FillRGBRect()?: \" B3 i9 a6 c/ H* T, F2 S, W: _ - ^ A" N( v0 X, X* ~, Y |
【STM32C5教程】(9)DAC 模拟量信号输出实验
STM32C543RC开发板Stop、Sleep和standby模式测试
【STM32C5教程】(10)LPUART DMA 通信实验
【STM32C5教程】(8)ADC 模拟量数据采集实验
【STM32C5教程】(7)TIM1 互补 PWM 输出实验
【STM32C5教程】(6)定时器 PWM 输出实验
【STM32C5教程】(5)定时器周期中断实验
【STM32C5教程】(4)GPIO 外部中断实验
【STM32C5教程】(3)GPIO 按键输入实验
STM32C542RC开发板PWM呼吸灯及多功能按键实验
微信公众号
手机版