ADN8810驱动
- 可以直接使用,启动信号大于一个时钟周期即可,启动信号可与写入数据同步输入,也可稍晚输入
//adn8810 椹卞姩
`define data_in_width 12
`define data_width 16
`define state_width 5
`define move_width 5
module adn8810(
input clk_100,
input rst_n,
input start_sig,
input [`data_in_width-1:0] data_in,
output reg SCLK,
output reg CS_adn8810,
output reg SDI,
output reg RESER_adn
);
parameter IDLE = `state_width'd1,
RESET_adn = `state_width'd2,
Start = `state_width'd4,
Work = `state_width'd8,
Stop = `state_width'd16;
reg [`state_width-1:0] current_state, next_state;
wire adn_addr = 3'b000;
wire [`data_width-1:0] data;
reg [`data_width-1:0] data_r;
reg [2:0] count_SCLK;
reg [`move_width-1:0] count_move;
assign data = {{1'b0},{adn_addr},{data_in}};
always @ (posedge clk_100 or negedge rst_n)
if(!rst_n)
current_state <= RESET_adn;
else
current_state <= next_state;
always @ (current_state or start_sig or SCLK or count_SCLK or count_move) //鐢靛钩瑙﹀彂
// always@(posedge clk_100 or posedge start_sig)
case(current_state)
RESET_adn:if(count_SCLK ==3'd3)
next_state = IDLE;
else
next_state = RESET_adn;
IDLE: if(start_sig)
next_state = Start; //闃诲璧嬪??
else
next_state = IDLE;
Start:if(SCLK == 1'b1)
next_state = Work; //闃诲璧嬪??
else
next_state = Start;
Work:if( count_move == `move_width'd16 && SCLK == 1'b1 && count_SCLK == 3'd1)
next_state = Stop;
else
next_state = Work;
Stop:if(count_SCLK == 3'd3)
next_state = IDLE;
else
next_state = Stop;
default:
next_state = IDLE;
endcase
//绗笁涓繘绋嬶紝鍚屾鏃跺簭always妯″潡锛屾牸寮忓寲鎻忚堪娆℃?佸瘎瀛樺櫒杈撳嚭
always @ (posedge clk_100 or negedge rst_n)
if(!rst_n)begin
CS_adn8810 <=1'b1;
SDI <=1'b0;
RESER_adn <= 1'b1;
end
else
case(current_state)
IDLE:begin
SDI <=1'b0;
count_move <= `move_width'd0;
end
RESET_adn:begin
RESER_adn <= 1'b0;
if(count_SCLK ==3'd3)
RESER_adn <= 1'b1;
end
Work:begin
if(count_SCLK == 3'd3 && SCLK == 1'b1)begin
CS_adn8810 <= 1'b0;
SDI <= data_r[15];
count_move <= count_move + 1'b1;
end
end
Stop:begin
CS_adn8810 <=1'b1;
end
default:begin
CS_adn8810 <=CS_adn8810;
SDI <=SDI;
count_move <= count_move;
RESER_adn <= RESER_adn;
end//default鐨勪綔鐢ㄦ槸鍏嶉櫎缁煎悎宸ュ叿缁煎悎鍑洪攣瀛樺櫒
endcase
always@(posedge clk_100)begin
if(!rst_n)begin
SCLK <=1'b0;
count_SCLK <= 3'd0;
end
else if(current_state == RESET_adn)begin
if(count_SCLK == 3'd3)begin
count_SCLK <= count_SCLK;
count_SCLK <= 3'd0;
end
else
count_SCLK <= count_SCLK +'b1;
end
// else if(current_state == Start || current_state == Work)begin
else if(current_state == Start || current_state == Work || current_state == Stop )begin
if(count_SCLK == 3'd3)begin
SCLK <= ~SCLK;
count_SCLK <= 3'd0;
end
else
count_SCLK <= count_SCLK +'b1;
end
else if(current_state == Stop)begin
if(count_SCLK == 3'd3)begin
count_SCLK <= 3'd0;
SCLK <= 1'b0;
end
else
count_SCLK <= count_SCLK + 1'b1;
end
end
always@(posedge clk_100)begin
if(current_state == Start)
data_r <= data;
else if(current_state == Work && count_SCLK == 3'd0 && SCLK == 1'b0)
data_r <= data_r << 1;
end
endmodule
module adn8810_tb(
);
reg clk_50,rst_n;
reg start_sig;
reg [11:0] data_in;
initial
begin
clk_50 = 1'b0;
start_sig = 1'b0;
rst_n = 1'b1;
#3 rst_n = 1'b0;
#3 rst_n = 1'b1;
#10start_sig = 1'b1;
data_in = 12'b1111_0000_1111;
#2 start_sig = 1'b0;
#1000 start_sig = 1'b0;
#10start_sig = 1'b1;
data_in = 12'b1010_1010_1010;
#2 start_sig = 1'b0;
end
always #1 clk_50 = ~clk_50;
wire CS_adn8810,SCLK, SDI,RESER_adn;
adn8810 adn8810(
.clk_100(clk_50), //input clk_50,
.rst_n(rst_n), //input rst_n,
.start_sig(start_sig) , //input start_sig,
.data_in(data_in) , //input [`data_in_width-1:0] data_in,
. SCLK(SCLK) , //output reg SCLK,
. CS_adn8810(CS_adn8810) , //output reg CS_adn8810,
. SDI(SDI), //output reg SDI,
. RESER_adn(RESER_adn) //output reg RESER_adn
);
endmodule
- 仿真图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190831165226299.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzI0MDM4Nw==,size_16,color_FFFFFF,t_70)