久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7688|回復: 9
打印 上一主題 下一主題
收起左側

STC51+OV7670+FIFO+SD卡+znFAT+QVGA BMP 實現簡易數碼相機

  [復制鏈接]
跳轉到指定樓層
樓主
ID:140725 發(fā)表于 2016-10-18 15:47 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
源代碼下載:

所有資料下載:
campic.zip (188.26 KB, 下載次數: 174)

資料占用情況:Program Size: data=197.1 xdata=970 code=37223


實驗詳細說明:
       所謂“數碼相機”,其實就是圖像采集+數據存儲+顯示,當然還要有一個CPU作核心。

       DIY一個簡易的“數碼相機”的想法由來已久,我們不需要它有多么強的功能,只要實現基本的圖像采集與存儲功能即可。我一直在關注和研究OV的圖像傳感器(俗稱攝像頭芯片)OV7670,雖然已經比較了解它的驅動方法,但也是困難重重,“DIY數碼相機”實驗也就一直擱置。
       這個東西為什么那么難搞?其原因主要一是速度問題,二是數據量比較大。
速度方面,說白了,就是攝像頭芯片輸出像素數據的速度太快了!我們來舉例說明:假設芯片每秒產生10個圖像,即它的幀頻為10幀/秒。如果圖像的分辨率為320*240(QVGA),那么它每秒就將產生768000個像素數據,每一個像素數據在攝像頭芯片數據輸出端口上維持的時間約為1000ns。我們如果用單片機去采集這個數據,就必須在這1000ns的時間內完成數據的讀入、存儲與處理。有人可能說:“1000ns的時間應該是比較富裕的,足夠單片機去完成這些操作了。”確實!但是這需要代碼的運行效率很高,也許要使用匯編來完成。另外,每一個像素數據并不單純是一個字節(jié),而可能是16位或24位的。這就會涉及到多次數據讀入等操作。我們拿AVR這種單指令周期的CPU來舉個例子:我們將AVR超頻到20MHz(它的可靠工作主頻最高為16MHz),那么它每執(zhí)行一條指令的時間為50ns,它要在1000ns的時間里完成像素數據的讀取等操作,最多只能用20條指令。是不是感覺有點玄乎?!再加之,像素數據在攝像頭芯片的數據輸出端口上產生也需要一個信號建立的過程,為了保證數據數據的穩(wěn)定性,實際上留給我們去讀取像素數據的時間也只有700ns左右。這顯然是非常緊張的!
       其實,就算真的來得及去讀取和處理像素數據,數據量也是一個大問題。像素數據我們是首先暫存在RAM中的,前面說過,一個像素數據可能是16位或24位的,就拿16位來說,一幅QVGA的圖像數據量為150KB,有多少單片機,乃至于ARM或更高端的芯片會有這么多的RAM資源?
       上面說的是“數碼相機”實驗中,攝像頭芯片方面的一此困難。另一方面的問題是:SD卡的文件操作和數據寫入速率問題。假設我們現在已經得到了一幅完整而正確的圖像數據,它就存放在RAM中。現在,我們要把這些數據以文件的形式存入到SD卡中,并作成BMP位圖圖片。這一過程,仍然是一個極大的挑戰(zhàn),挑戰(zhàn)并不在于SD卡的驅動或是BMP文件格式,這些都簡單!而在于文件系統(tǒng),尤其是文件數據寫入這方面!詳細解釋一下:我們知道,SD卡或U盤這類存儲設備,要存儲文件必須事先進行格式化。格式化的過程其實就是使存儲設備遵從某種文件系統(tǒng)協(xié)議或者格式,比如我們經常使用的FAT32。要用單片機或ARM等去操作SD卡上的文件,必須也要遵循FAT32的協(xié)議格式。振南長期以來所研究和編寫的znFAT就是在作這樣的事情,通過znFAT可以在SD卡等存儲設備上進行各種文件操作,如文件創(chuàng)建、數據讀寫等等。我們要將像素數據以BMP文件的形式寫入SD卡,就可以使用znFAT的文件創(chuàng)建和數據寫入功能來實現(znFAT是一個完備而龐雜的東西,詳細可以參考使用手冊)。對于像素數據的寫入,我們是要講求一些速度的。說白了,向SD卡上的文件中寫入這150KB的像素數據,如果用了半個小時,那這樣的“數碼相機”實驗還有什么樂趣和實用性可言,簡直變成了一種煎熬!我們要求每寫入一個圖片,這個寫入數據的過程所花費的時間最好控制在幾秒以內,最多不過10秒。znFAT的性能和執(zhí)行效率能有這么高嗎?這正是上面我們所說的的挑戰(zhàn)所在!
       現在“數碼相機”實驗已經作成功了,發(fā)布在這里給大家作個參考。上面的諸多問題的解決方法:
       1、速度太快的問題采用在攝像頭芯片的數據輸出端口上加一片FIFO芯片AL422來解決,同時因為AL422有300多KB的容量,所以數據量大的問題也隨之解決。150KB的像素數據進入到FIFO中后,單片機可以“小數據量,多次取出”的方式將數據取走,進而再存到SD卡的BMP文件中。當然,數據寫入文件的方式是“頻繁的小數據量寫入”,這種寫入方式其實是最考驗一個文件系統(tǒng)方案的效率的。我試過在不開啟znFAT的加速算法的時候,以這種方式寫完一個BMP文件,大約需要40s左右。然而在開啟加速算法之后,只需要10s(開啟與不開啟,在RAM資源的占用上僅僅多了幾十個字節(jié),這也正是znFAT所使用的加速算法的獨到之處)。

       2、znFAT中采用了比較優(yōu)秀的加速算法(基于預建簇鏈與壓縮簇鏈緩沖思想),可以在占用極少的內存資源的前提下,極大的提高文件數據的寫入速率。因此,BMP文件數據的寫入速率問題也解決了。

  1. #include "stdio.h"

  2. #include "znfat/znFAT.h"
  3. #include "sdx.h"
  4. #include "uart.h"
  5. #include "myfun.h"

  6. #include "sensor.h"
  7. #include "fifo.h"

  8. //===========================================
  9. // 此程序用于完成OV7670+SD卡的數碼相機實驗
  10. // 文件系統(tǒng) znFAT
  11. // 于振南  QQ 987582714
  12. //===========================================

  13. sfr P1M0 = 0x92;
  14. sfr P1M1 = 0x91;

  15. struct znFAT_Init_Args idata Init_Args; //初始化參數集合
  16. struct FileInfo idata fileinfo; //文件信息集合

  17. struct DateTime dt; //日期時間結構體變量

  18. unsigned char cur_status=0;

  19. unsigned char buf[192];

  20. unsigned char code bmp_header[54]=
  21. {
  22. 0x42,0x4D,0x38,0x58,0x02,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
  23. 0x00,0x00,0x40,0x01,0x00,0x00,0xF0,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x00,0x00,
  24. 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x0B,0x00,0x00,0x12,0x0B,0x00,0x00,0x00,0x00,
  25. 0x00,0x00,0x00,0x00,0x00,0x00
  26. };

  27. //==================================================================

  28. void int0(void) interrupt 0
  29. {
  30. EX0=0; //關閉中斷

  31. if(cur_status==0) //如果此時狀態(tài)為0,則說明是一個圖像的開始,開始向FIFO罐入數據
  32. {
  33.   FIFO_WEN=1;
  34.   cur_status=1; //標記為1
  35.         
  36.   EX0=1;        //打開中斷
  37. }
  38. else
  39.   if(cur_status==1)        //說明此處為圖像的結束,亦即下一圖像的開始
  40.   {
  41.    FIFO_WEN=0;
  42.    cur_status=2;
  43.   }
  44. }

  45. int main()
  46. {
  47. unsigned char idata  i=0;

  48. FIFO_OE=0;

  49. P1M1=0x40;        //P16高阻輸入
  50. P1M0=0xa8; //如果使用51單片機來調試SD卡模塊,打開推挽,增強IO驅動能力

  51. UART_Init();
  52. UART_Send_Str("串口初始化完成.");UART_Send_Enter();

  53. znFAT_Device_Init(); //存儲設備初始化
  54. UART_Send_Str("存儲設備初始化完成.");UART_Send_Enter();

  55. znFAT_Select_Device(0,&Init_Args); //選擇設備

  56. znFAT_Init(); //文件系統(tǒng)初始化
  57. UART_Send_Str("文件系統(tǒng)初始化完成.");UART_Send_Enter();

  58. while(!Sensor_init());  

  59. UART_Send_Str("攝像頭芯片初始化完成.");UART_Send_Enter();

  60. //==============================================================================
  61.    
  62. dt.date.year=2012; dt.date.month=12; dt.date.day=21;
  63. dt.time.hour=15; dt.time.min=14; dt.time.sec=35;
  64.                   
  65. znFAT_Create_File(&fileinfo,"/znmcu6.bmp",&dt);

  66. UART_Send_Str("圖像文件已創(chuàng)建成功.");UART_Send_Enter();

  67. znFAT_WriteData(&fileinfo,54,bmp_header);

  68. UART_Send_Str("圖像文件頭數據已寫入.");UART_Send_Enter();

  69. IT0=1; //下降沿觸發(fā)
  70. EX0=1;        //打開外部中斷0
  71. EA=1;        //打開總中斷

  72. UART_Send_Str("外部中斷已開啟,等待圖像數據...");UART_Send_Enter();

  73. while(1)
  74. {
  75.   if(cur_status==2) //越級FIFO中已經罐入一個完整的圖像
  76.   {
  77.    cur_status=0;

  78.    UART_Send_Str("圖像已獲取.");UART_Send_Enter();

  79.    FIFO_Reset_Read_Addr(); //把FIFO的讀指針指向0地址

  80.    UART_Send_Str("開始將圖像寫入文件.");UART_Send_Enter();

  81.    for(i=0;i<200;i++)
  82.    {
  83.     FIFO_Read_Words(96,buf); //從FIFO讀取數據
  84.     znFAT_WriteData(&fileinfo,192,buf); //將數據寫入文件
  85.     FIFO_Read_Words(96,buf); //從FIFO讀取數據
  86.     znFAT_WriteData(&fileinfo,192,buf); //將數據寫入文件
  87.     FIFO_Read_Words(96,buf); //從FIFO讀取數據
  88.     znFAT_WriteData(&fileinfo,192,buf); //將數據寫入文件
  89.     FIFO_Read_Words(96,buf); //從FIFO讀取數據
  90.     znFAT_WriteData(&fileinfo,192,buf); //將數據寫入文件
  91.    }

  92.    UART_Send_Str("圖像寫入完成.");UART_Send_Enter();

  93.    znFAT_Close_File(&fileinfo);

  94.    znFAT_Flush_FS();
  95.   }
  96. }

  97. while(1);
  98. return 0;
  99. }
