当前位置:首页 > 单片机 > 单片机
[导读]由于需要用到液晶屏(320*240)显示图片,而且图片的数量比较多(好几百张),并且图片要求保存到16M的SPI FLASH里面,显然如果不处理 16M的FLASH明显是放不下去。后来同事说可以用压缩算法RLE,并且用C#给我做了个小

由于需要用到液晶屏(320*240)显示图片,而且图片的数量比较多(好几百张),并且图片要求保存到16M的SPI FLASH里面,显然如果不处理 16M的FLASH明显是放不下去。后来同事说可以用压缩算法RLE,并且用C#给我做了个小的软件,压缩图片得到RLE压缩后的数据。

点击打开链接 ---------- 详细的RLE算法可以参考次连接http://blog.csdn.net/orbit/article/details/7062218


这个算法的缺点是 如果图片颜色复杂就不好,所以颜色尽量单调些。


1、RLE算法小工具的使用

2、我使用的RLE和上面连接的区别(改进)

3、单片机里面实现的方法



1、RLE算法小工具的使用点击打开链接

这里是小工具的下载地址 http://download.csdn.net/detail/chen244798611/9696253



使用:使用也非常简单 下载下来RLETest.exe,点击打开 --》界面就一个按钮 “压缩”---》点击选择图片 自动压缩

提示完成可以看见生成


第一个里面有压缩前和压缩后的文件大小对比

最后一个.c文件压缩后得到一个数据,可以保存到spi flash里面

2、我使用的RLE和上面连接的区别(改进)

由于采用的液晶屏是16位的数据,那么比较可定应该是按照2字节 一个数据的比较,不能采用上面那种1个字节的比较。所以这里做了改进,其他都和上面那篇文章介绍一样。并且采用的是上面文章介绍的最后一个改进算法,如下

详细介绍 还是去看看那个文章。

225intRle_Decode_O(unsignedchar*inbuf,intinSize,unsignedchar*outbuf,intonuBufSize)

