本文介紹一個監(jiān)控用的數(shù)碼相機的軟硬件工作原理和實現(xiàn)方法。整個裝置以51單片機為核心,采用CMOS圖像傳感器芯片OV7640進行圖像的采集,由OV528芯片進行圖像壓縮,然后經(jīng)SL811HS USB主機芯片將圖像保存到U盤中。這是我多年前制作的小裝置,經(jīng)過了實際使用的測試。
1 引言 在面對低端用戶的應用中,設計一種體積小、使用安裝容易,價格低廉,并能滿足應用要求的簡易視頻監(jiān)控裝置,無疑會有較好的應用前景。基于性價比考慮,本裝置以51單片機為控制中心,用CMOS圖像芯片為傳感器,以U盤作為存儲介質(zhì)來制作一個能自動拍攝的簡易數(shù)碼相機。它采用靜態(tài)圖像單幀間隔采集保存的方式,可以滿足普通家庭安全監(jiān)控的要求。
2 硬件設計
接口電路圖.JPG (68.38 KB, 下載次數(shù): 41)
下載附件
2018-1-16 10:50 上傳
圖像處理芯片OV7640和OV528均是美國OmniVision公司的產(chǎn)品。OV7640是CMOS彩色圖像傳感器,負責圖像的采集。它內(nèi)置640×480分辨率的象素陣列,并支持外部水平、垂直同步輸入格式、數(shù)字視頻輸出、增益控制、自動白平衡等。OV528則是一款高性能的DSP。本裝置采用的OV528有兩個功能:一是將單片機發(fā)出的圖像設置和讀寫控制命令傳給OV7640,二是將OV7640采集到的圖像數(shù)據(jù)壓縮成JPEG格式后,再傳輸給單片機。最后,由單片機將JPEG圖像文件經(jīng)SL811HS的USB主機接口寫到外接U盤中。 USB主機接口采用Cypress公司的SL811HS的USB芯片。它兼容USB1.1規(guī)范,支持usb主機或usb設備功能。 由于USB接口芯片SL811HS的M/S腳接低電平時,工作于主機方式;當M/S腳接高電平時,工作于設備方式。為了能讓它充當外接U盤設備的主機接口,所以將M/S腳接地。而SL811HS的地址和數(shù)據(jù)信號是分時復用的,所以只要將的AD0-AD7與單片機的數(shù)據(jù)總線連接即可。至于地址信號和數(shù)據(jù)信號的區(qū)分,則由充當?shù)刂房刂凭的A0決定。在讀寫SL811HS,先讓A0=0,向數(shù)據(jù)總線發(fā)送要讀寫的地址;然后讓A0=1,再向數(shù)據(jù)總線發(fā)送要讀寫的數(shù)據(jù)。連接INT0的中斷信號可使SL811HS有事件發(fā)生時(當有USB設備接入時,可觸發(fā)該中斷),單片機可通過讀取SL811HS 的狀態(tài)寄存器來判斷事件類型,并做出相應處理。 STC89LE51RD+是51系列兼容的單片機,它有64K的FLASH可用于裝載運行程序。由于它只有1K的RAM,不能滿足工作要求,所以另外擴展了32K的RAM(圖中未畫出)。由單片機的A15提供片外RAM和SL811HS的片選信號(A15=0選片外RAM,A15=1選SL811HS)。單片機通過串口向OV528發(fā)送圖像采集命令和接收圖像數(shù)據(jù),通過并口和SL811HS將圖像數(shù)據(jù)寫到U盤。 3 軟件設計
主程序流程圖.JPG (22.36 KB, 下載次數(shù): 23)
下載附件
2018-1-16 10:51 上傳
程序開始時,先進行初始化操作,然后就進入圖像采集和存儲的循環(huán)。對SL811HS芯片的初始化操作主要包括內(nèi)部寄存器復位和USB總線復位。對圖像芯片初始化是通過ov528實現(xiàn):它設置圖像尺寸為320*240的JPEG格式,每個數(shù)據(jù)包大小為518字節(jié)(內(nèi)含512字節(jié)圖像數(shù)據(jù),這是允許的包數(shù)據(jù)最大字節(jié)數(shù))。 在主程序的循環(huán)體中,單片機不斷檢測USB設備狀態(tài),如果發(fā)現(xiàn)設備(U盤)接入,則通過SL811HS進行U盤設備枚舉。一旦枚舉成功,就創(chuàng)建文件,進行圖像采集和數(shù)據(jù)存盤,如此不停循環(huán)。當然每次創(chuàng)建的文件名應該不同(文件名采用字母加序號方式)。 因為實現(xiàn)U盤文件系統(tǒng)的程序設計已有很多文獻介紹,在此不予討論。 4 圖像采集命令 圖像采集是由單片機通過串口向OV528發(fā)送控制命令來實現(xiàn)的(命令格式由OV528手冊提供)。單片機每次發(fā)送圖像采集命令前,均要發(fā)送一系列同步(SYNC)信號,以便讓單片機與OV528建立通訊連接(OV528有波特率檢測和自適應功能)。工作正常時,命令和應答包都是6個字節(jié)。“同步信號”的格式為16進制“AA 0D 00 00 00 00”,“應答(ACK)”的格式為“AA 0E XX** 00 00”。“XX”表示根據(jù)不同命令取不同值,“**”表示可取任意值。 單片機收到OV528的應答和同步信號后,才開始圖像采集。圖像采集的工作流程如圖5所示,其各步驟涉及的相關命令如下: (1)為了保證圖像采集工作方式不變,單片機每次開始圖像采集時,都先設置圖像格式和每個數(shù)據(jù)包的大小。“設置圖像格式”的命令字為“AA 01 00 07 ** 05”。其中07表示圖像為JPEG格式,05表示圖像尺寸為320*240,“**”表示該字節(jié)可取任意值。 (2)“設置數(shù)據(jù)包大小”的命令為“AA 06 08 06 02 00”,其中第3-4字節(jié)“0602”為數(shù)據(jù)包大小。因為是低字節(jié)在前,高字節(jié)在后,調(diào)整后為0206H,即518字節(jié)。 (3)“獲取圖像”命令的格式為“AA 04 05 00 00 00”。當單片機發(fā)出“獲取圖像”命令時, OV528會回應1個6字節(jié)的應答包和1個6字節(jié)的數(shù)據(jù)包。該6字節(jié)數(shù)據(jù)包的第4和第5字節(jié)為圖像文件的長度。 (4)單片機根據(jù)圖像文件長度參數(shù)來計算后面要接收多少個512字節(jié)的圖像數(shù)據(jù),才能接收完整個圖像文件(注意,最后一個包的圖像數(shù)據(jù)通常不夠512字節(jié))。 (5)單片機發(fā)出帶有包序列號的“請求數(shù)據(jù)包”命令,并逐個接收數(shù)據(jù)包。“請求數(shù)據(jù)包”命令格式為“AA 0E 00 00 LL HH”, 后2個字節(jié)為包序列號,低字節(jié)在前,高字節(jié)在后。如“AA 0E 00 00 00 00”為“請求第0個數(shù)據(jù)包”, “AA 0E 00 00 01 00” 為“請求第1個數(shù)據(jù)包”,依此類推。 (6)單片機接收到的一個518字節(jié)的數(shù)據(jù)包結構依次為:2字節(jié)的包序列號,2字節(jié)數(shù)據(jù)長度,512字節(jié)的圖像數(shù)據(jù)和2字節(jié)的校驗碼。所以單片機每接收一個數(shù)據(jù)包后,都應剔除開不屬圖像數(shù)據(jù)的這6個字節(jié)。當接收完所有的數(shù)據(jù)包后,就將圖像文件存盤。由于對U盤的操作比較慢,最后應有短暫延時,待寫U盤操作完成后,再進入下一次圖像采集過程。 本系統(tǒng)采用320X240的JPEG圖像格式時,每個文件大小為5-14KB,寫一個文件到U盤約要3秒左右。可以滿足一般安防監(jiān)控的要求。 采集圖像的關鍵函數(shù)源碼及注解如下: - void Get_Picture(void)
- { unsigned charxdata *Ptr1;
- byte idata bI; byte idata bM;
- byte idatabBuffer[6],bBuffer1[5]; word idatawK,wPackNo;
- unsigned longwwI;
- wwI = 0x01ffff; wRec_Num = 0;
- bBuffer[0] =0xAA; bBuffer[1] = 0x04; bBuffer[2] = 0x05; //get picture:
- bBuffer[3] =0x00; bBuffer[4] = 0x00; bBuffer[5] = 0x00;
- Send_Command(bBuffer,6); //發(fā)送“獲取圖像”命令
- WDT_CONTR = 0x00; //0x3f //feed watchdog //喂狗
- MCU_LED1=1;MCU_LED2=1;MCU_LED3=1;MCU_LED4=1; //運行狀態(tài)指示-4個LED滅
- while(wRec_Num<12) MCU_LED1=0;MCU_LED1=1; //waitc328's ack+image size=12B
- wRec_Num = 0;
- if (RxBuf[1] ==0x0E && RxBuf[2] == 0x04 && RxBuf[7] == 0x0A) //c328's ack
- { bBuffer1[3] = RxBuf[9]; bBuffer1[4] = RxBuf[10]; //=jpeg length
- wPackNo =((word)bBuffer1[4] << 8) + (word)bBuffer1[3];
- wPackNo /=512;
- bBuffer[0] =0xAA; bBuffer[1] = 0x0E; bBuffer[2] = 0x00;
- bBuffer[3] =0x00; bBuffer[4] = 0x00; //bBuffer[4]=0th packetID=0
- bBuffer[5] =0x00;
- Send_Command(bBuffer,6); //發(fā)送應答命令+ask for packetID=0
- WDT_CONTR= 0x00; //0x3f //feed watchdog //喂狗
- //-------------------start of loop to receive wPackNo ofpackets----------
- for (bI =0;bI < wPackNo;bI ++ ) //loop toreceive wPackNo of packets
- {
- while(wRec_Num < 7) MCU_LED2=0; MCU_LED2=1; //wait for data size
- WDT_CONTR= 0x00; //0x3f //feed watchdog //喂狗
- wK =((word)RxBuf[3] << 8) + (word)RxBuf[2];//datasize=packetsize-6=512
- while(wRec_Num<=wK) MCU_LED3=0;MCU_LED3=1; //waitimage receive finish
- EA =0; //DISABLE_INTERRUPTS;
- Ptr1=RxBuf+4; //omitted the first 4B(ID+datasize)
- WriteImg(Ptr1,wK);//omittedthe first 4B and last 2B(only write 512B)
- EA =1; //ENABLE_INTERRUPTS;
- for (bM= 0;bM < 50 ;bM ++ ) // wait forc328 to receive MCU's ack
- { } //ifcode down by 12 Tcyc,bM<30 isnot enough;50 is ok
- wRec_Num= 0; wK = 0;
- bBuffer[0]= 0xAA; bBuffer[1] = 0x0E;
- bBuffer[2]= 0x00; bBuffer[3] = 0x00;
- bBuffer[4]= bI + 1; //bBuffer[4]=bI+1thpacketID
- bBuffer[5]= 0x00;
- Send_Command(bBuffer,6); //發(fā)送應答命令+next packet ID
- WDT_CONTR = 0x00; //0x3f //feedwatchdog //喂狗
- }
- //----------------------//end of loop to receive wPackNoof packets-------------
- while(wRec_Num < 7) MCU_LED4=0; MCU_LED4=1;
- WDT_CONTR= 0x00; //0x3f //feed watchdog //喂狗
- wK =((word)RxBuf[3] << 8) + (word)RxBuf[2]; //lastpacket size
- while(wRec_Num<=wK)MCU_LED1=0; MCU_LED1=1; //waitlast package data
- EA =0; //DISABLE_INTERRUPTS;
- Ptr1=RxBuf;
- WriteImg(Ptr1,wK); //omitted the first 4B and last 2B
- EA =1; //ENABLE_INTERRUPTS;
- MCU_LED1=0; MCU_LED2=1;MCU_LED3=1;MCU_LED4=1; //運行狀態(tài)指示
- bBuffer[0] =0xAA; bBuffer[1] = 0x0E; bBuffer[2] = 0x00;
- bBuffer[3] =0x00; bBuffer[4] = 0xF0; bBuffer[5] = 0xF0;
- Send_Command(bBuffer,6); //發(fā)送last應答命令to c328
- WDT_CONTR= 0x00; //0x3f //feed watchdog //喂狗
- } //end of "if (RxBuf[1] ==0x0E............"
- WDT_CONTR = 0x00; //0x3f //feed watchdog //喂狗
- }
復制代碼 我給出的附錄源碼為4個主要的C文件:Main.c,SL811.C,F(xiàn)at32.c,serial.c。主程序在Main.c中,SL811.C和Fat32.c有U盤相關函數(shù),serial.c里有圖像驅(qū)動函數(shù)。均是經(jīng)無錯誤編譯并成功完成圖像采集和存盤的源程序。硬件結構和接口圖及軟件流程圖的介紹請看附件的“監(jiān)控數(shù)碼相機的制作.DOC”。 其他程序和頭文件如果有人感興趣,過后可以繼續(xù)補充提供。
0.png (8.57 KB, 下載次數(shù): 37)
下載附件
2018-1-17 00:04 上傳
全部資料51hei下載地址:
camera-code -主要源碼 DOC.zip
(116.66 KB, 下載次數(shù): 25)
2018-1-16 10:52 上傳
點擊文件名下載附件
詳細文檔和主要源碼 下載積分: 黑幣 -5
|