【正点原子STM32连载】 第五十二章 图片显示实验摘自【正点原子】APM32F407最小系统板使用指南

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html##

第五十二章 图片显示实验

本章将介绍使用APM32F407软件解码BMP、JPG和GIF等格式的图片,并在LCD进行显示。通过本章的学习,读者将学习到图片解码库的使用。
52.1 硬件设计
52.2 程序设计
52.3 下载验证

52.1 硬件设计
52.1.1 例程功能

  1. 程序运行后,会显示SD卡中PICTURE文件夹中的第一张图片(支持bmp、jpg、jpeg或gif格式)
  2. 按下KEY0或KEY_UP按键,可分别进行切换上一张图片和切换下一张图片的操作
  3. 可通过USMART操作解码任意路径下的图片
  4. LED0闪烁,指示程序正在运行
    52.1.2 硬件资源
  5. LED
    LED0 - PF9
  6. 按键
    KEY0 - PE4
    KEY_UP - PA0
  7. USART1(PA9、PA10连接至板载USB转串口芯片上)
  8. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
  9. SD卡(SDIO驱动)
  10. NOR Flash(SPI驱动)
    52.1.3 原理图
    本章实验使用的图片解码库为软件库,因此没有对应的连接原理图。
    52.2 程序设计
    52.2.1 图片解码库的使用
    正点原子提供的图片解码库包含了九个文件,分别为:piclib.c、piclib.h、bmp.c、bmp.h、gif.c、gif.h、tjpgd.c、tjpgd.h、tjpgdcnf.h,这几个文件的描述,如下表所示:
    文件 描述
    piclib.c
    piclib.h 正点原子图片解码库文件,主要提供图片解码库和画图的初始化和根据文件类型自动解码并画图的函数等
    bmp.c
    bmp.h 正点原子BMP图片编解码库,主要用于解码BMP图片文件
    gif.c
    gif.h 正点原子GIF图片解码库,主要用于解码GIF图片文件
    tjpgd.c
    tjpgd.h
    tjpgdcnf.h TjpgDec(JPEG图片解码库)的源文件和配置文件,为了方便使用,添加了用于正点原子图片解码库的函数
    表52.2.1.1 图片解码库各文件描述
    以上图片解码库的九个文件,在本章实验配套的实验例程中都已提供,并且针对正点原子APM32F407最小系统板软硬件进行了移植适配,用户在使用时,仅需将这九个文件添加到自己的工程即可,如下所示:
    在这里插入图片描述

图52.2.1.1 正点原子图片解码库文件
52.2.2 实验应用代码
本章实验的应用代码,如下所示:

