当前位置:   article > 正文

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

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

1)实验平台:正点原子APM32E103最小系统板
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/docs/boards/xiaoxitongban

第四十九章 图片显示实验

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

49.1 硬件设计
49.1.1 例程功能

  1. 程序运行后,会显示SD卡中PICTURE文件夹中的第一张图片(支持bmp、jpg、jpeg或gif格式)
  2. 按下KEY0或KEY_UP按键,可分别进行切换上一张图片和切换下一张图片的操作
  3. 可通过USMART操作解码任意路径下的图片
  4. LED0闪烁,指示程序正在运行
    49.1.2 硬件资源
  5. LED
    LED0 - PB5
  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驱动)
    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,这几个文件的描述,如下表所示:
    正点原子提供的图片解码库包含了九个文件,分别为:piclib.c、piclib.h、bmp.c、bmp.h、gif.c、gif.h、tjpgd.c、tjpgd.h、tjpgdcnf.h,这几个文件的描述,如下表所示:
    在这里插入图片描述

表49.2.1.1 图片解码库各文件描述
以上图片解码库的九个文件,在本章实验配套的实验例程中都已提供,并且针对正点原子APM32最小系统板软硬件进行了移植适配,用户在使用时,仅需将这九个文件添加到自己的工程即可,如下所示:
在这里插入图片描述

图49.2.1.1 正点原子图片解码库文件
49.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_4);  /* 设置中断优先级分组为组4 */
    sys_apm32_clock_init(15);                         /* 配置系统时钟 */
    delay_init(120);                                  /* 初始化延时功能 */
    usart_init(115200);                               /* 初始化串口 */
    usmart_dev.init(120);                             /* 初始化USMART */
    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 (sd_init() != SD_OK)                        /* 初始化SD卡 */
    {
        lcd_show_string(30, 50, 200, 16, 16, "SD Card Failed!", RED);
        delay_ms(200);
        lcd_fill(30, 50, 200 + 30, 50 + 16, WHITE);
        delay_ms(200);
    }
    
    while (fonts_init() != 0)                         /* 检查字库 */
    {
        lcd_clear(WHITE);
        lcd_show_string(30, 30, 200, 16, 16, "APM32", RED);
        
        while (sd_init() != SD_OK)
        {
            lcd_show_string(30, 50, 200, 16, 16, "SD Card Failed!", RED);
            delay_ms(200);
            lcd_fill(30, 50, 200 + 30, 50 + 16, WHITE);
            delay_ms(200);
        }
        
        lcd_show_string(30, 50, 200, 16, 16, "SD Card OK", RED);
        lcd_show_string(30, 70, 200, 16, 16, "Font Updating...", RED);
        res = fonts_update_font(20, 90, 16, (uint8_t *)"0:", RED);
        while (res != 0)
        {
            lcd_show_string(30, 90, 200, 16, 16, "Font Update Failed!", RED);
            delay_ms(200);
            lcd_fill(20, 90, 200 + 20, 90 + 16, WHITE);
            delay_ms(200);
        }
        
        lcd_show_string(30, 90, 200, 16, 16, "Font Update Success!   ", RED);
        delay_ms(1500);
        lcd_clear(WHITE);
    }
    
    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) /* 打开图片文件夹 */
    {
        text_show_string(30, 150, 240, 16, 
"PICTURE文件夹错误!", 16, 0, RED);
        delay_ms(200);
        lcd_fill(30, 150, 240, 186, WHITE);
        delay_ms(200);
    }
    
    totpicnum = pic_get_tnum("0:/PICTURE");           /* 获取有效图片文件数量 */
    while (totpicnum == 0)
    {
        text_show_string(30, 150, 240, 16, 
"没有图片文件!", 16, 0, RED);
        delay_ms(200);
        lcd_fill(30, 150, 240, 186, WHITE);
        delay_ms(200);
    }
    /* 申请内存 */
picfileinfo = (FILINFO *)mymalloc(SRAMIN, sizeof(FILINFO)); 
/* 为带路径的文件名分配内存 */
pname = (char *)mymalloc(SRAMIN, FF_MAX_LFN * 2 + 1);
	/* 申请4*totpicnum个字节的内存,用于存放图片索引 */
picoffsettbl = (uint32_t *)mymalloc(SRAMIN, 4 * totpicnum);
/* 内存申请失败 */
    while ((picfileinfo == NULL) || (pname == NULL) || (picoffsettbl == NULL))
    {
        text_show_string(30, 150, 240, 16, "内存分配失败!", 16, 0, RED);
        delay_ms(200);
        lcd_fill(30, 150, 240, 186, WHITE);
        delay_ms(200);
    }
    
    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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193

从上面的代码中可以看出,本实验的应用代码中,在完成文件系统、SD卡等一些列必要的初始化后,便会统计SD卡中PICTURE文件夹下图片的数量和路径,然后根据KEY0和KEY_UP按键,调用函数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文件夹中的图片,并且按下KEY0按键或KEY_UP按键可以切换LCD显示SD卡PICTURE文件夹中的上一张或下一张图片。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/172500
推荐阅读
相关标签
  

闽ICP备14008679号