TFT-LCD屏幕读取Flash芯片图片资源并显示

news2024/11/25 17:15:59

TFT-LCD屏幕读取Flash芯片图片资源并显示

在前面用TFT-LCD显示图片的实验中,由于图片资源过大,240 * 320 的图片大小为150K,而STM32F103ZET6的内部Flash才512K,最多能放三张图片,所以这次将图片放到外部Flash中,外部Flash芯片为W25Q64,有64Mbit,即8Mbyte,因为1M = 1024KB,所以8M = 8192K,8192K / 150K = 54,所以大概能放54张240 * 320的图片

使用之前写好的SPI_Flash.c源文件和SPI_Flash.h头文件,增加一个读取图片的函数

SPI_Flash.h

先在头文件中根据图片大小定好每张图片存放在Flash中的位置

//3张图片在外部Flash的地址,共占用150k * 3 = 450k
#define Pic_Size          (uint32_t)153600
#define Flash_Pic1_Addr   (uint32_t)0                                 //第一张图片的地址
#define Flash_Pic2_Addr   (uint32_t)Flash_Pic1_Addr+Pic_Size          //第二张图片的地址
#define Flash_Pic3_Addr   (uint32_t)Flash_Pic2_Addr+Pic_Size          //第三张图片的地址

SPI_Flash.c

在对Flash芯片操作中添加读取图片资源到TFT-LCD屏幕显示的函数

/**
 * @name   TranferPicturetoTFT_LCD
 * @brief  读取外部Flash图片资源到TFT-LCD显示
 * @param  Pic_Num:图片序号
 * @retval None  
 */
static void TranferPicturetoTFT_LCD(uint8_t Pic_Num)
{
    uint32_t uiDataLength = Pic_Size;
    uint32_t uiPic_Addr = NULL;
    uint16_t usPic_Data;
	//判断是第几张图片,设置存放位置
    switch (Pic_Num)
    {
        case 1: uiPic_Addr = Flash_Pic1_Addr; break;
        case 2: uiPic_Addr = Flash_Pic2_Addr; break;
        case 3: uiPic_Addr = Flash_Pic3_Addr; break;
        default: uiPic_Addr = Flash_Pic1_Addr; break;
    }

    //选择Flash芯片:CS输出低电平
    CLR_SPI_Flash_CS;

    //发送命令,读取数据
    SPI_Flash_WriteByte(W25X_ReadData);
    //发送地址高字节
    SPI_Flash_WriteByte((uiPic_Addr & 0xFF0000) >> 16);
    //发送地址中字节
    SPI_Flash_WriteByte((uiPic_Addr & 0xFF00) >> 8);
    //发送地址低字节
    SPI_Flash_WriteByte(uiPic_Addr & 0xFF);

    //设置窗口大小
    TFT_LCD.LCD_SetWindows(0,0,LCD_WIGHT,LCD_HIGHT);

    //开始传输数据
    while (uiDataLength)
    {
        //从Flash读取数据,组成十六位数据
        usPic_Data = SPI_Flash_ReadByte();
        usPic_Data <<= 8;
        usPic_Data += SPI_Flash_ReadByte();

        //将数据写入到TFT-LCD屏幕中
        LCD_WRITE_DATA(usPic_Data);
        uiDataLength-=2;
    }

    //禁用Flash芯片:CS引脚输出高电平
    SET_SPI_Flash_CS;
}

Picture1.h

图片数据