int main(void)
{
    uint8_t res;
    DIR picdir;
    uint16_t totpicnum;
    FILINFO *picfileinfo;
    char *pname;
    uint32_t *picoffsettbl;
    uint16_t curindex;
    uint16_t temp;
    uint8_t t = 0;
    uint8_t key;
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 设置中断优先级分组为组3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系统时钟 */
    delay_init(168);										/* 初始化延时功能 */
    usart_init(115200);									/* 初始化串口 */
    usmart_dev.init(84);								/* 初始化USMART */
    led_init()											/* 初始化LED */
    key_init()											/* 初始化按键 */
    lcd_init()											/* 初始化LCD */
    my_mem_init(SRAMIN);								/* 初始化内部SRAM内存池 */
    my_mem_init(SRAMCCM);								/* 初始化CCM内存池 */
    exfuns_init()										/* 为exfuns申请内存 */
    f_mount(fs[0], "0:", 1);							/* 挂载SD卡 */
    f_mount(fs[1], "1:", 1);							/* 挂载NOR Flash */
    
    while (sd_init() != SD_OK)							/* 初始化SD卡 */
    {
    		/* SD卡初始化失败,代码省略 */
    }
    
    /* 检查字库,代码省略 */
    
    text_show_string(30,  50, 200, 16, "正点原子APM32开发板", 16, 0, RED);
    text_show_string(30,  70, 200, 16, "图片显示实验", 16, 0, RED);
    text_show_string(30,  90, 200, 16, "KEY0: PREV", 16, 0, RED);
    text_show_string(30, 110, 200, 16, "KEY_UP: NEXT", 16, 0, RED);
    text_show_string(30, 130, 200, 16, "正点原子@ALIENTEK", 16, 0, RED);
    
    /* 打开图片文件夹 */
    while (f_opendir(&picdir, "0:/PICTURE") != FR_OK)
    {
    		/* PICTURE文件夹错误,代码省略 */
    }
    
    /* 获取有效图片文件数量 */
    totpicnum = pic_get_tnum("0:/PICTURE");
    while (totpicnum == 0)
    {
    		/* 没有图片文件,代码省略 */
    }
    
    /* 申请内存 */
    picfileinfo = (FILINFO *)mymalloc(SRAMIN, sizeof(FILINFO));
    pname = (char *)mymalloc(SRAMIN, FF_MAX_LFN * 2 + 1);
    picoffsettbl = (uint32_t *)mymalloc(SRAMIN, 4 * totpicnum);
    while ((picfileinfo == NULL) || (pname == NULL) || (picoffsettbl == NULL))
    {
    		/* 内存申请失败,代码省略 */
    }
    
    /* 打开目录 */
    res = (uint8_t)f_opendir(&picdir, "0:/PICTURE");
    if (res == 0)
    {
    		curindex = 0;
    		while (1)
    		{
    			temp = picdir.dptr;								/* 记录当前dptr偏移 */
    			res = (uint8_t)f_readdir(&picdir, picfileinfo);/* 读取下一个文件 */
    			if ((res != 0) || (picfileinfo->fname[0] == 0))/* 错误或到末尾,退出 */
    			{
    				break;
    			}
    			
    			res = exfuns_file_type(picfileinfo->fname);
    			if ((res & 0xF0) == 0x50)						/* 是图片文件 */
    			{
    				picoffsettbl[curindex] = temp;				/* 记录索引 */
    				curindex++;
    			}
    		}
    }
    
    text_show_string(30, 150, 240, 16, "开始显示...", 16, 0, RED);
    delay_ms(1500);
    piclib_init();											/* 初始化画图 */
    curindex = 0;											/* 从0开始显示 */
    /* 打开目录 */
    res = (uint8_t)f_opendir(&picdir, (const TCHAR *)"0:/PICTURE");
    while (res == 0)
    {
    		/* 改变当前目录索引 */
    		dir_sdi(&picdir, picoffsettbl[curindex]);
    		/* 读取目录的下一个文件 */
    		res = (uint8_t)f_readdir(&picdir, picfileinfo);
    		/* 错误或到末尾,退出 */
    		if ((res != 0) || (picfileinfo->fname[0] == 0))
    		{
    			break;
    		}
    		
    		/* 复制路径(目录) */
    		strcpy((char *)pname, "0:/PICTURE/");
    		/* 将文件名接在后面 */
    		strcat((char *)pname, (const char *)picfileinfo->fname);
    		lcd_clear(BLACK);
    		/* 显示图片 */
    		piclib_ai_load_picfile(pname, 0, 0, lcddev.width, lcddev.height, 1);
    		/* 显示图片名字 */
    		text_show_string(2, 2, lcddev.width, 16, (char *)pname, 16, 1, RED);
    		
    		while (1)
    		{
    			t++;
    			key = key_scan(0);
    			
    			if (key == KEY0_PRES)		/* 上一张 */
    			{
    				if (curindex != 0)
    				{
    					curindex--;
    				}
    				else
    				{
    					curindex = totpicnum - 1;
    				}
    				break;
    			}
    			else if (key == WKUP_PRES)	/* 下一张 */
    			{
    				curindex++;
    				if (curindex >= totpicnum)
    				{
    					curindex = 0;
    				}
    				break;
    			}
    			
    			if (t == 20)
    			{
    				LED0_TOGGLE();
    				t = 0;
    			}
    			
    			delay_ms(10);
    		}
    }
    
    /* 释放内存 */
    myfree(SRAMIN, picfileinfo);
    myfree(SRAMIN, pname);
    myfree(SRAMIN, picoffsettbl);
    
    while (1);
}

