这几天在学STM32,基于正点原子的开发板和视频教程,TFTLCD能显示字符和汉字,那么能不能显示图片,看看下文你就知道答案了。
其实显示字符和汉字是通过点阵的方式来实现的,显示图片也是一个道理,要将图片转成点阵。
假设有这么一张图片
用MATLAB转换成二值图像
代码如下:
f=imread('索隆.jpg');
I=im2bw(f);
I=imresize(I, [480,800],'nearest');
I=rot90(I);
imshow(I)
我使用的是4.3寸的LCD显示屏(480×800)
第三行代码是将图片压缩为高480宽800的图像,刚好能填充满显示屏
第四行代码是将图片顺时针旋转90度,用竖屏显示图片
其实二值图像就是0和1的矩阵,MDK只支持C语言的数据结构,所以还要将MATLAB的矩阵转成C语言数组,通过MATLAB写入文本文件,打开文本文件直接复制粘贴到C代码中实现
fid = fopen('ZL_Data.txt','wt');
matrix=I;
[m n] =size (matrix) ;
fprintf(fid,'int DCTCOEF[%d] [%d]={\n',m,n) ;
for i=1 :m
fprintf(fid,'{' );
for j=1:n-1
fprintf(fid,'%d,',matrix(i,j));
end
fprintf(fid,'%d}, \n',matrix(i,n));
end
fprintf(fid,'};');
fclose(fid) ;
要保证主函数代码的美观性,需要将这么大的数组在其他文件中定义
lcd.h中定义变量
extern u8 DCTCOEF[800] [480];
lcd.c中对变量进行赋值
u8 DCTCOEF[800] [480]=从文本文件中拷贝过来的数组;
最后在main.c文件中引入头文件lcd.h
虽然还没写画图函数,不过可以先编译看看有没有错
..\OBJ\LCD.axf: Error: L6406E: No space in execution regions with .ANY selec
有十几个类似这样的错误,仔细读发现是空间不足的问题,我用的是战舰开发板,只有512K的FLASH空间
这是代码的大小,已经超出了FLASH空间
思考了一会才想出答案,数组是用int类型定义的,也就是说每个元素都占16位,可实际上正真用到的只有最后一位(要么是0要么是1),C语言没有定义1位变量的语句。可以使用位运算将数组中16个元素分为一组用整形变量来表示,这么算下来原来800×480的数组可以压缩为800×30的数组。
数组压缩的操作在C语言中实现
#include
int main()
{
int DCTCOEF[800] [480]=从文本文件中拷贝过来的数组;
FILE* pfile = fopen("16.txt", "w");
int i,j,p,temp;
for(i=0;i<800;i++)
{
fprintf(pfile,"{");
for(j=0;j<30;j++)
{
temp=0;
for(p=0;p<16;p++)
{
temp=temp|((DCTCOEF[i][j*16+p])<<p);
}
if(j==29)fprintf(pfile,"0x%X",temp);
else fprintf(pfile,"0x%X,",temp);
}
fprintf(pfile,"},\n");
}
fclose(pfile);
以上代码还会生成一个文本文件"16.txt",将之前在lcd.c和lcd.h中定义的变量替换为文件中的数据即可
看看压缩数据后的文件大小
比之前小了好多
在lcd.c中编写画图函数
void LCD_ShowPicture(u16 picture[][30])
{
u16 m,n,p,temp;
for(n=0;n<800;n++)
{
for(m=0;m<30;m++)
{
for(p=0;p<16;p++)
{
temp=picture[n][m]>>p;
if(temp&0x01)
{
LCD_Fast_DrawPoint((m*16+p),n,BACK_COLOR);
}
else
{
LCD_Fast_DrawPoint((m*16+p),n,POINT_COLOR);
}
}
}
}
}
压缩数据做位运算时是左移读入,所以解压数据时是右移读出,这里一定不能弄错,不然图片显示会乱到让你怀疑人生。picture是lcd.c替换数据后重新给变量的命名。
最后一步需要调整main.c文件中的代码
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
/************************************************
ALIENTEK 战舰STM32F103开发板实验13
TFTLCD显示实验
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司
作者:正点原子 @ALIENTEK
************************************************/
int main(void)
{
u8 lcd_id[12]; //存放LCD ID字符串
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
while(1)
{
LCD_ShowPicture(picture);
LED0=!LED0;
delay_ms(1000);
}
}