226{

227unsignedchar*src=inbuf;

228inti;

229intdecSize=0;

230intcount=0;

231

232while(src<(inbuf+inSize))

233{

234 unsignedcharsign=*src++;

235 intcount=sign&0x3F;

236 if((decSize+count)>onuBufSize)/*输出缓冲区空间不够了*/

237 {

238 return-1;

239 }

240 if((sign&0x80)==0x80)/*连续重复数据标志*/

241 {

242 for(i=0;i

243 {

244 outbuf[decSize++]=*src;

245 }

246 src++;

247 }

248 else

249 {

250 for(i=0;i

251 {

252 outbuf[decSize++]=*src++;

253 }

254 }

255}

256

257returndecSize;

258}



3、单片机里面实现的方法



下面是在单片机里面实现的代码,不过这里一个问题频繁读取 刷屏速度比较慢 测试发现要100多MS,后面改进了算法 ,并且采用FATFS管理SPI FLASH 测试发现28ms可以显示一张图片(不过颜色不是很复杂 复杂时间会更长)


void lcd_display_image(uint32_t epromoffset)//保存在flsah中的地址
{
uint8_t buf[1024] = {0};//定义缓冲区大小
uint32_t totlelen = 0;//用于保存数据总长度
uint32_t index = 0;//索引
uint8_t temp = 0;//临时存放数据
uint8_t count = 0;//连续数据个数
uint16_t colour = 0;//保存颜色用如液晶显示
uint8_t i = 0;
SPI_FLASH_ReadBuffer(buf,epromoffset, 3);//前3个字节保存数据的总长度
epromoffset = epromoffset + 3;//flash 地址偏移3
totlelen = buf[0] << 16 " buf[1] << 8 | buf[2];//计算得到总长度
LCD_SetWindows(0,319,0,239);//320 240 设置LCD显示区域
while(index < totlelen)//判断 索引和文件总长度 退出的条件
{
SPI_FLASH_ReadBuffer(buf,epromoffset, 1);//读数据
epromoffset++;//flash 地址自加
temp = buf[0];//得到读取的数据
index++;//索引自加
count = temp & 0x7f;//得到连续的个数
if((temp & 0x80) == 0x80)//判断是否是相同 还是不同的 连续
{
SPI_FLASH_ReadBuffer(buf,epromoffset, 2);//相同连续 读取两个字节
epromoffset = epromoffset + 2;
index = index + 2;
colour = buf[0] << 8 | buf[1];//组合成颜色 RGB 565
for(i = 0;i < count;i++)
{
LCD_RAM = colour;//显示 FSMC
}
}
else//不相同 连续
{
//SPI_FLASH_ReadBuffer(buf,epromoffset, count *2);
//读取 count*2个数据 2个数据组成一个颜色数据 count 个颜色数据 所以要*2
SPI_DMA_FLASH_ReadBuffer_1(epromoffset,buf,count *2);
epromoffset = epromoffset + count * 2;//地址偏移
index = index + count * 2;
for(i = 0; i < count * 2;i= i+2)
{
LCD_RAM = buf[i] << 8 | buf[i+1];//显示
}
}
}
index = 0;
}


改进后的单片机程序

void SPI_Flash_lcd_Fatfs_image(const char *filename)//文件名
{
uint8_t buf[piece_size] = {0};//开辟一个大的缓冲区


uint32_t epromoffset = 0;
uint32_t totlelen = 0;
uint32_t index = 0;
uint8_t temp = 0;
uint32_t num = 0;
uint8_t count = 0;
uint16_t colour = 0;
uint8_t i = 0,j = 0;
uint16_t write_buf = 0;
uint16_t read_buf = 0;


SPI_Flash_ReadFileData_add(filename,buf,epromoffset,3,&num);//读取总长度 采用FATFA
epromoffset = epromoffset + 3;
totlelen = buf[0] << 16 | buf[1] << 8 | buf[2];
LCD_SetWindows(0,319,0,239);//320 240

while(index < totlelen)
{
if(totlelen - index > piece_size)
{


SPI_Flash_ReadFileData_add(filename,buf,epromoffset,piece_size,&num);//读取数据保存到缓冲区
epromoffset = epromoffset + piece_size;
read_buf = piece_size;
index = index + piece_size;
}
else
{
SPI_Flash_ReadFileData_add(filename,buf,epromoffset,totlelen - index,&num);
epromoffset = epromoffset + totlelen - index;
read_buf = totlelen - index;
index = totlelen;
}
while(write_buf < read_buf)
{
temp = buf[write_buf];
write_buf++;
count = temp & 0x7f;
if((temp & 0x80) == 0x80)
{
if((read_buf- write_buf) > 2)
{
colour = buf[write_buf] << 8 | buf[write_buf+1];
write_buf = write_buf + 2;
}
else
{
write_buf = write_buf + 2;
}
for(i = 0;i < count;i++)
{
LCD_RAM = colour;
}
}
else
{
count = count *2;
j = 0;
for(i = 0; i < count ;i= i+2)
{
if((read_buf - write_buf) > 2)
{
colour = buf[write_buf] << 8 | buf[write_buf+1];
LCD_RAM = colour;
write_buf = write_buf +2;
}
else
{
SPI_Flash_ReadFileData_add(filename,buf,epromoffset + j,2,&num);//这里有点问题 需要改进 假如缓冲区数据读完 就会出现点问题
j = j + 2;
LCD_RAM =buf[0] << 8 | buf[1];
write_buf = write_buf +2;
}
}
}
}
write_buf= write_buf %piece_size;
}


}

这个程序还有点小

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

单片机是一种嵌入式系统,它是一块集成电路芯片,内部包含了处理器、存储器和输入输出接口等功能。

关键字: 单片机 编写程序 嵌入式

在现代电子技术的快速发展中,单片机以其高度的集成性、稳定性和可靠性,在工业自动化、智能家居、医疗设备、航空航天等诸多领域得到了广泛应用。S32单片机,作为其中的佼佼者,其引脚功能丰富多样,是实现与外部设备通信、控制、数据...

关键字: s32单片机引脚 单片机

在微控制器领域,MSP430与STM32无疑是两颗璀璨的明星。它们各自凭借其独特的技术特点和广泛的应用领域,在市场上占据了重要的位置。本文将深入解析MSP430与STM32之间的区别,探讨它们在不同应用场景下的优势和局限...

关键字: MSP430 STM32 单片机

该系列产品有助于嵌入式设计人员在更广泛的系统中轻松实现USB功能

关键字: 单片机 嵌入式设计 USB

单片机编程语言是程序员与微控制器进行交流的桥梁,它们构成了单片机系统的软件开发基石,决定着如何有效、高效地控制和管理单片机的各项资源。随着微控制器技术的不断发展,针对不同应用场景的需求,形成了丰富多样的编程语言体系。本文...

关键字: 单片机 微控制器

单片机,全称为“单片微型计算机”或“微控制器”(Microcontroller Unit,简称MCU),是一种高度集成化的电子器件,它是现代科技领域的关键组件,尤其在自动化控制、物联网、消费电子、汽车电子、工业控制等领域...

关键字: 单片机 MCU

STM32是由意法半导体公司(STMicroelectronics)推出的基于ARM Cortex-M内核的32位微控制器系列,以其高性能、低功耗、丰富的外设接口和强大的生态系统深受广大嵌入式开发者喜爱。本文将详细介绍S...

关键字: STM32 单片机

在当前的科技浪潮中,单片机作为嵌入式系统的重要组成部分,正以其强大的功能和广泛的应用领域受到越来越多行业的青睐。在众多单片机中,W79E2051以其卓越的性能和稳定的工作特性,成为市场上的明星产品。本文将深入探讨W79E...

关键字: 单片机 w79e2051单片机

单片机,又称为微控制器或微处理器,是现代电子设备中的核心部件之一。它集成了中央处理器、存储器、输入输出接口等电路,通过外部信号引脚与外部设备进行通信,实现对设备的控制和管理。本文将详细介绍单片机的外部信号引脚名称及其功能...

关键字: 单片机 微控制器 中央处理器

随着科技的飞速发展,单片机和嵌入式系统在现代电子设备中的应用越来越广泛。它们不仅提高了设备的智能化水平,还推动了各行各业的创新与发展。在单片机和嵌入式系统的开发中,编程语言的选择至关重要。本文将深入探讨单片机和嵌入式系统...

关键字: 单片机 嵌入式系统 电子设备
关闭
关闭