原子STM32连载】 第五十三章 照相机实验 摘自【正点原子】APM32F407最小系统板使用指南"/>
【正点原子STM32连载】 第五十三章 照相机实验 摘自【正点原子】APM32F407最小系统板使用指南
1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: .html##
第五十三章 照相机实验
本章将介绍使用APM32F407模拟照相机将摄像头采集到的图像数据以BMP或JPEG的文件格式保存至SD中,是前面章节中SD卡驱动、摄像头驱动、FATFS、字库管理库、图片编解码库等的综合应用。通过本章的学习,读者将学习到编码BMP文件以及保存摄像头采集到图像数据的保存。
本章分为如下几个小节:
53.1 硬件设计
53.2 程序设计
53.3 下载验证
53.1 硬件设计
53.1.1 例程功能
- 程序运行后会先检查SD卡,若检测不到SD卡则无法进行本实验,若SD无法访问则后续不能保存图片文件
- 初始化完成后,LCD实时显示摄像头采集到的数据
- 按下KEY0或KEY_UP按键,可分别进行拍摄并保存BMP或JPG格式的图片文件至SD卡
- LED1闪烁,提示DCI捕获到一帧数据
- LED0闪烁,指示程序正在运行
53.1.2 硬件资源 - LED
LED0 - PF9
LED1 - PF10 - 按键
KEY0 - PE4
KEY_UP - PA0 - 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
- ATK-MC2640摄像头模块
OV_D0~D7 - PC6/PC7/PC8/PC9/PC11/PB6/PE5/PE6
OV_SCL - PD6
OV_SDA - PD7
OV_VSYNC - PB7
OV_HREF - PA4
OV_PCLK - PA6
OV_PWDN - PG9
OV_RESET - PG15
OV_XCLK - PA8 - SD卡(SDIO驱动)
- NOR Flash(SPI驱动)
53.1.3 原理图
本章实验涉及的SD卡、摄像头、LCD等的连接原理图,请读者自行查看前面对应章节中的连接原理图。
53.2 程序设计
53.2.1 实验应用代码
本章实验的应用代码,如下所示:
int main(void)
{uint8_t t = 0;uint8_t key;uint8_t res;uint8_t sd_ok = 1;uint8_t *pname;NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3); /* 设置中断优先级分组为组3 */sys_apm32_clock_init(336, 8, 2, 7); /* 配置系统时钟 */delay_init(168); /* 初始化延时功能 */usart_init(115200); /* 初始化串口 */led_init(); /* 初始化LED */key_init(); /* 初始化按键 */lcd_init(); /* 初始化LCD */piclib_init(); /* 初始化画图 */sram_init(); /* 初始化外部SRAM */my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */my_mem_init(SRAMCCM); /* 初始化CCM内存池 */my_mem_init(SRAMEX); /* 初始化外部SRAM内存池 */exfuns_init(); /* 为exfuns申请内存 */f_mount(fs[0], "0:", 1); /* 挂载SD卡 */f_mount(fs[1], "1:", 1); /* 挂载NOR Flash */while (ov2640_init() != 0) /* 初始化OV2640 */{/* 摄像头错误,代码省略 */}sw_sdcard_mode();while (sd_init() != SD_OK) /* 初始化SD卡 */{/* SD卡错误,代码省略 */}while (fonts_init() != 0) /* 检查字库 */{/* 字库错误,代码省略 */}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:拍照(bmp格式)", 16, 0, RED);text_show_string(30, 110, 200, 16, "KEY_UP:拍照(jpg格式)", 16, 0, RED);/* 创建PHOTO文件夹 */res = (uint8_t)f_mkdir("0:/PHOTO");if ((res != (uint8_t)FR_EXIST) && (res != 0)){/* SD卡错误,代码省略 */}/* 申请内存 */g_dci_line_buf[0] = (uint32_t *)mymalloc(SRAMIN,JPEG_LINE_SIZE * sizeof(uint32_t));g_dci_line_buf[1] = (uint32_t *)mymalloc(SRAMIN,JPEG_LINE_SIZE * sizeof(uint32_t));g_jpeg_data_buf = (uint32_t *)mymalloc(SRAMEX, JPEG_BUF_SIZE);pname = (uint8_t *)mymalloc(SRAMIN, 30);while ( (g_dci_line_buf[0] == NULL) ||(g_dci_line_buf[1] == NULL) ||(g_jpeg_data_buf == NULL) ||(pname == NULL)){/* 内存分配错误,代码省略 */}sw_ov2640_mode();ov2640_rgb565_mode(); /* 配置OV2640为RGB565模式 */dci_init(); /* 初始化DCI */dci_dma_init( (uint32_t)&(LCD->LCD_RAM), /* 配置DCI DMA */0,1,DMA_MEMORY_DATA_SIZE_HALFWORD,DMA_MEMORY_INC_DISABLE);ov2640_outsize_set(lcddev.width, lcddev.height); /* 全屏缩放 */dci_start(); /* 启动DCI传输 */ov2640_flash_intctrl(); /* 内部控制闪光灯 */while (1){t++;key = key_scan(0);if (key != 0) /* 有按键按下 */{dci_stop(); /* 先禁止DCI传输 */if (sd_ok == 1) /* SD卡正常 */{sw_sdcard_mode(); /* 切换为SD卡模式 */switch (key){case KEY0_PRES:{/* 得到BMP格式文件名 */camera_new_pathname(pname, 0);/* 编码并保存BMP文件 */res = bmp_encode( pname,0,0,lcddev.width,lcddev.height,0);break;}case WKUP_PRES:{/* 得到JPG格式文件名 */camera_new_pathname(pname, 1);/* 保存OV2640输出的JPEG数据到JPG文件 */res = ov2640_jpg_photo(pname);ov2640_outsize_set(lcddev.width, lcddev.height);break;}default:{break;}}sw_ov2640_mode(); /* 切换为OV2640模式 */if (res != 0){text_show_string(30, 130, 240, 16,"写入文件错误!", 16, 0, RED);}else{text_show_string(10, 130, 240, 16, "拍照成功!", 16, 0, RED);text_show_string(10, 150, 240, 16, "保存为:", 16, 0, RED);text_show_string(10 + 56, 150, 240, 16,(char*)pname, 16, 0, RED);}delay_ms(1000);}else/* SD卡不可用 */{text_show_string(30, 130, 240, 16, "SD卡错误!", 16, 0, RED);text_show_string(30, 150, 240, 16, "拍照功能不可用!", 16, 0, RED);}delay_ms(2000);dci_start(); /* 恢复DCI传输 */}if (t == 20){LED0_TOGGLE();t = 0;}delay_ms(10);}
}
可以看到,本章实验实际上是前面章节中SD卡驱动、摄像头驱动、FATFS、字库管理库、图片编解码库等的综合应用,并没有涉及新的内容。要注意的是,对于正点原子APM32F407最小系统板,其SD卡和摄像头是无法同时工作的,因为它们使用到了部分共同的GPIO引脚,因此在本章实验中,需要对GPIO引脚的复用模式进行切换,以正常使用SD卡或摄像头,用于切换GPIO引脚复用模式的函数,如下所示:
/*** @bref 切换为OV2640模式* @note 切换PC8/PC9/PC11为DCI复用功能(AF13)* @param 无* @retval 无*/
static void sw_ov2640_mode(void)
{OV2640_PWDN(0);GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_8, GPIO_AF_DCMI);GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_9, GPIO_AF_DCMI);GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_11, GPIO_AF_DCMI);
}/*** @bref 切换为SD卡模式* @note 切换PC8/PC9/PC11为SDIO复用功能(AF12)* @param 无* @retval 无*/
static void sw_sdcard_mode(void)
{OV2640_PWDN(1);GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_8, GPIO_AF_SDIO);GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_9, GPIO_AF_SDIO);GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_11, GPIO_AF_SDIO);
}
从应用代码的初始化函数中可以看到,在初始化过程中,配置了DCI和DMA将摄像头返回的图像数据传输至LCD上进行显示,初始化完成后,便检测按键输入,若无按键输入,则一直在LCD上显示摄像头采集到的图像数据,若检测到KEY0按键被按下,则调用函数bmp_encode()读取LCD上整个屏幕显示的数据并编码保存到SD卡上,若检测到KEY_UP按键,则调用函数ov2640_jpg_photo()将摄像头配置为JPEG格式输出图像数据,然后获取摄像头输出的一帧JPEG数据,并将JPEG数据通过FATFS写入SD的指定文件中。
53.3 下载验证
在完成编译和烧录操作后,可以看到LCD上实时显示这摄像头采集到的图像数据,此时若按下KEY0按键,可以看到LCD上显示了拍照成功和BMP图片保存路径的提示信息,若按下KEY_UP按键,可以看到LCD上显示了拍照成功和JPEG图片保存路径的提示信息。拍照完成后,可通过PC或图片显示实验例程(需修改获取图片的文件夹路径为“0:PHOTO”)查看所拍摄的BMP或JPEG格式的照片。
更多推荐
【正点原子STM32连载】 第五十三章 照相机实验 摘自【正点原子】APM32F407最小系统板使用指南
发布评论