从上面的代码中可以看出,本实验的应用代码中,在完成文件系统、SD卡等一些列必要的初始化后,便会统计SD卡中PICTURE文件夹下图片的数量和路径,然后根据KEY0和KEY_UP按键,调用函数piclib_ai_load_picfile()切换显示SD卡PICTURE文件夹中的图片文件至LCD上。
本章实验所需的图片文件可以在A盘5,SD卡根目录文件PICTURE中找到,建议将A盘5,SD卡根目录文件中的所有文件按照该目录的目录结构复制进SD卡,方便后续实验的使用。
52.3 下载验证
在完成编译和烧录操作后,将根目录存放了A盘5,SD卡根目录文件中文件的SD卡插入开发板板载的SD卡卡座后,便能看到LCD上显示了SD卡PICTURE文件夹中的图片,并且按下KEY0按键或KEY_UP按键可以切换LCD显示SD卡PICTURE文件夹中的上一张或下一张图片。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何为VM虚拟机添加D盘

文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 前言 在虚拟机上安装Windows10 系统后&…

【C语法学习】23 - strlen()函数

文章目录 1 函数原型2 参数3 返回值4 示例4.1 示例1 1 函数原型 strlen():计算指针str所指向的字符串的长度,函数原型如下: size_t strlen(const char *str);2 参数 strlen()函数只有一个参数str: 参数str是指向待计算长度的字…

拟液态加载器

效果展示 CSS 知识点 SVG 的 feGaussianBlur、feColorMatrix 属性运用animation 属性运用filter 联合 SVG 使用 整体页面结构 <div class"container"><h2>Milk</h2><!-- 加载器的圆点部分 --><div class"loader"><spa…

PostGIS学习教程二:PostGIS安装和创建空间数据库

一、安装PostgreSQL 在安装PostGIS前首先必须安装PostgreSQL&#xff0c;然后在安装好的Stack Builder中选择安装PostGIS组件。 PostgreSQL安装文件下载地址是https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 这里使用的PostgreSQL版本是9.6。 双击…

微信个人号二次开发之检测好友

简要描述&#xff1a; 检测好友状态 请求URL&#xff1a; http://域名地址/userPrivacySettings 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选…

性能压测工具:Locust详解

一、Locust介绍 开源性能测试工具https://www.locust.io/&#xff0c;基于Python的性能压测工具&#xff0c;使用Python代码来定义用户行为&#xff0c;模拟百万计的并发用户访问。每个测试用户的行为由您定义&#xff0c;并且通过Web UI实时监控聚集过程。 压力发生器作为性…

thinkPHP8 调试

方法一&#xff1a; config/app.php 把‘config/app.php’ 里面的 ‘show_error_msg’ > false, 改成true; 这样如果网页找不到内容就会显示出具体原因 方法二&#xff1a;.example.env 重命名 为 .env 修改成.env&#xff0c;修改后如果没有找到方法&#xff0c;则会提示…

C语言—i++、++i、条件运算符、goto语句、注释

i和i #include <stdio.h> int main() {int i5,j;j i;printf("i%d,j%d\n", i, j);i 5;j i;printf("i%d,j%d\n", i, j);system("pause");return 0;}i6,j6 i6,j5 请按任意键继续. . .条件运算符 goto语句 #include <stdio.h> int …

Sui主网升级至V1.13.0版本

Sui主网现已升级至V1.13.0版本&#xff0c;同时Sui协议升级至30版本。其他升级要点如下所示&#xff1a; #14348 在运行Prover时&#xff0c;现在会打印有关Sui当前Move Prover支持水平的警告。 #13639 加强验证节点保护机制&#xff0c;防止在以下情况发生时接受交易&…

无人机交付:跨境电商的数字化未来

随着科技的不断进步&#xff0c;跨境电商行业正经历着前所未有的数字化变革。其中&#xff0c;无人机交付正成为这一领域的未来之路&#xff0c;为电商企业和消费者带来了新的便利和机遇。本文将深入探讨无人机交付在跨境电商中的应用&#xff0c;以及它如何塑造数字化未来。 无…

