使用c#做一个 udp接收视频图像的软件,验证fpga开发千兆网,百兆网传输摄像头
话不多说,先设计界面

因为使用,udp接收数据,所以需要配置端口号,咱们可以默认32768
然后就是图像大小
640*480
1024*768
1280*480
1920*240
160*240
raw格式类型
Gray
RGGB
GRBG
GGBR
BGGR
使用多线程后台采集数据
private void button1_Click(object sender, EventArgs e)
{
try
{
{
threadUdp = new Thread(new ParameterizedThreadStart(img_UDP));
threadUdp.IsBackground = true;
threadUdp.Start(this);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
定义好全局变量,用于展示工作过程信息
Thread threadUdp;
byte[] udp_img_buff = new byte[640 * 480 * 2];
UInt32 udp_img_size = 640 * 480;
UInt32 readCnt = 0;
UInt32 readPakCnt = 0;
UInt32 readFilCnt = 0;
UInt32 bmpCnt = 0;
Bitmap curBitmap = null;
UInt32[] bmphist = new UInt32[256];
int bmp_w = 1280;
int bmp_h = 480;
public static int gain_r = 50;
public static int gain_g = 50;
public static int gain_b = 50;
static int format = 0;
收到的网络数据直接显示
public void img_UDP(object objPort)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 32768);
EndPoint ep = (EndPoint)iep;
socket.Bind(iep);
string str = "";
while (true)
{
int len = 0;
string str1 = "";
byte[] buffer = new byte[16384];
try
{
len = socket.ReceiveFrom(buffer, ref ep);
if (len == 1280)
{
readCnt += (UInt32)len;
readPakCnt++;
if (udp_img_size >= 640 * 480)
{
udp_img_size = 0;
curBitmap = BuiltRGB24Bitmap(udp_img_buff, 640, 480);
pictureBox1.Invoke(new MethodInvoker(() => pictureBox1.Image = curBitmap));
bmpCnt++;
for (int i = 0; i < bmphist.Length; i++)
{
bmphist[i] = 0;
}
for (int i = 0; i < udp_img_buff.Length; i++)
{
bmphist[udp_img_buff[i]]++;
}
}
else
{
if (udp_img_size == 0)
{
if (buffer[0] != 0)
{
readFilCnt++;
continue;
}
//if(buffer.All(item=>item==0))
{
for (int i = 0; i < 1280; i++)
{
udp_img_buff[udp_img_size + i] = buffer[i];
}
udp_img_size += 1280;
}
// else
{
// readFilCnt++;
}
}
else
{
for (int i = 0; i < 1280; i++)
{
udp_img_buff[udp_img_size + i] = buffer[i];
}
udp_img_size += 1280;
}
}
}
else
{
readFilCnt++;
}
}
catch
{
continue;
}
int cmdlen = buffer[3] * 256 + buffer[2];
}
}
显示效果如下

此次使用的rtl8201 百兆网卡,mii模式传输,摄像头使用为ov7670
下次可以考虑使用更优质高分辨率摄像头验证
也可以使用千兆以太网验证


IDE40-J2接rtl8201模块
j5接摄像头 ov7670
使用qii 生产tcl配置文件如下
set_location_assignment PIN_E1 -to clk
set_location_assignment PIN_M15 -to rst_n
set_location_assignment PIN_D5 -to E_RXC
set_location_assignment PIN_A11 -to E_RXDV
set_location_assignment PIN_B12 -to E_RXD[0]
set_location_assignment PIN_A12 -to E_RXD[1]
set_location_assignment PIN_B13 -to E_RXD[2]
set_location_assignment PIN_A13 -to E_RXD[3]
set_location_assignment PIN_C6 -to E_TXD[0]
set_location_assignment PIN_E7 -to E_TXD[1]
set_location_assignment PIN_F8 -to E_TXD[2]
set_location_assignment PIN_D8 -to E_TXD[3]
set_location_assignment PIN_C8 -to E_TXEN
set_location_assignment PIN_D6 -to E_TXC
set_location_assignment PIN_K1 -to cam1_data[7]
set_location_assignment PIN_J2 -to cam1_data[6]
set_location_assignment PIN_L1 -to cam1_data[5]
set_location_assignment PIN_K2 -to cam1_data[4]
set_location_assignment PIN_M6 -to cam1_data[3]
set_location_assignment PIN_L2 -to cam1_data[2]
set_location_assignment PIN_M7 -to cam1_data[1]
set_location_assignment PIN_N5 -to cam1_data[0]
set_location_assignment PIN_G1 -to cam1_vsync
set_location_assignment PIN_F2 -to cam1_hsync
set_location_assignment PIN_J1 -to cam1_pclk
set_location_assignment PIN_G2 -to cam1_xclk
set_location_assignment PIN_N6 -to cam1_pdown
set_location_assignment PIN_M10 -to cam1_reset
set_location_assignment PIN_F1 -to cam1_scl
set_location_assignment PIN_F3 -to cam1_sda
顶层文件
//file name: top_fpga.v
//author: ETree
//date: 2017.10.1
//function: top file of project
//log:
module top_v011_lan(
//global signal
input clk,
input rst_n,
//CMOS Port
output cam_scl,
inout cam_sda,
input [7:0] cam_data,
input cam_vsync,
input cam_hsync,
input cam_pclk,
output cam_xclk,
output cam_pdown,
output cam_reset,
//cmos1
output cam1_scl,
inout cam1_sda,
input cam1_vsync,
input cam1_hsync,
input cam1_pclk,
output cam1_xclk,
output cam1_pdown,
output cam1_reset,
input [7:0] cam1_data,
//cmos2
output cam2_scl,
inout cam2_sda,
input cam2_vsync,
input cam2_hsync,
input cam2_pclk,
output cam2_xclk,
output cam2_pdown,
output cam2_reset,
input [7:0] cam2_data,
//ETHERNET Port
output E_RESET ,
input E_RXC,
input E_RXDV,
input [3:0] E_RXD,
input E_RXER,
input E_TXC,
output E_TXEN,
output [3:0] E_TXD,
//UART Port
input rxd,
output txd
);
wire [31:0] crc;
wire [31:0] crc_next;
wire crcen;
wire crcre;
wire [10:0] frame_index;
wire [15:0] tx_data_length;
wire [15:0] tx_total_length;
wire fifo_rd_en;
wire [31:0] datain;
wire [10:0] fifo_data_count;
wire [31:0] fifo_q;
wire [15:0] line_count;
wire locked;
wire clk_12M;
wire clk_100M;
reg [15:0] rst_cnt;
reg rstn;
parameter IMG_HDISP = 16'd640;
parameter IMG_VDISP = 16'd480;
assign tx_data_length = 16'd8+640*2; //8+640+640
assign tx_total_length = 16'd28+640*2; //20+8+256
assign frame_index = 0;
alt_pll alt_pll_inst(
.inclk0(clk),
.c0(clk_12M),
.c1(clk_100M),
.locked(locked)
);
//----------CMOS------------
wire [7:0] cam_data_out;
wire cam_vsync_out;
wire cam_hsync_out;
I2C_AV_Config I2C_AV_Config_inst
(
.iCLK(clk_12M),
.iRST_N(rstn),
.I2C_SCLK(cam1_scl),
.I2C_SDAT(cam1_sda),
);
camera_if camera_if_inst
(
.clk(clk_12M) , // input clk_sig
.rst_n(rstn) , // input rst_n_sig
.rx_data(uart_rx_data),
.rx_done(rx_done),
.cam_scl() , // output cam1_scl
.cam_sda() , // inout cam1_sda
.cam_data(cam1_data) , // input [7:0] cam_data_sig
.cam_vsync(cam1_vsync) , // input cam_vsync_sig
.cam_hsync(cam1_hsync) , // input cam_hsync_sig
.cam_pclk(cam1_pclk) , // input cam_pclk_sig
.cam_xclk(cam1_xclk) , // output cam_xclk_sig
.cam_pdown(cam1_pdown) , // output cam_pdown_sig
.cam_reset(cam1_reset) , // output cam_reset_sig
.cam_data_out(cam_data_out),
.cam_vsync_out(cam_vsync_out),
.cam_hsync_out(cam_hsync_out),
.line_count(line_count),
.cam_en(1'b1) // input cam_en_sig
);
defparam camera_if_inst.IMG_H=640;
//------------UART---------------
wire [23:0] uart_rx_data;
wire rx_done;
myuart myuart_inst(
.clk(clk),
.rst_n(1'b1),
.rxd(rxd),
.txd(txd),
.rx_done(rx_done),
.data_out(uart_rx_data )
);
//--------------------------------
always @(posedge clk)
if(rst_cnt>=16'hfffa)
rst_cnt <= rst_cnt;
else
rst_cnt <= rst_cnt + 1'b1;
always @(posedge clk)
if(rst_cnt>=16'hfff0)
rstn <= 1'b1;
else
rstn <= 0;
//-----------FIFO------------------
assign {datain[7:0],datain[15:8],datain[23:16],datain[31:24]} = fifo_q;
wrfifo0832 wrfifo_inst
(
.aclr(~rstn | cam_vsync_out) , // input aclr
.data(cam_data_out) , // input [15:0] data
.rdclk(~E_TXC) , // input rdclk
.rdreq(fifo_rd_en) , // input rdreq
.wrclk(cam1_pclk) , // input wrclk
.wrreq(cam_hsync_out) , // input wrreq
.q(fifo_q) , // output [63:0] q
.rdempty() , // output rdempty
.rdusedw(fifo_data_count), // output [6:0] rdusedw
.wrfull() , // output wrfull
.wrusedw() // output [8:0] wrusedw
);
ipsend ipsend_inst
(
.clk(E_TXC ) , // input clk
.txen(E_TXEN ) , // output txen
.txer() , // output txer
.dataout(E_TXD ) , // output [4:0] dataout
.rst_n(rstn ) , // input rst_n
.crc(crc ) , // input [31:0] crc
.crc_next(crc_next),
.crcen(crcen ) , // output crcen
.crcre(crcre ) , // output crcre
.datain(datain ) , // input [31:0] datain 32'h12345678
.fifo_data_count(fifo_data_count ) , // input [10:0] fifo_data_count
.fifo_rd_en(fifo_rd_en ) , // output fifo_rd_en
.frame_index(frame_index ) , // input [10:0] frame_index
.tx_state(tx_state ) , // output [3:0] tx_state
.tx_data_length(tx_data_length ) , // input [15:0] tx_data_length
.tx_total_length(tx_total_length ) // input [15:0] tx_total_length
);
crc b2v_inst(
.Clk(E_TXC),
.Reset(crcre),
.Enable(crcen),
.Data(E_TXD),
.Crc(crc),
.CrcNext(crc_next)
);
assign E_RESET = rstn;
endmodule
摄像头时钟配置为12.5Mhz
浙公网安备 33010602011771号