OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 538|回复: 0

《M144Z-M3最小系统板使用指南——STM32F103版》第四十九章 图片显示实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4667
金钱
4667
注册时间
2019-5-8
在线时间
1224 小时
发表于 2024-5-21 16:12:26 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-5-20 15:28 编辑

第四十九章 图片显示实验
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板

2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boar ... _mini_sysboard.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32技术交流QQ群:725095144

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

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

49.1 硬件设计
49.1.1 例程功能
1. LCD上不断刷新显示图片
2. 按下WKUP按键可切换至上一个图片
3. 按下KEY0按键可切换至下一个图片
4. LED0闪烁,提示程序正在运行

49.1.2 硬件资源
1. LED
       LED0 - PB5
2. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块
3. 按键
       WKUP - PA0
4. NOR Flash
       SPI2_SCK - PB13
       SPI2_MISO - PB14
       SPI2_MOSI - PB15
       SPI2_CS - PB12
5. SD
       SDIO_D0 - PC8
       SDIO_D1 - PC9
       SDIO_D2 - PC10
       SDIO_D3 - PC11
       SDIO_SCK - PC12
       SDIO_CMD - PD2

49.1.3原理图
本章实验使用的图片解码库为软件库,因此没有对应的连接原理图。

49.2 程序设计
49.2.1 图片解码库的使用
正点原子提供的图片解码库包含了九个文件,分别为:piclib.c、piclib.h、bmp.c、bmp.h、gif.c、gif.h、tjpgd.c、tjpgd.h、tjpgdcnf.h,这几个文件的描述,如下表所示:
QQ截图20240520152725.png
表49.2.1.1 图片解码库各文件描述
以上图片解码库的九个文件,在本章实验配套的实验例程中都已提供,并且针对正点原子M144Z-M3最小系统板STM32F103版软硬件进行了移植适配,用户在使用时,仅需将这九个文件添加到自己的工程即可,如下所示:
       QQ截图20240520152757.png
图49.2.1.1 正点原子图片解码库文件