RocketMQ 如何保证消息正常【投递】和【消费】

消息整体处理过程&#xff0c;这里我们将消息的整体处理阶段分为3个阶段进行分析&#xff1a;1、Producer发送消息阶段。 2、Broker处理消息阶段。 3、Consumer消费消息阶段。一、Producer发送消息阶段 1、安全机制保障1&#xff0c;发送方式。 1、同步发送 2、异步发送 3、O…

展会预告 | 图扑邀您相约高交会-全球清洁能源创新博览会

第二十五届中国国际高新技术成果交易会(简称“高交会”)将在深圳盛大开幕。高交会由商务部、科学技术部、工业和信息化部、国家发展改革委、农业农村部、国家知识产权局、中国科学院、中国工程院和深圳市人民政府共同举办。是目前中国规模最大、最具影响力的科技类展会。 图扑软…

【沐风老师】3dMax一键多边形窗插件PolyWindow使用教程

3dMax一键多边形窗插件使用教程 3dMax一键多边形窗插件PolyWindow&#xff0c;将选择的多边形面一键转化为窗模型。你可以通过编辑多边形的线框&#xff08;边&#xff09;来定义窗子的分格形状&#xff0c;这款插件可以大大提高艺术家建筑建模、室内建模制作窗子的速度。 可适…

第一章:线性查找

系列文章目录 文章目录 系列文章目录前言一、线性查找二、实现查找算法三、循环不变量四、复杂度分析五、常见复杂度六、测试算法性能总结 前言 从线性查找入手算法。 一、线性查找 线性查找目的在线性数据结构中一个一个查找目标元素输入数组和目标元素输出目标元素所在的索…

新能源汽车三电系统上的VDA接口在操作空间有限时如何快速密封与连接

针对新能源汽车三电系统上的VDA接口的快速密封与连接&#xff0c;格雷希尔GripSeal快速接头有其对应的G90系列&#xff0c;但随着现在有些新能源汽车体型越来越小&#xff0c;其三电系统的体积也越来越小&#xff0c;相对应的它们各个接口之间的距离也就越来越近&#xff0c;其…

【MySQL】对表结构进行增删查改的操作

表的操作 前言正式开始建表查看表show tables;desc xxx;show create table xxx; 修改表修改表名 rename to对表结构进行修改新增一个列 add 对指定列的属性做修改 modify修改列名 change 删除某列 drop 删除表 drop 前言 前一篇讲了库相关的操作&#xff0c;如果你不太懂&…

数字双向码、密勒码、传号反转(CMI)码、AMI、HDB3的编码规则和功率谱解析+眼图

数字双向码、密勒码、传号反转&#xff08;CMI&#xff09;码、AMI、HDB3的编码规则和功率谱解析眼图 本文主要涉及数字双向码、密勒码、传号反转&#xff08;CMI&#xff09;码、AMI、HDB3的编码规则,优缺点和功率谱解析以及眼图的分析。关于简单二元码大家可以参考简单二元码…

机带RAM:16G(可用2G)

文章目录 机带RAM 16G&#xff08;可用2G&#xff09;一 、问题描述二、解决办法2.1 最大内存设置 2.2 系统激活重启 机带RAM 16G&#xff08;可用2G&#xff09; 一 、问题描述 戴尔商务计算机 Windows11系统 16GB内存 之前一直是正常使用的&#xff0c;突然有一天内存占用率…

150. 逆波兰表达式求值

150. 逆波兰表达式求值 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;错误经验吸取 原题链接&#xff1a; 150. 逆波兰表达式求值 https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/ 完成情况&#xff1a…

Mac笔记本打开Outlook提示:您需要最新的版本的Outlook才能使用此数据库

Mac笔记本打开Outlook提示&#xff1a;您需要最新的版本的Outlook才能使用此数据库 故障现象&#xff1a; 卸载旧的office安装新版的office&#xff0c;打开outlook提示&#xff1a;您需要最新的版本的outlook才能使用此数据库。 故障截图&#xff1a; 故障原因&#xff1a;…