Abstract
DE2提供了Control Panel與Image Converter,可以將CMOS所擷取的影像傳到PC端,

Introduction
版權聲明:文中所有範例皆出自DE2光碟,版權歸友晶科技所有。
使用環境:Quartus II 7.2 SP1 + DE2(Cyclone II EP2C35F627C6) + TRDB_DC2

在友晶提供的DE2_CCD.7z與DE2_CCD_detect.7z範例中,我們可以透過130萬像素的CMOS,將影像擷取到SDRAM中,若我們想將所擷取的影像傳到PC端作後續的處理, 可以透過DE2 Control Panel將SDRAM上的資料下載到PC,並使用Teasic Image Converter轉成bmp格式,所有的步驟在光碟中的TRDB_DC2 User Guide有詳細的說明。

這個方法套用在DE2_CCD.7z範例非常完美,可以擷取正確的影像,但若用相同的方式在DE2_CCD_detect.7z範例,將獲得如以下有問題的bmp影像。

為什麼會這樣子呢?因為DE2_CCD.7z與DE2_CCD_detect.7z兩個範例對於SDRAM使用的方式並不一樣。我們先來看看DE2_CCD.7z,在DE2_CCD.v的456行

 1 Sdram_Control_4Port u6 (
 2   // HOST Side
 3   .REF_CLK(CLOCK_50),
 4   .RESET_N(1'b1),
 5   // FIFO Write Side 1
 6   .WR1_DATA({sCCD_G[9:5], sCCD_B[9:0]}),
 7   .WR1(sCCD_DVAL),
 8   .WR1_ADDR(0),
 9   .WR1_MAX_ADDR(640*512),
10   .WR1_LENGTH(9'h100),
11   .WR1_LOAD(!DLY_RST_0),
12   .WR1_CLK(CCD_PIXCLK),
13   // FIFO Write Side 2
14   .WR2_DATA({sCCD_G[4:0], sCCD_R[9:0]}),
15   .WR2(sCCD_DVAL),
16   .WR2_ADDR(22'h100000),
17   .WR2_MAX_ADDR(22'h100000+640*512),
18   .WR2_LENGTH(9'h100),
19   .WR2_LOAD(!DLY_RST_0),
20   .WR2_CLK(CCD_PIXCLK),
21   // FIFO Read Side 1
22   .RD1_DATA(Read_DATA1),
23   .RD1(Read),
24   .RD1_ADDR(640*16),
25   .RD1_MAX_ADDR(640*496),
26   .RD1_LENGTH(9'h100),
27   .RD1_LOAD(!DLY_RST_0),
28   .RD1_CLK(VGA_CTRL_CLK),
29   // FIFO Read Side 2
30   .RD2_DATA(Read_DATA2),
31   .RD2(Read),
32   .RD2_ADDR(22'h100000+640*16),
33   .RD2_MAX_ADDR(22'h100000+640*496),
34   .RD2_LENGTH(9'h100),
35   .RD2_LOAD(!DLY_RST_0),
36   .RD2_CLK(VGA_CTRL_CLK),
37   // SDRAM Side
38   .SA(DRAM_ADDR),
39   .BA({DRAM_BA_1,DRAM_BA_0}),
40   .CS_N(DRAM_CS_N),
41   .CKE(DRAM_CKE),
42   .RAS_N(DRAM_RAS_N),
43   .CAS_N(DRAM_CAS_N),
44   .WE_N(DRAM_WE_N),
45   .DQ(DRAM_DQ),
46   .DQM({DRAM_UDQM,DRAM_LDQM}),
47   .SDR_CLK(DRAM_CLK)
48 );

顯示了DE2_CCD.7z使用SDRAM的方式為

.WR1_DATA({sCCD_G[9:5], sCCD_B[9:0]}),
.WR2_DATA({sCCD_G[4:0], sCCD_R[9:0]}),

這可以用以下的圖來表示

也就是說,DE2_CCD.7z用了兩個bank來存一個pixel的RGB,第一個bank存了R[9:0]與G[9:5],第二個bank存了G[4:0]與B[9:0],所以利用DE2 Control Panel分別抓下兩個bank的資料,再用Image Converter合併成bmp檔。

我們再來看看DE2_CCD_detect.7z如何使用SDRAM。在DE2_CCD_detect.v的450行

 1Sdram_Control_4Port u6 (
 2  // HOST Side
 3  .REF_CLK(CLOCK_50),
 4  .RESET_N(1'b1),
 5  // FIFO Write Side 1
 6  .WR1_DATA({mCCD_R[9:5], mCCD_G[9:5], mCCD_B[9:5]}    ),
 7  .WR1(mCCD_DVAL_d),
 8  .WR1_ADDR(0),
 9  .WR1_MAX_ADDR(640*512*2),
10  .WR1_LENGTH(9'h100),
11  .WR1_LOAD(!DLY_RST_0),
12  .WR1_CLK(CCD_PIXCLK),
13  // FIFO Read Side 1
14  .RD1_DATA(Read_DATA1),
15  .RD1(Read),
16  .RD1_ADDR(640*16),
17  .RD1_MAX_ADDR(640*496),
18  .RD1_LENGTH(9'h100),
19  .RD1_LOAD(!DLY_RST_0),
20  .RD1_CLK(VGA_CTRL_CLK),
21  // FIFO Read Side 2
22  .RD2_DATA(Read_DATA2),
23  .RD2(Read),
24  .RD2_ADDR(640*512+640*16),
25  .RD2_MAX_ADDR(640*512+640*496),
26  .RD2_LENGTH(9'h100),
27  .RD2_LOAD(!DLY_RST_0),
28  .RD2_CLK(VGA_CTRL_CLK),
29  // SDRAM Side
30  .SA(DRAM_ADDR),
31  .BA({DRAM_BA_1,DRAM_BA_0}),
32  .CS_N(DRAM_CS_N),
33  .CKE(DRAM_CKE),
34  .RAS_N(DRAM_RAS_N),
35  .CAS_N(DRAM_CAS_N),
36  .WE_N(DRAM_WE_N),
37  .DQ(DRAM_DQ),
38  .DQM({DRAM_UDQM,DRAM_LDQM}),
39  .SDR_CLK(DRAM_CLK)
40);

顯示了DE2_CCD_detect.7z使用SDRAM的方式為

.WR1_DATA({mCCD_R[9:5], mCCD_G[9:5], mCCD_B[9:5]}),

若用圖表示則為

也就是說,DE2_CCD_detect.7z只用了一個bank來存1個pixel的RGB,可是每個bank只有16bit怎麼辦?只好犧牲一些畫質,只存R[9:5]、G[9:5]、B[9:5],所以若要從SDRAM抓下所擷取的影像,若用抓DE2_CCD.7z資料的方式,就會產生不正確的影像。

那要如何用DE2 Control Panel和Terasic Image Converter抓取DE2_CCD_detect.7z的影像呢?
Step1 :
從SDRAM抓取資料
一樣從SDRAM的記憶體位址0x2800開始抓,抓長度0x96000,存成檔名catpure2_gb.dat。

Step 2:
由capture2_gb.dat複製成capture2_gr.dat
在TRDB_DC2 User Guide中要我們記憶體位址0x102800開始抓0x96000長度的資料存到capture2_gr.dat,但因為DE2_CCD_detect.7z只用了1個bank,所以我們不需這樣抓,只需將Step 1所抓的檔案複製成capture2_gr.dat即可。

Step 3:
使用Terasic Image Converter轉成bmp
利用Image Converter將capture2_gb.dat和capture2_gr.dat合併成capture2.bmp檔。

眼尖的你一定發現,為什麼圖左右顛倒? 這是DE2_CCD_detect.7z範例的bug,請參閱(原創) 如何解決DE2範例DE2_CCD_detect左右相反的問題? (IC Design) (DE2) (Quartus II)

完整程式碼下載
友晶科技範例 DE2_CCD.7z
友晶科技範例 DE2_CCD_detect.7z
DE2 Control Panel
Teasic Image Converter

Conclusion
友晶原廠的TRDB_DC2 User Guide,只能針對DE2_CCD.7z,無法針對DE2_CCD_detect.7z,透過本文的方式,讓我們可以利用 DE2 Control Panel與Teasic Image Converter將DE2_CCD_detect.7z所擷取的影像傳到PC端,也讓我們更清楚兩個範例使用SDRAM方式的不同。

Remark
或許你會問,我怎麼知道要從SDRAM記憶體位址的0x2800抓長度0x96000呢?在DE2_CCD.7z的DE2_CCD.v的480行

.RD1_ADDR(640*16),
.RD1_MAX_ADDR(640*496),

告訴我們從位址640*16開始讀取,最多讀到640*496。

640 * 16 = 10240 = 0x2800
640 * (496-16) * 2 = 614400 = 0x96000

為什麼要*2呢?因為一個bank是16 bit,也就是2 byte,記憶體位址是用byte計算。

See Also
(原創) 如何解決DE2範例DE2_CCD_detect左右相反的問題? (IC Design) (DE2) (Quartus II)
(原創) 如何使用ANSI C讀寫24位元的BMP圖檔? (C/C++) (C) (Image Processing)
(原創) 如何使用ANSI C讀寫32位元的BMP圖檔? (C/C++) (C) (Image Processing)
(原創) 如何使用ANSI C讀寫24/32位元的BMP圖檔? (C/C++) (C) (Image Processing)
(原創) 如何將CMOS彩色影像轉換成灰階影像? (SOC) (DE2)

(原創) 如何將CMOS所擷取的影像傳到PC端? (SOC) (DE2) (TRDB-DC2)相关推荐

  1. (原創) 如何將編譯結果,統一放在一個目錄下? (SOC) (Quartus II)

    Abstract Quartus II預設會將所有檔案都放在project的根目錄下,導致根目錄檔案過多,管理不便,若能將編譯的結果統一放到其他目錄下,將有助於日後管理. Introduction 使 ...

  2. (原創) 如何將DE2_70_TV範例加上Sobel Edge Detector? (SOC) (Verilog) (Image Processing) (DE2-70)...

    Abstract 本文將DE2-70平台的DE2_70_TV的範例加上Sobel Edge Detector. Introduction 使用環境:Quartus II 8.0 + DE2-70 (C ...

  3. JS中移动端项目取余数和switch于PC端的不同

    在移动端js代码中浮点类型数据进行取余数时会自动将小数点去掉:PC端不会: 在移动端js代码中进行switch时候值为浮点类型的时候会自动向下取整:PC端不会: 遇到这种情况的时候需要调用Math.f ...

  4. (原創) 如何將16進位的ACSII值轉成相對應的字元? (C/C++) (C)

    Abstract若字串記載的是16進位的數值,該如何轉成相對應的ASCII值呢? Introduction若文字檔內記載的是16進位的數值,我們希望讀進字串後,轉成相對應的ASCII值. C語言 / ...

  5. (原創) 如何將ThinkPad的『上一頁』和『下一頁』改成『PageUp』和『PageDn』? (NB) (ThinkPad) (OS) (Windows)...

    AbstractThinkPad鍵盤在上下左右鍵上方增設了瀏覽器的『上一頁』和『下一頁』,本文介紹將這兩個鍵改成『PageUp』『PageDn』的方法. Introduction ThinkPad在上 ...

  6. (原創) 如何将字符串前后的空白去除? (使用string.find_first_not_of, string.find_last_not_of) (C/C++)...

    这在字符串处理是很常用的功能,.NET Framework的String class直接提供Trim()的method,其它语言也大都有提供(VB.VFP),但C++无论Standard Librar ...

  7. (原創) ThinkPad X61安裝過程全紀錄 (NB) (ThinkPad) (X61)

    Abstract 我的ThinkPad X61安裝過程詳細紀錄. Introduction Step 1: ThinkPad X61基本硬體 (原創) 如何自行在ThinkPad X61安裝Windo ...

  8. 手把手教你爬取PC端『某酷视频』个人历史播放数据,并可视化展示

    大家好,我是阿辰,今天手把手教你爬取PC端『某酷视频』个人历史播放数据,并可视化展示 上次有粉丝说,那个是ios手机,安卓手机现在需要root权限才可以安装证书,那么今天就不以手机为例,以电脑PC端为 ...

  9. (原創) Quartus II安裝新觀念:如何將Quartus II安裝在VirtualBox內? (SOC) (Quartus II) (VirtualBox)...

    Abstract VM並不是什麼新的觀念,透過VM我們可以在一個OS去執行其他OS,若我們將Quartus II也裝在VM中,將可解決一些長久以來Quartus II使用上所遇到的問題. Introd ...

最新文章

  1. MPB:中科院城环所杨军组-​​​基于DNA宏条形码的水体浮游细菌群落测序建库方法...
  2. Docker映像和容器之间有什么区别?
  3. Linux系统中退出vim的编辑器3种情况
  4. 无限容量数据库架构设计
  5. html登陆不刷新flask,Flask Button运行Python而不刷新页面?
  6. shell如何传参?
  7. IDEA的第一个java程序
  8. 软考中级软件设计师考试大纲
  9. Spring Data JPA进阶(三):Specification查询
  10. Testin云测如何成为传统企业转型升级的“X”因子?
  11. 快手资讯|快手推出多档世界杯相关节目
  12. python爬虫音乐犯法么_Python爬虫案例:爬取网易云音乐
  13. Java实现字母去重
  14. 什么是数据产品,怎么设计一个好用的数据产品
  15. 风靡全球3500万用户!realme真我8款潮玩新品亮相
  16. 数字电路技术可能出现的简答题_电子技术应用实验1(数字电路基础实验)答案公众号...
  17. PHP简洁小猫咪图床源码 带12个图床接口
  18. 耗时6个月,从月入3K到14K的,我都经历了什么......
  19. print log trace (I forgot it )
  20. 清华姚班毕业生开发新特效编程语言,99 行代码实现《冰雪奇缘》,网友:大神碉堡!创世的快乐...

热门文章

  1. 不同Logger的使用
  2. iOS符号表恢复逆向支付宝
  3. 【GoLang】GoLang GOPATH 工程管理 最佳实践
  4. 二元查找树变双向链表
  5. Listview 多个ViewHolder实现
  6. @include与jsp:include的区别
  7. 总结自己的Git常用命令
  8. 设计模式学习总结-迭代器模式(Iterator Pattern)
  9. jquery如何对多个对象绑定同一事件
  10. 360safe:腾讯QQ也见不得人[图]