数字振镜XY2-100协议

数字振镜XY2-100协议

AMENG
2023-07-06 / 0 评论 / 17 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年07月06日,已超过296天没有更新,若内容或图片失效,请留言反馈。

一、协议格式

XY2-100波形图.jpg

该协议时钟(SENDCK)为2MHz ,SYNC为同步信号,CHANNELX/Y 是数据信号,它有20位组成,其中C2、C1、C0是振镜运动方向值,参考值为001,D15—D0是数据位,它是16位的二进制数,用来控制振镜转过的角度大小(取值为0~65535,即将振镜轴的转动角度范围映射到0~65535);最后一位是偶校验位,当发送的数 据中有偶数个“1”时,对应的校验位为“0”。当发送的数据中有奇数个“1”时对应的校验位为“1”。

二、FPGA(Verilog)代码实现

module xy2_100(
//端口列表
 rst_n,
 clk50m,
 send_en,
 x_data,
 y_data,
 
 sendck,
 sync,
 chl_x,
 chl_y,
 TxDone,
 xy2_state
);
//端口定义
   input rst_n;
   input clk50m;
   input send_en;
   input [15:0]x_data;
   input [15:0]y_data;
   output reg sendck;
   output reg sync;
   output reg chl_x;
   output reg chl_y;
   output reg TxDone;
   output reg xy2_state;
   reg [4:0]div_cnt;//分频计数器
reg [4:0]bps_cnt;//波特率时钟计数器
reg [15:0]r_data_x;
reg [15:0]r_data_y;
localparam bps_DR = 5'd24;     //分频计数最大值
localparam CTRL_WD = 3'b001;  //控制字
localparam MAX_BIT = 5'd20;
//发送状态信号
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
xy2_state <= 1'b0;
else if(send_en)
xy2_state <= 1'b1;
else if(bps_cnt == MAX_BIT)
xy2_state <= 1'b0;
else
xy2_state <= xy2_state;
//发送数据锁存
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
   r_data_x <= 15'd0;
else if(send_en)
   r_data_x <= x_data;
else
   r_data_x <= r_data_x;
always@(posedge clk50m or negedge rst_n)
if(!rst_n)
   r_data_y <= 15'd0;
else if(send_en)
   r_data_y <= y_data;
else
   r_data_y <= r_data_y;
//分频计数器
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
   div_cnt <= 5'd0;
else if(xy2_state||send_en) begin
  if(div_cnt == bps_DR)
    div_cnt <= 5'd0;
  else 
    div_cnt <= div_cnt+1'b1;
 end
else
 div_cnt <= 5'd0;
// bps counter
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
 bps_cnt <= 5'd0;
else if(bps_cnt==MAX_BIT)
 bps_cnt <= 5'd0;
else if(div_cnt==bps_DR)
 bps_cnt <= bps_cnt + 1'b1;
else
 bps_cnt <= bps_cnt;
 
// 发送完成信号
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
 TxDone <= 1'b0;
else if(bps_cnt == MAX_BIT)
 TxDone <= 1'b1;
else 
 TxDone <= 1'b0;
 
// x按位发送数据
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
  chl_x <= 1'b0;
else if(div_cnt==5'd0) begin
  case (bps_cnt)
  0:chl_x <= 1'b0; //c2
1:chl_x <= 1'b0; //c1
2:chl_x <= 1'b1; //c0
3:chl_x <= r_data_x[15];
4:chl_x <= r_data_x[14];
5:chl_x <= r_data_x[13];
6:chl_x <= r_data_x[12];
7:chl_x <= r_data_x[11];
8:chl_x <= r_data_x[10];
9:chl_x <= r_data_x[9];
10:chl_x <= r_data_x[8];
11:chl_x <= r_data_x[7];
12:chl_x <= r_data_x[6];
13:chl_x <= r_data_x[5];
14:chl_x <= r_data_x[4];
15:chl_x <= r_data_x[3];
16:chl_x <= r_data_x[2];
17:chl_x <= r_data_x[1];
18:chl_x <= r_data_x[0];
19:chl_x <= ^{CTRL_WD,r_data_x};  //偶校验
default:chl_x <= 1'b0;
  endcase
end
// y按位发送数据
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
  chl_y <= 1'b0;
else if(div_cnt==5'd0) begin
  case (bps_cnt)
  0:chl_y <= 1'b0; //c2
1:chl_y <= 1'b0; //c1
2:chl_y <= 1'b1; //c0
3:chl_y <= r_data_y[15];
4:chl_y <= r_data_y[14];
5:chl_y <= r_data_y[13];
6:chl_y <= r_data_y[12];
7:chl_y <= r_data_y[11];
8:chl_y <= r_data_y[10];
9:chl_y <= r_data_y[9];
10:chl_y <= r_data_y[8];
11:chl_y <= r_data_y[7];
12:chl_y <= r_data_y[6];
13:chl_y <= r_data_y[5];
14:chl_y <= r_data_y[4];
15:chl_y <= r_data_y[3];
16:chl_y <= r_data_y[2];
17:chl_y <= r_data_y[1];
18:chl_y <= r_data_y[0];
19:chl_y <= ^{CTRL_WD,r_data_y};  //偶校验
default:chl_y <= 1'b0;
  endcase
end
//同步信号
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
 sync <= 1'b0;
else if(send_en)
 sync <= 1'b1;
else if(bps_cnt==(MAX_BIT-1))    //&&(div_cnt==5'd0))
 sync <= 1'b0;
else
 sync <= sync;
//发送时钟信号
   always@(posedge clk50m or negedge rst_n)
if(!rst_n)
 sendck <= 1'b0;
else if((xy2_state||send_en)&&(bps_cnt<MAX_BIT)) begin
 if(div_cnt<=bps_DR/2)
  sendck <= 1'b1;
 else
  sendck <= 1'b0;
end
else
 sendck <= 1'b0;
endmodule


0

评论 (0)

取消