LCD显示 SRAM与FLASH

最近在玩STM32的LCD显示时,发现了一些关于内存空间的问题。

stm32的FLASH可以类比于ROM(相当于硬盘),SRAM可以类比于RAM(内存),但也有一些区别,先不具体了解了,后面再说。

图片的表示有多种方式:RGB、HSV等。在传输图片时,一般是将图片的RGB转换成三种颜色对应的数字,数字的范围我们一般是采用从0-255,但是这也不是绝对的,可将范围变大变小,有时为了减少数据量,适当牺牲色彩的细腻也是可以接受的。由于采用的芯片STM32F103C8T6的SRAM太小,因此采用16bety的数据对每个像素进行表示,这依然有两种方式:

RGB565:用5位表示红、6位表示绿、5位表示蓝
RGB555:16位数据中用5位表示红、5位表示绿、5位表示蓝,浪费一位

这里采用RGB565的方式。

由于我使用的屏幕是128*160分辨率,故需要先对图片进行按比例缩放,同时将图片数据解析为数字信息。采用python实现该功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from PIL import Image
import numpy as np

def resize_and_process_image_to_hex(image_path, output_image_path, output_text_path):
# Load and resize the image
img = Image.open(image_path)
img_resized = img.resize((128, 160), Image.ANTIALIAS)
img_resized.save(output_image_path)

# Convert to RGB and get numpy array
img_rgb = img_resized.convert('RGB')
img_array = np.array(img_rgb)

# Initialize a list to hold the processed pixel values in hex
hex_values = []

# Process each pixel
for row in img_array:
for pixel in row:
r, g, b = pixel
# Convert to 5-6-5 bit RGB
r_565 = r >> 3
g_565 = g >> 2
b_565 = b >> 3
rgb_565 = (r_565 << 11) | (g_565 << 5) | b_565
# Split into high and low bytes and convert to hex
high_byte = (rgb_565 >> 8) & 0xFF
low_byte = rgb_565 & 0xFF
hex_values.append(f"0X{low_byte:02X}")
hex_values.append(f"0X{high_byte:02X}")

# Write to file, with 12 hex values per line
with open(output_text_path, "w") as file:
for i, value in enumerate(hex_values, start=1):
if i % 12 == 0: # After every 12 values, add a newline
file.write(value + ",\n")
else:
file.write(value + ",")


image_path = "./sample.jpg" # This should be the path to the image you want to process.
output_image_path = "./resized_image.png" # Path where the resized image will be saved.
output_text_path = "./pixel_values_hex.txt" # Path where the hex values will be saved.
resize_and_process_image_to_hex(image_path, output_image_path, output_text_path)

sample.jpg为需要处理的图片;output_image_path 为输出的128*160分辨率图片;output_text_path为输出的图片转换成RGB565的十六进制的数据。

STM32的工程代码省略了。

wrong

在编译时,出现了如上报错,这是因为在将图片显示在128*160分辨率的显示屏上时,图片转换的数据过多,STM32F103C8T6,LQFP48,FLASH:64K, SRAM:20K; 在使用SRAM更大的 STM32F103ZET6,FLASH:512K,SRAM:64K 运行程序得到如下结果:

test

RW-data + ZI-data构成SRAM,Code + RO-Data + RW-Data构成FLASH。所以超过了STM32F103C8T6的SRAM,这时一般需要更换SRAM更大的芯片,但是依然有缓兵之计, RO-data是 Read Only 只读常量的大小,如const型。 因此只需要将巨大的数组变成const类型就可以:

1
2
//unsigned char pic1[40960] = {...}  
const unsigned char pic1[40960] = {}

solve

果然成功编译!

接线:

LCD STM32F103C8T6
GND 电源地
VCC 接5V或3.3V电源
SCL 接PA5(SCL)
SDA 接PA7(SDA)
RST 接PB0
DC 接PB1
CS 接PA4
BL 接PB10
K1 接PB6
K2 接PB7
K3 接PB8
K4 接PB9

K1、K2、K3、K4为按键,可不接

最后结果图如下:

result