目的: 在LCD上显示图片
方案: 由于STM32F107VC内置内存只有64K,不足以全屏显示板载LCD,SSD1289,320x240x16bit
图像数据只能通过外部存储设备读入,板置W25X16,或SD。数据需要提前导入。
另一个方案是通过数据连接在运行时实时传输,USART,LAN,或USB。需要数据服务端程序。
通过SD传输是开发量最少且可以独立运行的方案
研究: 板载有2个SD卡槽,主板卡槽和LCD板背部槽。
由于主板卡槽使用的CS线与LCD的CS冲突,于是选择LCD板背后有SD卡插槽
该槽使用SPI3驱动,与AFIO的Remap连接
实现:
初始化GPIOC/GPIOD/AFIO,并使用SPI3的REMAP外接线
init_spi
*rcc_apb1enr |= 0x8000; //SPI3
*rcc_apb2enr |= 0x31; //GPIOC GPIOD AFIO
*afio_mapr |= 0x10000000; //AFIO SPI3 remap
SD的响应值设置超时等待
sd_respons
while (((rtn&0x80)!=0)&&(cnt)) { // R1: [MSB]0xxxxxxx
SD的CMD8用于确定新卡的版本,只处理v2以后的卡
sd_process
if (sd_cmd8()) {
sd_v2_process();
} else {
// sd_v1_process();
}
ACMD41为SD卡上电,进入可读写状态
ACMD41
cmd[0]=41;
cmd[1]=0x40; //v2 card set volt
cmd[5]=0x77; //CRC
sd_command(cmd, out, cc);
SD卡Page的大小为512字节,而图像的每个像素是24bit,3Byte,需要2字节用于处理每页的剩余数据
page_mod
unsigned char pagedata[512+3]; //512 + 3
if (512+cc > rtn) {
for (jj=0; jj<512+cc-rtn; jj++) {
pagedata[jj] = pagedata[rtn+jj];
}
}
cc = 512 + cc - rtn;
图像文件需要RGB 24bit,RAW格式文件
使用Linux环境图像转换工具ImageMagick可以简单处理
ImageMagick Convert
$> convert -resize 320x240 ori.jpg stm.rgb
如果图像比例不是4:3, 可以使用调整参数
$> convert -resize 320x240 -background skyblue -gravity center -extent 320x240 ori.jpg stm.rgb
使用USB读卡器将.rgb文件写到SD卡
dump image
LCD的像素是RGB5:6:5格式,需要进行转换
pixel_convert
rr=dat[0];
gg=dat[1];
bb=dat[2];
ddat = ((rr>>3)<<11) | ((gg>>2)<<5) | (bb>>3);
$> dd if=stm.rgb of=/dev/sd?