本帖最后由 冒险武者 于 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屏那就更加完美
视频如下:
1
大家可以看到闪屏,抓取的照片不是很花屏现场等等问题,研发就是遇到问题,分析问题,解决问题过程,这次试用对个人能力有一定提升,总体体验不错。
|