|
STM32H735G-DK 自带 MB1315 子板,上面是 4.3 寸 TFT,分辨率 480×272,RGB565 并行接口,经 CN19 直连 H735IGK6 的 LTDC 外设;背光由 PG15 控制,触摸是 FT5336。/ E9 \8 ~; y; X * l' a( v- x6 l; w6 t6 h H735 的 LTDC 自带两层图层,可从内部 SRAM/AXI SRAM/SDRAM/OSPI RAM 取显存,显存绝对不能放 DTCM(0x2000_0000 起),LTDC 总线读不到,这是 H735 黑屏第一大坑。 ( O& W9 U8 v5 t$ b 480×272×2Byte ≈ 261KB,H735 内部 AXI SRAM 有 512KB 够用,不必外挂 SDRAM。官方提供两个显示图片的例程,不能显示字符串。 我要显示字符串,自己配 LTDC是最土的法子,我就是用的这个土法子。调用font12、font16、font24的字模文件,字模数组按 RGB565 写进 framebuf 对应像素偏移,LTDC 自动刷出来。 O; g7 k4 o, d; X) J% c( N3 K 再main.h文件中要调用不少头文件8 }4 c- ~' D( D8 I/ B0 i #include "stm32h7xx_hal_conf.h" #include "stm32h735g_discovery.h"" e8 E3 I9 p7 f& Q' N# S' H' ] #include "stm32h7xx_hal_ospi.h" // ??? include ????1 F/ W3 b2 Q2 F$ @; { #include "stm32h735g_discovery_lcd.h" #include "stm32_lcd.h" /* UTIL_LCD_* */' n5 @! U' h$ H! b3 @3 d# ] #include "fonts.h" 定义如下显示字符函数 #define HW_WIDTH 480 // ??????, M( t6 ?, _- | #define HW_HEIGHT 272 // ?????? #define FB_ADDR ((uint16_t*)0x24000000) ( }" C* ~7 V, l0 Z1 U7 E static void draw_pixel_v(uint32_t x, uint32_t y, uint16_t color)9 t2 x5 \6 U! h2 ~: i" X! X { int hx = y; // ??y ? ??x(0479) int hy = (HW_HEIGHT - 1) - x; // ??x ? ??y(??,0271) if (hx >= 0 && hx < HW_WIDTH && hy >= 0 && hy < HW_HEIGHT), b8 s. a4 J) D% y# ~' I5 g, y" j0 N: K" t FB_ADDR[hy * HW_WIDTH + hx] = color; }6 ] }; V6 E2 D2 f- q) o; y# b /* ---------- ? Font12 ???(????????)---------- */% Z9 v* E. |6 T static void draw_char12_v(uint32_t x, uint32_t y, char c, uint16_t color)% y( K( G. j8 B" G, S3 y { if (c < 0x20 || c > 0x7E) return;/ U# I9 }4 Q: O+ y; f3 K uint32_t char_index = c - 0x20; const uint8_t *glyph = &Font12_Table[char_index * 12];/ j8 j+ m$ [& r4 {6 p( B for (int row = 0; row < 12; row++) { uint8_t bits = glyph[row]; for (int col = 0; col < 7; col++) {) V& X7 N1 |0 z, Q! W if (bits & (0x80 >> col)) {0 \) h' E/ I8 F draw_pixel_v(x + col, y + row, color); } }( n4 g5 R( P; R } } /* ---------- ????(??????)---------- */ static void draw_string12_v(uint32_t x, uint32_t y, const char *str, uint16_t color)+ {" C* C7 R6 _( L0 v {3 `$ b: X( a! ?. ~* P. }: v int cx = x;; G, a! s b( {7 l/ S while (*str) {; k" P6 U7 b) G- g" H' U draw_char12_v(cx, y, *str, color);9 ^& S- _2 V) h; r$ w4 K6 [ cx += 8; // 7??? + 1?? str++;* [ X# l9 e! S5 X" e }0 g, f% s2 m- Y8 }5 H' h8 ~8 X } 开始用的font24字符很霸气。每个字符 24 像素高,在 480×272 的屏上几乎占满半行。一行最多塞 20 个字符,但那个视觉冲击力是真的猛:黑底白字,每个笔画粗壮饱满,老远就能看清,三行字占掉 120 像素高度。" R& |$ K* S" q1 } 但信息密度太低。想多打两行,没地方了。24px 的字在 272 像素高的横屏上,顶多塞 十来行 行就到底,而且每行也就几个字。8 N- i2 X7 v2 |
; p/ c3 }" |2 \) k: [' u+ Z$ A% Y 把 Font24 换成 Font12 的那一刻,屏幕上突然瘦了下来,信息量直接翻倍。12px 的字符在 RGB565 屏上刚好是最漂亮的尺度,后期要把 CoreMark 分数、编译器版本、缓存状态全堆上去,屏面终于有了正经仪表盘的味道。: c% A4 a' N2 J1 m4 i$ R: [ 横屏 480 宽塞 Font12 可以放 40 个字符,但 272 高也只能放 22 行左右,参数再多就挤不下。横屏时那些短字符串,比如 "Hello World!"也占一行,空置率太高。
还是得竖屏,屏幕逻辑分辨率变成 272×480。这一转,整个布局逻辑全变了:宽度从 480 缩到 272 → Font12 每行只能放 22 个字符,长字符串必须拆行% E" W1 B' R! q! N) @+ [) d 高度从 272 拉到 480 → 能放 40 行 Font12 文字,信息纵向展开后节奏感出来了,参数一行一个,像手机上的系统信息页,从上往下扫读,层次分明。) T. w M# l! F g) Z
竖屏妙啊,嵌入式系统信息天然适合纵向列表。5 `; k$ h) w8 B" Z 而且竖屏 272×480 的显存还是 261KB,CPU 不用多干任何活。 ) t! K, `& ^9 M: u8 l" J, | 小结避坑:, A* _! S% m1 r1 X 黑屏只背光亮:九成显存地址在 DTCM,或 PLL3_R 没给 LTDC 时钟,或 PH6 复位脚没拉。 颜色红蓝反:RGB565 字节序或 R/B 线交换,DMA2D 做 Red/Blue Swap 最快。 字糊成竖条:Layer 窗口大小和显存 stride 不一致(480×2 必须对齐 64 字节 AXI 突发)。 |
ST软件工具我知道之STM32CubeProg和TouchGFX
2025国庆中秋活动体验报告6 OpenAMP实现数据交互
2025国庆中秋活动体验报告5 CustomContainer中控件与参数适配
2025国庆中秋活动体验报告4_解析传感器数据
2025国庆中秋活动体验报告3-STM32H745之CM4内核不定长中断接收
2025国庆中秋活动体验报告2 健康监测界面设计
【学习有礼】 STM32H7R/S线上课程,快速入手!
AN5617中OpenAMP Linker configuration中的一处勘误
STM32H755双核通信学习资料
STM32H7双核通信实现方法学习AN5617
微信公众号
手机版