一、項目介紹
當前文章介紹基于STM32設計的門禁照相機,本項目提供了一種更加智能、安全、便捷的門禁解決方案。門禁照相機采用STM32F103ZET6 MCU作為主控芯片,配合2.8寸LCD顯示屏、OV7725數字攝像頭、SD卡和模擬門鈴按鍵等外設模塊,實現了攝像頭畫面實時顯示、門鈴觸發拍照、圖片存儲等功能。
在使用該門禁照相機時,來訪客人只需按下門鈴按鍵,攝像頭即可自動拍攝照片并保存到SD卡中。同時,用戶也可以通過LCD屏幕進行時間調整和本地圖片瀏覽等操作,提高了門禁系統的可操作性和用戶體驗。
門禁照相機的設計為了提高門禁系統的安全性和智能化程度,解決傳統門禁系統存在的諸多問題。通過采用數字攝像頭替代傳統貓眼,并實現照片自動拍攝和存儲功能,有效提高了門禁系統的安全性。同時,通過LCD屏幕進行時間調整和本地圖片瀏覽等操作,實現了門禁系統的智能化,提高了用戶的使用體驗。
二、硬件設計
本照相機的主要硬件包括 STM32F103ZET6 MCU、3.5寸 LCD 顯示屏、OV7725 數字攝像頭、SD 卡和一個模擬門鈴的按鍵。
(1)STM32F103ZET6 MCU
STM32F103ZET6 MCU 是本照相機的主控芯片,它可以通過 GPIO 口驅動其他外設模塊。
(2)3.5寸 LCD 顯示屏
3.5寸 LCD 顯示屏可以實時顯示攝像頭捕捉的畫面,并且支持多個頁面的切換。
(3)OV7725 數字攝像頭
OV7725 數字攝像頭可以采集來訪客人的畫面,并將其實時顯示在 LCD 顯示屏上。
(4)SD 卡
SD 卡用于存儲照相機拍攝的照片,照片的名稱由當前時間日期命名。
(5)模擬門鈴的按鍵
模擬門鈴的按鍵用于觸發照相機拍攝照片。
三、軟件設計
3.1 技術要求
(1)實時顯示畫面
本照相機通過 OV7725 數字攝像頭捕捉來訪客人的畫面,并通過3.5寸 LCD 顯示屏實時顯示。
(2)拍照并保存到 SD 卡
當有來訪者按下模擬門鈴按鍵時,照相機會拍攝照片并保存到 SD 卡中,照片名稱以當前時間日期命名。
3.2 軟件流程
(1) 初始化STM32F103ZET6 MCU及外部設備; (2) 啟動OV7725 數字攝像頭; (3) 開啟LCD; (4) 進入主循環: a. 讀取按鍵狀態是否是門鈴被按下; b. 若發現門鈴按下,則照相機開始拍照并將照片保存到 SD 卡; c. 更新屏幕上的內容。
3.3 代碼實現
代碼實現過程:
(1) 初始化STM32F103ZET6 MCU及外部設備;
(2) 啟動OV7725 數字攝像頭,并設置其采集參數;
(3) 初始化 SD 卡,并在 SD 卡上創建一個文件夾用于存儲照片;
(4) 開啟LCD,并設置其顯示參數;
(5) 進入主循環,讀取按鍵狀態并更新屏幕上的內容;
(6) 當發現門鈴被按下時,開始拍照并將照片保存到 SD 卡中。
四、代碼實現
4.1 整體代碼框架
#include "stm32f10x.h"
#include "sdio_sdcard.h"
#include "ff.h"
?
/* 定義一些宏和變量 */
?
int main(void) {
/* 初始化系統時鐘(例如使用 HSE 8MHz 作為系統時鐘) */
/* 初始化 GPIO 端口、SDIO、LCD、OV7725 等外設模塊 */
/* 初始化 SD 卡,并在其上創建用于存儲照片的文件夾 */
?
while(1) {
/* 讀取門鈴按鍵狀態 */
if(/* 檢測到門鈴被按下 */) {
/* 拍攝照片并保存到 SD 卡中,照片名以當前時間日期命名 */
}
?
/* 更新屏幕顯示內容,包括實時攝像頭畫面、時間日期、照片預覽等 */
}
}
4.2 拍照存儲
下面是采用 STM32 的HAL 庫設計的代碼,控制OV7725 拍照保存為 BMP 圖片到 SD 卡中。
#include "stm32f1xx_hal.h"
#include "sdio_sdcard.h"
#include "ff.h"
#include "ov7725.h"
?
extern SD_HandleTypeDef hsd;
extern DCMI_HandleTypeDef hdcmi;
extern DMA_HandleTypeDef hdma_dcmi;
?
FATFS fs;
FIL file;
UINT bw;
?
/* 定義一些宏和變量 */
?
int main(void) {
/* 初始化系統時鐘(例如使用 HSE 8MHz 作為系統時鐘) */
/* 初始化 GPIO 端口、SDIO、LCD、OV7725 等外設模塊 */
/* 初始化 SD 卡,并在其上創建用于存儲照片的文件夾 */
?
while(1) {
/* 讀取門鈴按鍵狀態 */
if(/* 檢測到門鈴被按下 */) {
/* 拍攝照片并保存到 SD 卡中,照片名以當前時間日期命名 */
HAL_GPIO_WritePin(OV7725_RESET_GPIO_Port, OV7725_RESET_Pin, GPIO_PIN_SET); // 復位 OV7725
HAL_Delay(50);
HAL_GPIO_WritePin(OV7725_RESET_GPIO_Port, OV7725_RESET_Pin, GPIO_PIN_RESET);
?
ov7725_init(); // 初始化 OV7725
?
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)RGB565_buffer, (uint32_t)(CAMERA_RWIDTH * CAMERA_RHEIGH), 1); // 開始采集
?
HAL_DMA_PollForTransfer(&hdma_dcmi, HAL_DMA_FULL_TRANSFER, 1000); // 等待采集完成
?
/* 將 RGB565 數據轉換成 BMP 格式 */
uint16_t bmp_header[54/2] = {0x4D42, 54+CAMERA_RWIDTH*CAMERA_RHEIGH*3, 0, 0, 54,
40, CAMERA_RWIDTH, CAMERA_RHEIGH, 1, 24, 0, CAMERA_RWIDTH*CAMERA_RHEIGH*3, 0, 0, 0, 0};
uint8_t bmp_data[CAMERA_RWIDTH*CAMERA_RHEIGH*3];
uint16_t i = 0, j = 0;
for(i = 0; i < 54/2; i++) {
bmp_data[i*2] = bmp_header[i]; // 拷貝 BMP 文件頭
bmp_data[i*2+1] = bmp_header[i] > >8;
}
for(i = 0; i < CAMERA_RWIDTH*CAMERA_RHEIGH; i++) {
bmp_data[54+i*3+0] = RGB565_buffer[i] > >8; // RGB565 轉換為 BMP 格式的 RGB 24位色
bmp_data[54+i*3+1] = RGB565_buffer[i] > >3;
bmp_data[54+i*3+2] = RGB565_buffer[i]< < 3;
}
?
/* 保存 BMP 圖片到 SD 卡中 */
if(f_mount(&fs, SD_Path, 1) == FR_OK) { // 掛載 SD 卡
char filename[20];
/* 將文件名設置為當前時間日期,例如"202206151243.bmp" */
sprintf(filename, "%04d%02d%02d%02d%02d%02d.bmp", year, month, day, hour, minute, second);
?
if(f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { // 創建文件并寫入數據
f_write(&file, bmp_data, sizeof(bmp_data), &bw);
f_close(&file);
}
}
?
HAL_Delay(1000); // 防止連續拍照
}
?
/* 更新屏幕顯示內容,包括實時攝像頭畫面、時間日期、照片預覽等 */
}
}