復制代碼




評分

參與人數 1黑幣 +5 收起 理由
YOLO666 + 5 很給力!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏12 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:185829 發(fā)表于 2017-4-9 21:49 | 只看該作者
很好的高速數據轉低速存儲案例
回復

使用道具 舉報

板凳
ID:235729 發(fā)表于 2017-11-17 15:54 | 只看該作者
你好 我有個問題 這樣做下去還能用單片機進行圖像識別嗎 比如識別一個紅綠燈 然后標記出來 51能做到嗎
回復

使用道具 舉報

地板
ID:79481 發(fā)表于 2018-1-20 20:03 | 只看該作者
牛逼的不要不要的
回復

使用道具 舉報

5#
ID:281852 發(fā)表于 2018-2-2 23:06 | 只看該作者
mark!!備用
回復

使用道具 舉報

6#
ID:380389 發(fā)表于 2018-8-23 17:13 來自手機 | 只看該作者
很高級  學習一下
回復

使用道具 舉報

7#
ID:447260 發(fā)表于 2019-4-23 16:33 | 只看該作者
準備采用,感謝大佬!
回復

使用道具 舉報

8#
ID:8222 發(fā)表于 2019-4-24 00:36 | 只看該作者
大牛!非常牛!
回復

使用道具 舉報