const unsigned char gImage_Picture1[153600] = { /* 0X10,0X10,0X00,0XF0,0X01,0X40,0X01,0X1B, */
0XA4,0X0C,0X93,0XCB,0XA4,0X2D,0XAC,0X8E,0XA4,0X0C,0XA4,0X0C,0XB4,0X8E,0XBC,0XAE,
0XAC,0X2D,0XBC,0XAE,0XC4,0XEF,0X8B,0X49,0X8B,0X48,0XAC,0X2C,0XC4,0XCE,0XC4,0XAE,

System.c

主函数中先将图片写入到外部Flash中,并在屏幕上显示写入过程,等待写入完成

/*
* @name   Run
* @brief  系统运行
* @param  Nonee
* @retval None   
*/
static void Run()
{
  /*************** 将内部Flash的图片保存到外部Flash芯片中 ************** */
   uint32_t uiIndex;
   const uint8_t * pucic = NULL;
   //擦除整个扇区
   TFT_LCD.LCD_ShowString(0,48,"Erase total flash chip...",Color_GRAY,Color_RED,ASCII_font_24);
   SPI_Flash.SPI_Flash_ChipSector();

   //写入第一张图片
   TFT_LCD.LCD_ShowString(0,72,"Writing the first image...",Color_GRAY,Color_RED,ASCII_font_24);
   pucic = gImage_Picture1;
   //写入不定长数据
   for(uiIndex = 0; uiIndex < Pic_Size; uiIndex++)
   {
     SPI_Flash.SPI_Flash_WriteUnfixed((uint8_t*)pucic,(Flash_Pic1_Addr+uiIndex),1);
     pucic++;
   }

   //写入第二张图片
   TFT_LCD.LCD_ShowString(0,100,"Writing the second image...",Color_GRAY,Color_RED,ASCII_font_24);
   pucic = gImage_Picture2;
   //写入不定长数据
	 for(uiIndex = 0; uiIndex < Pic_Size; uiIndex++)
   {
     SPI_Flash.SPI_Flash_WriteUnfixed((uint8_t*)pucic,(Flash_Pic2_Addr+uiIndex),1);
     pucic++;
   }

   //写入第三张图片
   TFT_LCD.LCD_ShowString(0,130,"Writing the third image...",Color_GRAY,Color_RED,ASCII_font_24);
   pucic = gImage_Picture3;
   //写入不定长数据
   for(uiIndex = 0; uiIndex < Pic_Size; uiIndex++)
   {
     SPI_Flash.SPI_Flash_WriteUnfixed((uint8_t*)pucic,(Flash_Pic3_Addr+uiIndex),1);
     pucic++;
   }
   //写入完成
   TFT_LCD.LCD_ShowString(0,157,"Writing finish",Color_GRAY,Color_RED,ASCII_font_24);

   while(1);
}

写入过程

在这里插入图片描述

读出Flash中的图片

将主函数中写入图片的那部分去掉,调用前面写的TranferPicturetoTFT_LCD函数,读出图片,因为写入了三张,所以也读出三张

/*
* @name   Run
* @brief  系统运行
* @param  Nonee
* @retval None   
*/
static void Run()
{
  /*************** 从外部Flash中读取图片数据,并在TFT-LCD屏上显示 ************** */
  SPI_Flash.TranferPicturetoTFT_LCD(1);
  HAL_Delay(1000);
  SPI_Flash.TranferPicturetoTFT_LCD(2);
  HAL_Delay(1000);
  SPI_Flash.TranferPicturetoTFT_LCD(3);
  HAL_Delay(1000);
}

显示效果

三张图片每隔1秒进行切换显示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/20675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java八股文总结】之Redis数据库

文章目录Redis 数据库一、Redis基础1、Redis应用场景2、Redis数据类型3、Redis常用命令4、Redis为什么速度快&#xff1f;5、Redis和Memcached的区别和共同点6、Redis和MySQL的区别&#xff1f;二、高可用1、主从复制Q&#xff1a;主从复制主要的作用?2、Redis主从复制原理Red…

Cadence之Allegro:蛇形与差分等长

文章目录 一、三种等长方法二、直接等长法设置教程1、差分设置2、analysis设置三、pin-pair法设置教程一、三种等长方法 直接等长法 适用pin和pin之间没有容抗和阻抗的情况,即pin和pin之间只有一根线、没有电阻和电容的时候才可以使用这种方法。 pin-pair法 建立Sigxplorer模形…

基于stm32的光照强度检测智能窗帘系统

资料编号&#xff1a;098 下面是相关功能视频演示&#xff1a; 98-基于stm32的光照强度检测智能窗帘系统Proteus仿真&#xff08;源码仿真全套资料&#xff09;功能介绍&#xff1a; 检测当前的光照强度&#xff0c;LCD1602显示&#xff0c;并且可以自动打开关闭窗帘&#xf…

Tomcat AJP 文件包含漏洞(CVE-2020-1938)

目录 1&#xff0e;漏洞简介 2、AJP13 协议介绍 Tomcat 主要有两大功能&#xff1a; 3&#xff0e;Tomcat 远程文件包含漏洞分析 4&#xff0e;漏洞复现 5、漏洞分析 6&#xff0e;RCE 实现的原理 1&#xff0e;漏洞简介 2020 年 2 月 20 日&#xff0c;公开CNVD 的漏洞公…

【ACL 2022】用于多标签文本分类的对比学习增强最近邻机制

论文地址&#xff1a;https://aclanthology.org/2022.acl-short.75.pdf 1. 摘要 多标签文本分类&#xff08;MLTC&#xff09;是自然语言处理中的一项基本且具有挑战性的任务。以往的研究主要集中在学习文本表示和建模标签相关性上。然而&#xff0c;在预测特定文本的标签时&…

玩转SQL语句之group by 多字段分组查询与having子句,一篇解决你的疑惑!

sql语句group by使用详解group by的基本语法基本语法什么是分组查询(一个字段)多个字段的分组查询1.两个字段的分组查询2.三个字段及N个字段进行分组查询having子句的使用基本语法having是干什么的演示分组查询select关键字后面列名书写的注意事项group by的基本语法 基本语法…

入门必写项目之图书管理系统(分析详解+完美运行+代码可拿)

文章目录一、需求分析二、思路分析三、包分类四、模块代码展示1.1书籍类&#xff08;Book&#xff09;实现1.2书架类&#xff08;BookList类&#xff09;实现2.1功能接口&#xff08;IOperation&#xff09;实现2.2增加图书&#xff08;Addoperation&#xff09;实现2.3删除图书…

家庭实验室系列文章-电脑如何配置网络唤醒 (WOL)?

前言 其实这个专题很久很久之前就想写了&#xff0c;但是一直因为各种原因拖着没动笔。 因为没有资格&#xff0c;也没有钱在一线城市买房 (&#x1f602;&#x1f602;&#x1f602;); 但是在要结婚之前&#xff0c;婚房又是刚需。 我和太太最终一起在一线城市周边的某二线城…

Pyspark学习笔记小总

pyspark官方文档: https://spark.apache.org/docs/latest/api/python/index.html pyspark案例教程: https://sparkbyexamples.com/pyspark-tutorial/ 1. 写在前面 这篇文章记录下最近学习的有关Pyspark以及用spark sql去处理大规模数据的一些常用语法&#xff0c;之前总觉得p…

中小企业办公自动化系统设计与实现(SSH)

目 录 摘 要 I ABSTRACT II 目 录 IV 第1章 绪论 1 1.1 课题背景 1 1.1.1 办公自动化概述 1 1.1.2 中小企业办公模式的现状 2 1.2 研究意义 3 1.3 设计技术及开发环境 5 1.3.1 设计技术 5 1.3.2 开发环境 7 第2章 可行性分析 9 2.1 组织和管理可行性 9 2.2 经济可行性 9 2.3 技…

动态规划模板总结(1)

动态规划思想(1) 背包问题 ​ 分类&#xff1a; 01 背包问题 ​ 含义&#xff1a;每个物体最多选1次&#xff0c;在不超过总体积的情况下价值最大图解&#xff1a; f(i,j)表示的是集合的某种属性&#xff0c;是个值。 集合是所有选法 i 只从前i个中选 朴素实现 #include&…

ElasticSearch是什么?ElasticSearch在SpringBoot中怎么用?SpringBoot整合ElasticSearch

写在前面&#xff1a; 继续记录自己的SpringBoot学习之旅&#xff0c;这次是SpringBoot应用相关知识学习记录。若看不懂则建议先看前几篇博客&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 3.4.3.4 ElasticSearch(ES) 3.4.3.4.1 介绍 是一个…

MySQL JDBC编程

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;MySQL &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 文章目录前置知识APIJDBC的使用安装数据库代码插入操作查找操作前置知识 API API(Application Program Interface)被定义为应用程…

金属纳米颗粒图像分割和计数

代码下载链接&#xff0c;直接上程序运行的效果&#xff1a; 为了便于大家学习&#xff0c;把原图也都贴上了&#xff1a;

乐趣国学—品读《弟子规》中的“亲仁”之道

文章目录亲仁同是人 类不齐 流俗众 仁者希果仁者 人多畏 言不讳 色不媚能亲仁 无限好 德日进 过日少不亲仁 无限害 小人进 百事坏亲仁 “亲仁”&#xff0c;亲是亲近、学习的意思&#xff0c;亲近那些有道德、有学问、有人生境界、有情操的人&#xff0c;这是讲择师。一个人的学…

【Redis】配置项与发布订阅

一、配置项 redis相关配置项都存放在redis.conf文件中&#xff0c;暂时只列举常见的几个&#xff0c;其余的工作中用到再回来更新 1、网络 bind&#xff1a;指定redis只能接受来自此IP绑定的网卡的请求&#xff0c;注意此默认值默认外网是不可访问的&#xff0c;如果想要开启…

Unity3D制作塔防类游戏

演示 功能简介 制作细节详解 演示 资源包:链接&#xff1a;https://pan.baidu.com/s/15MMtYeKkNk5xChvCx0EckQ?pwdd1ub 提取码&#xff1a;d1ub 对应视频教学:01-开始介绍和创建工程_哔哩哔哩_bilibili 功能简介 分为蓝&#xff0c;紫&#xff0c;粉&#xff0c;红四…

[iOS]UI分析工具Reveal

Reveal是ITTY BITTY发布的UI分析工具&#xff0c;可以很直观的查看App的UI布局。 去官网下载安装Reveal&#xff0c;启动后样式如下。 下面介绍一下如何在非越狱设备和越狱设备上用Reveal工具分析UI 一、非越狱设备用Reveal分析UI 1.安装MonkeyDev 安装流程可查看前文[iOS]…

2. Java线程模型

1. 操作系统线程 无论使用何种编程语言编写多线程程序&#xff0c;最终都是通过调用操作系统的线程来执行任务。线程是CPU调度的最小执行单元。 线程有多种实现方式&#xff0c;常见的有&#xff1a;内核线程、用户线程、混合线程。 不同线程模型的主要区别在于线程的调度方不…

bat脚本启动Java服务

bat脚本启动Java服务1.终端cmd窗口运行jar2. bat脚本启动jar包3.后台启动bat脚本4. 运行bat只启动一次jar服务及停止脚本5.注意事项6.所用资源1.终端cmd窗口运行jar Java项目一般会被打包成jar后启动&#xff0c;在windows系统中可以通过终端窗口cmd启动jar包&#xff0c;即在…