本帖最后由 正点原子运营 于 2024-5-20 15:28 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章将介绍使用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,这几个文件的描述,如下表所示: 表49.2.1.1 图片解码库各文件描述 以上图片解码库的九个文件,在本章实验配套的实验例程中都已提供,并且针对正点原子M144Z-M3最小系统板STM32F103版软硬件进行了移植适配,用户在使用时,仅需将这九个文件添加到自己的工程即可,如下所示: 图49.2.1.1 正点原子图片解码库文件
49.2.2 实验应用代码 本章实验的应用代码,如下所示: - int main(void)
- {
- uint8_t t = 0;
- uint8_t key;
- uint8_t res;
- DIRpicdir;
- uint16_t totpicnum;
- FILINFO *picfileinfo;
- char *pname;
- uint32_t *picoffsettbl;
- uint16_t curindex;
- uint16_t temp;
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- key_init(); /* 初始化按键 */
- lcd_init(); /* 初始化LCD */
- my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */
- exfuns_init(); /* 为exfuns申请内存 */
- f_mount(fs[0], "0:", 1); /* 挂载SD卡 */
- f_mount(fs[1], "1:", 1); /* 挂载NOR Flash */
-
- /* 检查字库 */
- while (fonts_init() != 0)
- {
- lcd_show_string(30, 30, 200, 16, 16, "STM32", RED);
-
- /* 初始化SD卡 */
- while (sd_init() != 0)
- {
- lcd_show_string(30, 30, 200, 16, 16, "SD CardError!", RED);
- delay_ms(500);
- lcd_show_string(30, 30, 200, 16, 16, "PleaseCheck! ", RED);
- delay_ms(500);
- LED0_TOGGLE();
- }
-
- lcd_show_string(30, 50, 200, 16, 16, "SD CardOK", RED);
- lcd_show_string(30, 70, 200, 16, 16, "FontUpdating...", RED);
-
- /* 更新字库 */
- res = fonts_update_font(30, 90, 16, (uint8_t *)"0:", RED);
- while (res != 0)
- {
- lcd_show_string(30, 90, 200, 16, 16, "Font UpdateFailed!", RED);
- delay_ms(200);
- lcd_show_string(30, 90, 200, 16, 16, "PleaseCheck! ", RED);
- delay_ms(200);
- }
-
- lcd_show_string(30, 90, 200, 16, 16, "Font UpdateSuccess! ", RED);
- delay_ms(1500);
- lcd_clear(WHITE);
- }
-
- text_show_string(30, 30, 200, 16, "正点原子STM32开发板", 16, 0, RED);
- text_show_string(30, 50, 200, 16, "图片显示实验", 16, 0, RED);
- text_show_string(30, 70, 200, 16, "ATOM@ALIENTEK", 16, 0, RED);
- text_show_string(30, 90, 200, 16, "WKUP: PREV", 16, 0, RED);
- text_show_string(30, 110, 200, 16, "KEY0: NEXT", 16, 0, RED);
-
- /* 打开图片文件夹 */
- while (f_opendir(&picdir, "0:/PICTURE") != FR_OK)
- {
- text_show_string(30, 130, 200, 16, "PICTURE文件夹错误!", 16, 0, RED);
- delay_ms(200);
- lcd_fill(30, 130, 200, 16, WHITE);
- delay_ms(200);
- }
-
- /* 获取有效图片文件数量 */
- totpicnum = pic_get_tnum("0:/PICTURE");
- while (totpicnum == 0)
- {
- text_show_string(30, 130, 200, 16, "没有图片文件!", 16, 0, RED);
- delay_ms(200);
- lcd_fill(30, 130, 200, 16, WHITE);
- delay_ms(200);
- }
-
- /* 申请内存 */
- 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))
- {
- text_show_string(30, 130, 200, 16, "内存分配失败!", 16, 0, RED);
- delay_ms(200);
- lcd_fill(30, 130, 200, 16, WHITE);
- delay_ms(200);
- }
-
- /* 打开目录并记录图片索引 */
- res= (uint8_t)f_opendir(&picdir, "0:/PICTURE");
- if (res == 0)
- {
- curindex = 0;
- while (1)
- {
- temp = picdir.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, 130, 200, 16, "开始显示...", 16, 0, RED);
- delay_ms(1500);
- piclib_init();
- curindex = 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)
- {
- 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)
- {
- t= 0;
- LED0_TOGGLE();
- }
-
- delay_ms(10);
- }
- }
-
- /* 释放内存 */
- myfree(SRAMIN, picfileinfo);
- myfree(SRAMIN, pname);
- myfree(SRAMIN, picoffsettbl);
-
- while (1);
- }
复制代码从上面的代码中可以看出,本实验的应用代码中,在完成文件系统、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文件夹中的上一张或下一张图片。 |