本帖最后由 冒险武者 于 2022-8-1 00:17 编辑
利用周末空闲时间,简易板照相机只能说基本功能达到了,主要功能如下
1.实时显示视频流
2.按拍照按钮后,把图像数据存到sdram中,然后存到sd卡
3.视频显示用的是VGA显示屏(可惜没有TFT_LCD接口)
按钮的定义:按键0:模式选择:视频流与查看照片 按键1与3上下翻找照片,按键3打开拍照,拍完后返回视频流,如下所示:
- always@(posedge camera_wclk or negedge rst_n)
- begin
- if(!rst_n) begin
- pai_cnt <= 2'b00 ;
- mode <= 1'b1 ;
- pai_en <= 1'b0 ;
- end
- else if((tim == 8'd40) && pai_en ) begin //&& (camera_addr == 16'h0)
- pai_en <= 1'b0 ;
- mode <= 1'b1 ;
- end
- else if(key_pulse[0]) begin //mode
- mode <= ~mode ;
- pai_cnt <= 8'h0 ;
- end
- else if(key_pulse[1]) begin //up
- pai_cnt <= pai_cnt + 1'b1;
- end
- else if(key_pulse[2]) begin //pai
- mode <= 1'b0 ;
- pai_en <= 1'b1 ;
- pai_cnt <= pai_cnt + 1'b1;
- end
- else if(key_pulse[3]) begin//down
- pai_cnt <= pai_cnt - 1'b1;
- end
- end
-
- always@(posedge clk_50m or negedge rst_n)
- begin
- if(!rst_n)
- key_led <= 5'h1F;
- else if(key_pulse[0])
- key_led[0] <= ~key_led[0];
- else if(key_pulse[1])
- key_led[1] <= ~key_led[1];
- else if(key_pulse[2])
- key_led[2] <= ~key_led[2];
- else if(key_pulse[3])
- key_led[3] <= ~key_led[3];
- else if(key_pulse[4])
- key_led[4] <= ~key_led[4];
- else
- key_led <= key_led;
- end
sdram的控制直接修改例程获得
- Sdram_Control_4Port Sdram_Control(
- // HOST Side
- .CTRL_CLK(clk_sdr_ctrl), //输入参考时钟,默认100M,如果为其他频率,请修改pll设置
- .SDRAM_CLK(clk_sdram), //SDRAM时钟,默认100M(90°),如果为其他频率,请修改pll设置
- .RESET_N(rst_n), //复位输入,低电平复位
-
- // FIFO Write Side 1
- .WR1_DATA(camera_wrdat), //写入端口1的数据输入端16bit
- .WR1(camera_wrreq), //写入端口1的写使能端,高电平写入
- .WR1_ADDR(21'b0), //写入端口1的写起始地址
- .WR1_MAX_ADDR((IMG_W*IMG_H)), //写入端口1的写入最大地址
- // .WR1_LENGTH(10'd1), //一次性写入数据长度
- .WR1_LENGTH(10'd256), //一次性写入数据长度
- .WR1_LOAD((~rst_n)&(init_ready) ),
- //写入端口1清零请求,高电平清零写入地址和fifo
- .WR1_CLK(camera_wclk), //写入端口1 fifo写入时钟
- .WR1_FULL(), //写入端口1 fifo写满信号
- .WR1_USE(), //写入端口1 fifo已经写入的数据长度
- // FIFO Write Side 2
- .WR2_DATA(sd_wrdat), //写入端口2的数据输入端16bit
- .WR2(1'b0), //写入端口2的写使能端,高电平写入
- .WR2_ADDR(21'd32800), //写入端口2的写起始地址
- .WR2_MAX_ADDR(32800), //写入端口2的写入最大地址 (IMG_W*IMG_H)
- .WR2_LENGTH(9'd256), //一次性写入数据长度
- .WR2_LOAD((~rst_n)&(init_ready)), //写入端口2清零请求,高电平清零写入地址和fifo
- .WR2_CLK(sd_clk), //写入端口2 fifo写入时钟
- .WR2_FULL(), //写入端口2 fifo写满信号
- .WR2_USE(), //写入端口2 fifo已经写入的数据长度
- // FIFO Read Side 1
- .RD1_DATA(sd_rddat), //读出端口1的数据输出端16bit
- .RD1(sd_rden), //读出端口1的读使能端,高电平读出
- .RD1_ADDR(21'b0), //读出端口1的读起始地址
- .RD1_MAX_ADDR(32800), //读出端口1的读出最大地址(IMG_W*IMG_H)
- // .RD1_LENGTH(10'd1), //一次性读出数据长度
- .RD1_LENGTH(10'd256), //一次性读出数据长度
- .RD1_LOAD((~rst_n) & (init_ready)),
- //读出端口1 清零请求,高电平清零读出地址和fifo
- .RD1_CLK(sd_clk), //读出端口1 fifo读取时钟
- .RD1_EMPTY(), //读出端口1 fifo读空信号
- .RD1_USE(), //读出端口1 fifo已经还可以读取的数据长度
-
- // FIFO Read Side 2
- .RD2_DATA(sd_rddat), //读出端口2的数据输出端16bit
- .RD2(vga_den), //读出端口2的读使能端,高电平读出
- .RD2_ADDR(21'd32800), //读出端口2的读起始地址
- .RD2_MAX_ADDR((IMG_W*IMG_H)), //读出端口2的读出最大地址
- .RD2_LENGTH(9'd256), //一次性读出数据长度
- .RD2_LOAD((~rst_n) & (init_ready)), //读出端口2清零请求,高电平清零读出地址和fifo
- .RD2_CLK(clk_lcd), //读出端口2 fifo读取时钟
- .RD2_EMPTY(), //读出端口2 fifo读空信号
- .RD2_USE() //读出端口2 fifo已经还可以读取的数据长度
- );
SD读写是SPI协议控制,copy正点原子的相关文件后修改的获得
- //SD卡顶层控制模块
- sd_ctrl_top u_sd_ctrl_top(
- .clk_ref (clk_sd),
- .clk_ref_180deg (clk_sd_180deg),
- .rst_n (rst_n),
- //SD卡接口
- .sd_miso (sd_miso),
- .sd_clk (sd_clk),
- .sd_cs (sd_cs),
- .sd_mosi (sd_mosi),
- //用户写SD卡接口
- .wr_start_en (wr_start_en),
- .wr_sec_addr (wr_sec_addr),
- .wr_data (wr_data),
- .wr_busy (wr_busy),
- .wr_req (wr_req),
- //用户读SD卡接口
- .rd_start_en (rd_start_en),
- .rd_sec_addr (rd_sec_addr),
- .rd_busy (rd_busy),
- .rd_val_en (rd_val_en),
- .rd_val_data (rd_val_data),
-
- .sd_init_done (sd_init_done)
- );
需要强调的是SD卡中存数据无法形成照片,因为涉及到照片格式与文件相关簇信息管理,暂时搞不定,这个可以研究手册
视频显示用的是VGA接口显示器,可惜该单板没有预留TFT_LCD显示屏,用TFT_LCD屏那就更加完美
视频如下:
鎾斁鍣ㄥ姞杞藉け璐�: 鏈娴嬪埌Flash Player锛岃鍒� 瀹夎
1
大家可以看到闪屏,抓取的照片不是很花屏现场等等问题,研发就是遇到问题,分析问题,解决问题过程,这次试用对个人能力有一定提升,总体体验不错。
|