STM32LCD液晶屏显示二值图片

基本原理

这几天在学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 <stdio.h>

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);	
	}
}

代码通过ST-Link烧写器写入开发板中就可以看到结果了
在这里插入图片描述
效果还不错,还原度还蛮高的,索大是真的帅

  • 14
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫卡的小星星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值