49.2.2 实验应用代码
本章实验的应用代码,如下所示:
  1. int main(void)
  2. {
  3.     uint8_t t = 0;
  4.     uint8_t key;
  5.     uint8_t res;
  6.     DIRpicdir;
  7.     uint16_t totpicnum;
  8.    FILINFO *picfileinfo;
  9.     char *pname;
  10.     uint32_t *picoffsettbl;
  11.     uint16_t curindex;
  12.     uint16_t temp;
  13.    
  14.    HAL_Init();                         /* 初始化HAL库 */
  15.    sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
  16.    delay_init(72);                     /* 初始化延时 */
  17.    usart_init(115200);                 /* 初始化串口 */
  18.    led_init();                         /* 初始化LED */
  19.    key_init();                         /* 初始化按键 */
  20.    lcd_init();                         /* 初始化LCD */
  21.    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */
  22.    exfuns_init();                      /* 为exfuns申请内存 */
  23.    f_mount(fs[0], "0:", 1);            /* 挂载SD卡 */
  24.    f_mount(fs[1], "1:", 1);            /* 挂载NOR Flash */
  25.    
  26.     /* 检查字库 */
  27.     while (fonts_init() != 0)
  28.     {
  29.          lcd_show_string(30, 30, 200, 16, 16, "STM32", RED);
  30.          
  31.          /* 初始化SD卡 */
  32.          while (sd_init() != 0)
  33.          {
  34.              lcd_show_string(30, 30, 200, 16, 16, "SD CardError!", RED);
  35.              delay_ms(500);
  36.              lcd_show_string(30, 30, 200, 16, 16, "PleaseCheck! ", RED);
  37.              delay_ms(500);
  38.              LED0_TOGGLE();
  39.          }
  40.          
  41.          lcd_show_string(30, 50, 200, 16, 16, "SD CardOK", RED);
  42.          lcd_show_string(30, 70, 200, 16, 16, "FontUpdating...", RED);
  43.          
  44.          /* 更新字库 */
  45.          res = fonts_update_font(30, 90, 16, (uint8_t *)"0:", RED);
  46.          while (res != 0)
  47.          {
  48.              lcd_show_string(30, 90, 200, 16, 16, "Font UpdateFailed!", RED);
  49.              delay_ms(200);
  50.              lcd_show_string(30, 90, 200, 16, 16, "PleaseCheck!      ", RED);
  51.              delay_ms(200);
  52.          }
  53.          
  54.          lcd_show_string(30, 90, 200, 16, 16, "Font UpdateSuccess!   ", RED);
  55.          delay_ms(1500);
  56.          lcd_clear(WHITE);
  57.     }
  58.    
  59.    text_show_string(30, 30, 200, 16, "正点原子STM32开发板", 16, 0, RED);
  60.    text_show_string(30, 50, 200, 16, "图片显示实验", 16, 0, RED);
  61.    text_show_string(30, 70, 200, 16, "ATOM@ALIENTEK", 16, 0, RED);
  62.    text_show_string(30, 90, 200, 16, "WKUP: PREV", 16, 0, RED);
  63.    text_show_string(30, 110, 200, 16, "KEY0: NEXT", 16, 0, RED);
  64.    
  65.     /* 打开图片文件夹 */
  66.     while (f_opendir(&picdir, "0:/PICTURE") != FR_OK)
  67.     {
  68.          text_show_string(30, 130, 200, 16, "PICTURE文件夹错误!", 16, 0, RED);
  69.          delay_ms(200);
  70.          lcd_fill(30, 130, 200, 16, WHITE);
  71.          delay_ms(200);
  72.     }
  73.    
  74.     /* 获取有效图片文件数量 */
  75.    totpicnum = pic_get_tnum("0:/PICTURE");
  76.     while (totpicnum == 0)
  77.     {
  78.          text_show_string(30, 130, 200, 16, "没有图片文件!", 16, 0, RED);
  79.          delay_ms(200);
  80.          lcd_fill(30, 130, 200, 16, WHITE);
  81.          delay_ms(200);
  82.     }
  83.    
  84.     /* 申请内存 */
  85.    picfileinfo = (FILINFO *)mymalloc(SRAMIN, sizeof(FILINFO));
  86.    pname = (char *)mymalloc(SRAMIN, FF_MAX_LFN * 2 + 1);
  87.    picoffsettbl = (uint32_t *)mymalloc(SRAMIN, 4 * totpicnum);
  88.     while ((picfileinfo == NULL) || (pname == NULL) || (picoffsettbl == NULL))
  89.     {
  90.          text_show_string(30, 130, 200, 16, "内存分配失败!", 16, 0, RED);
  91.          delay_ms(200);
  92.          lcd_fill(30, 130, 200, 16, WHITE);
  93.          delay_ms(200);
  94.     }
  95.    
  96.     /* 打开目录并记录图片索引 */
  97.     res= (uint8_t)f_opendir(&picdir, "0:/PICTURE");
  98.     if (res == 0)
  99.     {
  100.          curindex = 0;
  101.          while (1)
  102.          {
  103.              temp = picdir.dptr;
  104.              res = (uint8_t)f_readdir(&picdir, picfileinfo);
  105.              if ((res != 0) || (picfileinfo->fname[0] == 0))
  106.              {
  107.                  break;
  108.              }
  109.             
  110.              res = exfuns_file_type(picfileinfo->fname);
  111.              if ((res & 0xF0) == 0x50)
  112.              {
  113.                  picoffsettbl[curindex] = temp;
  114.                  curindex++;
  115.              }
  116.          }
  117.     }
  118.    
  119.     /* 开始显示图片 */
  120.    text_show_string(30, 130, 200, 16, "开始显示...", 16, 0, RED);
  121.    delay_ms(1500);
  122.    piclib_init();
  123.    curindex = 0;
  124.     res= (uint8_t)f_opendir(&picdir, (const TCHAR *)"0:/PICTURE");
  125.     while (res == 0)
  126.     {
  127.          /* 获取下一个图片文件信息 */
  128.          dir_sdi(&picdir, picoffsettbl[curindex]);
  129.          res = (uint8_t)f_readdir(&picdir, picfileinfo);
  130.          if ((res != 0) || (picfileinfo->fname[0] == 0))
  131.          {
  132.              break;
  133.          }
  134.          
  135.          /* 根据图片路径显示图片 */
  136.          strcpy((char *)pname, "0:/PICTURE/");
  137.          strcat((char *)pname, (const char *)picfileinfo->fname);
  138.          lcd_clear(BLACK);
  139.          piclib_ai_load_picfile(pname, 0, 0, lcddev.width, lcddev.height, 1);
  140.          text_show_string(2, 2, lcddev.width, 16, (char *)pname, 16, 1, RED);
  141.          
  142.          while (1)
  143.          {
  144.              key = key_scan(0);
  145.              if (key == KEY0_PRES)
  146.              {
  147.                  /* 切换上一张 */
  148.                  if (curindex != 0)
  149.                  {
  150.                      curindex--;
  151.                  }
  152.                  else
  153.                  {
  154.                      curindex = totpicnum - 1;
  155.                  }
  156.                  break;
  157.              }
  158.              else if (key == WKUP_PRES)
  159.              {
  160.                  /* 切换下一张 */
  161.                  curindex++;
  162.                  if (curindex >= totpicnum)
  163.                  {
  164.                      curindex = 0;
  165.                  }
  166.                  break;
  167.              }
  168.             
  169.              if (++t == 20)
  170.              {
  171.                  t= 0;
  172.                  LED0_TOGGLE();
  173.              }
  174.             
  175.              delay_ms(10);
  176.          }
  177.     }
  178.    
  179.     /* 释放内存 */
  180.    myfree(SRAMIN, picfileinfo);
  181.    myfree(SRAMIN, pname);
  182.    myfree(SRAMIN, picoffsettbl);
  183.    
  184.     while (1);
  185. }
复制代码
从上面的代码中可以看出,本实验的应用代码中,在完成文件系统、SD卡等一些列必要的初始化后,便会统计SD卡中PICTURE文件夹下图片的数量和路径,然后根据WKUP和KEY0按键,调用函数piclib_ai_load_picfile()切换显示SD卡PICTURE文件夹中的图片文件至LCD上。
本章实验所需的图片文件可以在A盘à5,SD卡根目录文件àPICTURE中找到,建议将A盘à5,SD卡根目录文件中的所有文件按照该目录的目录结构复制进SD卡,方便后续实验的使用。

49.3 下载验证
在完成编译和烧录操作后,将根目录存放了A盘à5,SD卡根目录文件中文件的SD卡插入开发板板载的SD卡卡座后,便能看到LCD上显示了SD卡PICTURE文件夹中的图片,并且按下WKUP按键或KEY0按键可以切换LCD显示SD卡PICTURE文件夹中的上一张或下一张图片。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 19:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表