9#
ID:585455 發(fā)表于 2020-10-3 21:18 | 只看該作者
實在太強大了,我下周來測試看看,感謝你。
回復

使用道具 舉報

10#
ID:517951 發(fā)表于 2020-11-15 17:43 | 只看該作者
不錯,值得學習。51hei有你更精彩!!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91天堂网| 99热视| 精品免费av | 国产精品一区二区在线免费观看 | 澳门永久av免费网站 | 人人干在线视频 | 999精品视频| 日韩免费av一区二区 | 高清一区二区视频 | 一区二区三区电影网 | 国产精品久久久久久久久久久免费看 | 日本天堂视频 | 免费观看www | 亚洲精品日日夜夜 | 欧美精品在线一区 | 91国产视频在线 | 久久国产激情视频 | 亚洲免费在线观看 | 久久手机视频 | 欧美五月婷婷 | 狠狠色综合网站久久久久久久 | 99热在这里只有精品 | 国产精品久久久久久久岛一牛影视 | 黄色国产在线播放 | 成人免费大片黄在线播放 | 在线看黄免费 | 亚洲欧美激情四射 | 久久里面有精品 | 国产精品免费观看 | 91免费在线 | 亚洲精品自在在线观看 | 色视频网站 | 97精品超碰一区二区三区 | 久久久久www | va精品 | 亚洲不卡 | 欧美日韩在线观看视频 | 国产精品久久久久免费 | 国产www.| 国产一区二区精品 | 久综合|