搜索

[FPGA] OV7670摄像头显示

[复制链接]
115|0
 楼主 | 2020-11-7 18:00 | 显示全部楼层 |阅读模式
1.2.3 参考代码
1.  //矩阵键盘

  • always  @(posedge clk or negedge rst_n)begin
  •     if(rst_n==1'b0)begin
  •         key_col_ff0 <= 4'b1111;
  •         key_col_ff1 <= 4'b1111;
  •     end
  •     else begin
  •         key_col_ff0 <= key_col    ;
  •         key_col_ff1 <= key_col_ff0;
  •     end
  • end
  • always @(posedge clk or negedge rst_n) begin
  •     if (rst_n==0) begin
  •         shake_cnt <= 0;
  •     end
  •     else if(add_shake_cnt) begin
  •         if(end_shake_cnt)
  •             shake_cnt <= 0;
  •         else
  •             shake_cnt <= shake_cnt+1 ;
  •    end
  • end
  • assign add_shake_cnt = key_col_ff1!=4'hf;
  • assign end_shake_cnt = add_shake_cnt  && shake_cnt == TIME_20MS-1 ;
  • always  @(posedge clk or negedge rst_n)begin
  •     if(rst_n==1'b0)begin
  •         state_c <= CHK_COL;
  •     end
  •     else begin
  •         state_c <= state_n;
  •     end
  • end
  • always  @(*)begin
  •     case(state_c)
  •         CHK_COL: begin
  •                      if(col2row_start )begin
  •                          state_n = CHK_ROW;
  •                      end
  •                      else begin
  •                          state_n = CHK_COL;
  •                      end
  •                  end
  •         CHK_ROW: begin
  •                      if(row2del_start)begin
  •                          state_n = DELAY;
  •                      end
  •                      else begin
  •                          state_n = CHK_ROW;
  •                      end
  •                  end
  •         DELAY :  begin
  •                      if(del2wait_start)begin
  •                          state_n = WAIT_END;
  •                      end
  •                      else begin
  •                          state_n = DELAY;
  •                      end
  •                  end
  •         WAIT_END: begin
  •                      if(wait2col_start)begin
  •                          state_n = CHK_COL;
  •                      end
  •                      else begin
  •                          state_n = WAIT_END;
  •                      end
  •                   end
  •        default: state_n = CHK_COL;
  •     endcase
  • end
  • assign col2row_start = state_c==CHK_COL  && end_shake_cnt;
  • assign row2del_start = state_c==CHK_ROW  && row_index==3 && end_row_cnt;
  • assign del2wait_start= state_c==DELAY    && end_row_cnt;
  • assign wait2col_start= state_c==WAIT_END && key_col_ff1==4'hf;
  • always  @(posedge clk or negedge rst_n)begin
  •     if(rst_n==1'b0)begin
  •         key_row <= 4'b0;
  •     end
  •     else if(state_c==CHK_ROW)begin
  •         key_row <= ~(1'b1 << row_index);
  •     end
  •     else begin
  •         key_row <= 4'b0;
  •     end
  • end
  • always @(posedge clk or negedge rst_n) begin
  •     if (rst_n==0) begin
  •         row_index <= 0;
  •     end
  •     else if(add_row_index) begin
  •         if(end_row_index)
  •             row_index <= 0;
  •         else
  •             row_index <= row_index+1 ;
  •    end
  •    else if(state_c!=CHK_ROW)begin
  •        row_index <= 0;
  •    end
  • end
  • assign add_row_index = state_c==CHK_ROW && end_row_cnt;
  • assign end_row_index = add_row_index  && row_index == 4-1 ;
  • always @(posedge clk or negedge rst_n) begin
  •     if (rst_n==0) begin
  •         row_cnt <= 0;
  •     end
  •     else if(add_row_cnt) begin
  •         if(end_row_cnt)
  •             row_cnt <= 0;
  •         else
  •             row_cnt <= row_cnt+1 ;
  •    end
  • end
  • assign add_row_cnt = state_c==CHK_ROW || state_c==DELAY;
  • assign end_row_cnt = add_row_cnt  && row_cnt == 16-1 ;
  • always  @(posedge clk or negedge rst_n)begin
  •     if(rst_n==1'b0)begin
  •         key_col_get <= 0;
  •     end
  •     else if(state_c==CHK_COL && end_shake_cnt ) begin
  •         if(key_col_ff1==4'b1110)
  •             key_col_get <= 0;
  •         else if(key_col_ff1==4'b1101)
  •             key_col_get <= 1;
  •         else if(key_col_ff1==4'b1011)
  •             key_col_get <= 2;
  •         else
  •             key_col_get <= 3;
  •     end
  • end
  • always  @(posedge clk or negedge rst_n)begin
  •     if(rst_n==1'b0)begin
  •         key_out <= 0;
  •     end
  •     else if(state_c==CHK_ROW && end_row_cnt)begin
  •         key_out <= {row_index,key_col_get};
  •     end
  •     else begin
  •         key_out <= 0;
  •     end
  • end
  • always  @(posedge clk or negedge rst_n)begin
  •     if(rst_n==1'b0)begin
  •         key_vld <= 1'b0;
  •     end
  •     else if(state_c==CHK_ROW && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin
  •         key_vld <= 1'b1;
  •     end
  •     else begin
  •         key_vld <= 1'b0;
  •     end
  • end
  • always  @(*)begin
  •     if(rst_n==1'b0)begin
  •         key_en = 0;
  •     end
  •     else if(key_vld && key_out==0)begin
  •         key_en = 4'b0001;
  •     end
  •     else if(key_vld && key_out==1)begin
  •         key_en = 4'b0010;
  •     end
  •     else if(key_vld && key_out==2)begin
  •         key_en = 4'b0100;
  •     end
  •     else begin
  •         key_en = 0;
  •     end
  • end
  • endmodule

[color=rgb(51, 102, 153) !important]复制代码



1.3 锁相环1.3.1 接口信号
PLL_1pll_sd
  
信号名
  
I/O
位宽
定义
Inclk0
I
1
输入时钟50M
C0
O
1
输出时钟25M
C1
O
1
输出时钟100M
PLL_2cmos_pll
  
信号名
  
I/O
位宽
定义
Inclk0
I
1
输入时钟25M
C0
O
1
输出时钟25M

1.3.2 设计思路
此模块是使用Quartus生成的PLL IP核,相关的生成步骤、功能原理等可以看明德扬论坛中关于PLL的介绍。
IP核设计(PLL

1.3.3 时钟网络
本工程共有5个时钟,硬件上的晶振提供的50M时钟。由于摄像头的驱动时钟为25M,因此需要由锁相环产生一个25M的时钟xclk,摄像头输出图像数据的同时,会输出一个像素时钟pclk,该时钟是和图像数据对齐的,由于摄像头属于外设,是临时插在开发板上的,因此,插得不牢、晃动、碰撞等,都有可能造成摄像头输出的时钟pclk的不稳定,因此这里将此时钟经过锁相环,产生一个同频同相的稳定时钟clk_25M,作为之后图像处理模块的工作时钟。而SDRAM的工作时钟是100M,因此需要通过锁相环产生100M的时钟。通过架构图中模块的颜色来进行判别,按键检测模块、配置模块和SCCB模块都是采用的xclk;图像采集模块、存储控制模块和VGA接口模块都是采用的clk_25MSDRAM接口模块的工作时钟为100M

1.4 配置模块设计
1.4.1接口信号
  
信号名
  
I/O
位宽
定义
clk
I
1
工作时钟 100M
rst_n
I
1
系统复位信号,低电平有效
Config_en
I
1
开始配置指示脉冲
rdy
I
1
下游模块准备好指示信号
rdata
I
8
从摄像头中读取的数据
rdata_vld
I
1
读取数据有效指示信号
Wdata
O
8
将要写到摄像头中的数据
Wr_en
O
2
写使能
Addr
O
8
摄像头寄存器地址信号
rd_en
O
1
读使能
Cmos_en
O
1
配置完成指示信号
Pwdn
O
1
摄像头待机状态指示信号

1.4.2配置表
需要配置的寄存器信息都在配置表文件中保存,通过寄存器计数器reg_cnt进行读取,18bit位宽的信号add_wdata为保存配置信息的信号,其中add_wdata[17]表示读属性,当其为1时,表示该寄存器可读;daa_wdata[16]表示写属性,当其为1时,表示该寄存器可写;add_wdata[17:8]表示寄存器地址;add_wdata[7:0]表示要往寄存器中写入的值。

寄存器地址表示的寄存器以及数据每一位代表的意思,可以参考ov7670_中文版数据手册

OV7670摄像头模块资料及参考学习资料

举例说明:add_wdata={2’b11,16’h1e31},其中2’b11表示该寄存器可读可写,寄存器地址为8’h1e,查数据手册可知,寄存器名为MVFP,表示水平镜像/竖直翻转使能。数据的位[7:8]作为保留位,没有作用;位[5]表示水平镜像使能,0为正常,1为镜像;位[4]表示竖直翻转使能,0为正常,1为翻转;位[3]保留;位[2]表示消除黑太阳使能;位[10]保留。写数据为8’h31,表示开启水平镜像和竖直翻转。
注意,该文件不可综合,不要添加到编译软件中综合,否则会报错,只需要将此文件放到工程目录下即可。

1.4.3参考代码
  • parameter      REG_NUM =       164;
  • always@(*) begin
  •             case(reg_cnt)
  •                     0   : add_wdata = {2'b11,16'h1204};
  •                 1   : add_wdata = {2'b11,16'h40d0};
  •                 2   : add_wdata = {2'b11,16'h3a04};
  •                 3   : add_wdata = {2'b11,16'h3dc8};
  •                 4   : add_wdata = {2'b11,16'h1e31};
  •                 5   : add_wdata = {2'b11,16'h6b00};
  •                 6   : add_wdata = {2'b11,16'h32b6};
  •                 7   : add_wdata = {2'b11,16'h1713};
  •                 8   : add_wdata = {2'b11,16'h1801};
  •                 9   : add_wdata = {2'b11,16'h1902};
  •                 10  : add_wdata = {2'b11,16'h1a7a};
  •                 11  : add_wdata = {2'b11,16'h030a};
  •                 12  : add_wdata = {2'b11,16'h0c00};
  •                 13  : add_wdata = {2'b11,16'h3e10};
  •                 14  : add_wdata = {2'b11,16'h7000};
  •                 15  : add_wdata = {2'b11,16'h7100};
  •                 16  : add_wdata = {2'b11,16'h7211};
  •                 17  : add_wdata = {2'b11,16'h7300};
  •                 18  : add_wdata = {2'b11,16'ha202};
  •                 19  : add_wdata = {2'b11,16'h1180};
  •                 20  : add_wdata = {2'b11,16'h7a20};
  •                 21  : add_wdata = {2'b11,16'h7b1c};
  •                 22  : add_wdata = {2'b11,16'h7c28};
  •                 23  : add_wdata = {2'b11,16'h7d3c};
  •                 24  : add_wdata = {2'b11,16'h7e55};
  •                 25  : add_wdata = {2'b11,16'h7f68};
  •                 26  : add_wdata = {2'b11,16'h8076};
  •                 27  : add_wdata = {2'b11,16'h8180};
  •                 28  : add_wdata = {2'b11,16'h8288};
  •                 29  : add_wdata = {2'b11,16'h838f};
  •                 30  : add_wdata = {2'b11,16'h8496};
  •                 31  : add_wdata = {2'b11,16'h85a3};
  •                 32  : add_wdata = {2'b11,16'h86af};
  •                 33  : add_wdata = {2'b11,16'h87c4};
  •                 34  : add_wdata = {2'b11,16'h88d7};
  •                 35  : add_wdata = {2'b11,16'h89e8};
  •                 36  : add_wdata = {2'b11,16'h13e0};
  •                 37  : add_wdata = {2'b11,16'h0010};
  •                 38  : add_wdata = {2'b11,16'h1000};
  •                 39  : add_wdata = {2'b11,16'h0d00};
  •                 40  : add_wdata = {2'b11,16'h1428};
  •                 41  : add_wdata = {2'b11,16'ha505};
  •                 42  : add_wdata = {2'b11,16'hab07};
  •                 43  : add_wdata = {2'b11,16'h2475};
  •                 44  : add_wdata = {2'b11,16'h2563};
  •                 45  : add_wdata = {2'b11,16'h26a5};
  •                 46  : add_wdata = {2'b11,16'h9f78};
  •                 47  : add_wdata = {2'b11,16'ha068};
  •                 48  : add_wdata = {2'b11,16'ha103};
  •                 49  : add_wdata = {2'b11,16'ha6df};
  •                 50  : add_wdata = {2'b11,16'ha7df};
  •                 51  : add_wdata = {2'b11,16'ha8f0};
  •                 52  : add_wdata = {2'b11,16'ha990};
  •                 53  : add_wdata = {2'b11,16'haa94};
  •                 54  : add_wdata = {2'b11,16'h13ef};
  •                 55  : add_wdata = {2'b11,16'h0e61};
  •                 56  : add_wdata = {2'b11,16'h0f4b};
  •                 57  : add_wdata = {2'b11,16'h1602};
  •                 58  : add_wdata = {2'b11,16'h2102};
  •                 59  : add_wdata = {2'b11,16'h2291};
  •                 60  : add_wdata = {2'b11,16'h2907};
  •                 61  : add_wdata = {2'b11,16'h330b};
  •                 62  : add_wdata = {2'b11,16'h350b};
  •                 63  : add_wdata = {2'b11,16'h371d};
  •                 64  : add_wdata = {2'b11,16'h3871};
  •                 65  : add_wdata = {2'b11,16'h392a};
  •                 66  : add_wdata = {2'b11,16'h3c78};
  •                 67  : add_wdata = {2'b11,16'h4d40};
  •                 68  : add_wdata = {2'b11,16'h4e20};
  •                 69  : add_wdata = {2'b11,16'h6900};
  •                 70  : add_wdata = {2'b11,16'h7419};
  •                 71  : add_wdata = {2'b11,16'h8d4f};
  •                 72  : add_wdata = {2'b11,16'h8e00};
  •                 73  : add_wdata = {2'b11,16'h8f00};
  •                 74  : add_wdata = {2'b11,16'h9000};
  •                 75  : add_wdata = {2'b11,16'h9100};
  •                 76  : add_wdata = {2'b11,16'h9200};
  •                 77  : add_wdata = {2'b11,16'h9600};
  •                 78  : add_wdata = {2'b11,16'h9a80};
  •                 79  : add_wdata = {2'b11,16'hb084};
  •                 80  : add_wdata = {2'b11,16'hb10c};
  •                 81  : add_wdata = {2'b11,16'hb20e};
  •                 82  : add_wdata = {2'b11,16'hb382};
  •                 83  : add_wdata = {2'b11,16'hb80a};
  •                 84  : add_wdata = {2'b11,16'h4314};
  •                 85  : add_wdata = {2'b11,16'h44f0};
  •                 86  : add_wdata = {2'b11,16'h4534};
  •                 87  : add_wdata = {2'b11,16'h4658};
  •                 88  : add_wdata = {2'b11,16'h4728};
  •                 89  : add_wdata = {2'b11,16'h483a};
  •                 90  : add_wdata = {2'b11,16'h5988};
  •                 91  : add_wdata = {2'b11,16'h5a88};
  •                 92  : add_wdata = {2'b11,16'h5b44};
  •                 93  : add_wdata = {2'b11,16'h5c67};
  •                 94  : add_wdata = {2'b11,16'h5d49};
  •                 95  : add_wdata = {2'b11,16'h5e0e};
  •                 96  : add_wdata = {2'b11,16'h6404};
  •                 97  : add_wdata = {2'b11,16'h6520};
  •                 98  : add_wdata = {2'b11,16'h6605};
  •                 99  : add_wdata = {2'b11,16'h9404};
  •                 100 : add_wdata = {2'b11,16'h9508};
  •                 101 : add_wdata = {2'b11,16'h6c0a};
  •                 102 : add_wdata = {2'b11,16'h6d55};
  •                 103 : add_wdata = {2'b11,16'h6e11};
  •                 104 : add_wdata = {2'b11,16'h6f9f};
  •                 105 : add_wdata = {2'b11,16'h6a40};
  •                 106 : add_wdata = {2'b11,16'h0140};
  •                 107 : add_wdata = {2'b11,16'h0240};
  •                 108 : add_wdata = {2'b11,16'h13e7};
  •                 109 : add_wdata = {2'b11,16'h1500};
  •                 110 : add_wdata = {2'b11,16'h4f80};
  •                 111 : add_wdata = {2'b11,16'h5080};
  •                 112 : add_wdata = {2'b11,16'h5100};
  •                 113 : add_wdata = {2'b11,16'h5222};
  •                 114 : add_wdata = {2'b11,16'h535e};
  •                 115 : add_wdata = {2'b11,16'h5480};
  •                 116 : add_wdata = {2'b11,16'h589e};
  •                 117 : add_wdata = {2'b11,16'h4108};
  •                 118 : add_wdata = {2'b11,16'h3f00};
  •                 119 : add_wdata = {2'b11,16'h7505};
  •                 120 : add_wdata = {2'b11,16'h76e1};
  •                 121 : add_wdata = {2'b11,16'h4c00};
  •                 122 : add_wdata = {2'b11,16'h7701};
  •                 123 : add_wdata = {2'b11,16'h4b09};
  •                 124 : add_wdata = {2'b11,16'hc9F0};
  •                 125 : add_wdata = {2'b11,16'h4138};
  •                 126 : add_wdata = {2'b11,16'h5640};
  •                 127 : add_wdata = {2'b11,16'h3411};
  •                 128 : add_wdata = {2'b11,16'h3b02};
  •                 129 : add_wdata = {2'b11,16'ha489};
  •                 130 : add_wdata = {2'b11,16'h9600};
  •                 131 : add_wdata = {2'b11,16'h9730};
  •                 132 : add_wdata = {2'b11,16'h9820};
  •                 133 : add_wdata = {2'b11,16'h9930};
  •                 134 : add_wdata = {2'b11,16'h9a84};
  •                 135 : add_wdata = {2'b11,16'h9b29};
  •                 136 : add_wdata = {2'b11,16'h9c03};
  •                 137 : add_wdata = {2'b11,16'h9d4c};
  •                 138 : add_wdata = {2'b11,16'h9e3f};
  •                 139 : add_wdata = {2'b11,16'h7804};
  •                  140 :add_wdata =  {2'b11,16'h7901};
  •                  141 :add_wdata =  {2'b11,16'hc8f0};
  •                  142 :add_wdata =  {2'b11,16'h790f};
  •                  143 :add_wdata =  {2'b11,16'hc800};
  •                  144 :add_wdata =  {2'b11,16'h7910};
  •                  145 :add_wdata =  {2'b11,16'hc87e};
  •                  146 :add_wdata =  {2'b11,16'h790a};
  •                  147 :add_wdata =  {2'b11,16'hc880};
  •                  148 :add_wdata =  {2'b11,16'h790b};
  •                  149 :add_wdata =  {2'b11,16'hc801};
  •                  150 :add_wdata =  {2'b11,16'h790c};
  •                  151 :add_wdata =  {2'b11,16'hc80f};
  •                  152 :add_wdata =  {2'b11,16'h790d};
  •                  153 :add_wdata =  {2'b11,16'hc820};
  •                  154 :add_wdata =  {2'b11,16'h7909};
  •                  155 :add_wdata =  {2'b11,16'hc880};
  •                  156 :add_wdata =  {2'b11,16'h7902};
  •                  157 :add_wdata =  {2'b11,16'hc8c0};
  •                  158 :add_wdata =  {2'b11,16'h7903};
  •                  159 :add_wdata =  {2'b11,16'hc840};
  •                  160 :add_wdata =  {2'b11,16'h7905};
  •                  161 :add_wdata =  {2'b11,16'hc830};
  •                  162 :add_wdata =  {2'b11,16'h7926};
  •                  163 : add_wdata = {2'b11,16'h0903};
  •                  164 : add_wdata = {2'b11,16'h3b42};
  •             default : add_wdata = 0;
  •             endcase
  •         end


[color=rgb(51, 102, 153) !important]复制代码


使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /5 下一条

在线客服 快速回复 返回顶部 返回列表