脚本宝典收集整理的这篇文章主要介绍了状态机练习-基于DAC8168C DAC电压输出,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
DAC8168C 时序图:
数据格式:
一组数据是32bit 至少产生32个sclk.
发送数据是在SCLK的上升延发出
利用状态机实现每个通道输出的电压不一样,每个状态之间延时50ms进行切换
状态机如下图:
代码:
1 module dac8168( 2 clk, 3 rst_n, 4 5 ldac_n, 6 clr_n, 7 sclk, 8 sync_n, 9 din 10 ); 11 12 parameter CONTROL = 4'b0010; 13 parameter ADDRESS = 4'b0000; 14 parameter DAC_DATA = 14'd300; //0.093V 15 //parameter DAC_DATA = 14'd16383; //4.98V 16 parameter FEATURE = 4'b0101; 17 18 parameter DLY_50MS = 2_500_000; 19 20 parameter A0 = 0; 21 parameter A1 = 1; 22 parameter A2 = 2; 23 parameter A3 = 3; 24 parameter A4 = 4; 25 parameter A5 = 5; 26 parameter A6 = 6; 27 parameter A7 = 7; 28 29 30 input clk; 31 input rst_n; 32 33 output ldac_n; 34 output clr_n; 35 output sclk; 36 output sync_n; 37 output din; 38 39 40 assign ldac_n = 1; 41 assign clr_n = 1; 42 43 reg sclk; 44 reg sync_n; 45 reg din; 46 reg flag_add; 47 48 wire add_cnt0; 49 wire end_cnt0; 50 51 wire add_cnt1; 52 wire end_cnt1; 53 54 wire add_cnt2; 55 wire end_cnt2; 56 57 wire A02A1_start; 58 wire A12A2_start; 59 wire A22A3_start; 60 wire A32A4_start; 61 wire A42A5_start; 62 wire A52A6_start; 63 wire A62A7_start; 64 wire A72A0_start; 65 66 wire [32-1:0] data; 67 reg [14-1:0] dout; 68 reg [4-1: 0] dac_address; 69 70 reg [3-1 :0] cnt0;//用来计数SCLK 71 reg [6-1 :0] cnt1; //用来计数字节个数 72 reg [22-1:0] cnt2; //用来延时,An到An+1的间隔时间 73 reg [3-1 :0] state_c; 74 reg [3-1 :0] state_n; 75 76 always @(posedge clk or negedge rst_n)begin 77 if(!rst_n)begin 78 cnt0 <= 0; 79 end 80 else if(add_cnt0)begin 81 if(end_cnt0)begin 82 cnt0 <= 0; 83 end 84 else begin 85 cnt0 <= cnt0 + 1; 86 end 87 end 88 end 89 90 assign add_cnt0 = flag_add; 91 assign end_cnt0 = add_cnt0 && cnt0 == 4 - 1; 92 93 94 always @(posedge clk or negedge rst_n)begin 95 if(!rst_n)begin 96 cnt1 <= 0; 97 end 98 else if(add_cnt1)begin 99 if(end_cnt1)begin 100 cnt1 <= 0; 101 end 102 else begin 103 cnt1 <= cnt1 + 1; 104 end 105 end 106 end 107 108 assign add_cnt1 = end_cnt0; 109 assign end_cnt1 = add_cnt1 && cnt1 == 33-1; 110 111 112 //增加一个信号,用来区分哪段是延时50ms技术,哪段时间是发产生sclk并发送数据 113 always @(posedge clk or negedge rst_n)begin 114 if(!rst_n)begin 115 flag_add <= 1; 116 end 117 else if(end_cnt1)begin 118 flag_add <= 0; 119 end 120 else if(end_cnt2)begin //An到An+延迟时间结束之后,再次启动 121 flag_add <= 1; 122 end 123 end 124 125 always @(posedge clk or negedge rst_n)begin 126 if(!rst_n)begin 127 cnt2 <= 0; 128 end 129 else if(add_cnt2)begin 130 if(end_cnt2)begin 131 cnt2 <= 0; 132 end 133 else begin 134 cnt2 <= cnt2 + 1; 135 end 136 end 137 end 138 139 assign add_cnt2 = flag_add == 0; 140 assign end_cnt2 = add_cnt2 && cnt2 == DLY_50MS - 1; 141 142 always @(posedge clk or negedge rst_n)begin 143 if(!rst_n)begin 144 sclk <= 1; 145 end 146 else if(add_cnt0 && cnt0 == 2 - 1)begin 147 sclk <= 0; 148 end 149 else if(end_cnt0)begin 150 sclk <= 1; 151 end 152 end 153 154 always @(posedge clk or negedge rst_n)begin 155 if(!rst_n)begin 156 sync_n <= 1; 157 end 158 else if(add_cnt0 && cnt0 == 3-1 && cnt1 == 0)begin 159 sync_n <= 0; 160 end 161 else if(end_cnt0 && cnt1 == 33-1)begin 162 sync_n <= 1; 163 end 164 end 165 166 //第一段,状态跳转 167 always @(posedge clk or negedge rst_n)begin 168 if(!rst_n)begin 169 state_c <= A0; 170 end 171 else begin 172 state_c <= state_n; 173 end 174 end 175 176 //第二段,组合逻辑,罗列出所有跳转条件 177 always @(*)begin 178 case(state_c) 179 180 A0:begin 181 if(A02A1_start)begin 182 state_n = A1; 183 end 184 else begin 185 state_n = state_c; 186 end 187 end 188 189 A1:begin 190 if(A12A2_start)begin 191 state_n = A2; 192 end 193 else begin 194 state_n = state_c; 195 end 196 end 197 198 A2:begin 199 if(A22A3_start)begin 200 state_n = A3; 201 end 202 else begin 203 state_n = state_c; 204 end 205 end 206 207 A3:begin 208 if(A32A4_start)begin 209 state_n = A4; 210 end 211 else begin 212 state_n = state_c; 213 end 214 end 215 216 A4:begin 217 if(A42A5_start)begin 218 state_n = A5; 219 end 220 else begin 221 state_n = state_c; 222 end 223 end 224 225 A5:begin 226 if(A52A6_start)begin 227 state_n = A6; 228 end 229 else begin 230 state_n = state_c; 231 end 232 end 233 234 A6:begin 235 if(A62A7_start)begin 236 state_n = A7; 237 end 238 else begin 239 state_n = state_c; 240 end 241 end 242 243 A7:begin 244 if(A72A0_start)begin 245 state_n = A0; 246 end 247 else begin 248 state_n = state_c; 249 end 250 end 251 252 default: begin 253 state_n = A0; 254 end 255 endcase 256 end 257 258 259 //第三段,设计条件转移 260 assign A02A1_start = state_c == A0 && end_cnt2; 261 assign A12A2_start = state_c == A1 && end_cnt2; 262 assign A22A3_start = state_c == A2 && end_cnt2; 263 assign A32A4_start = state_c == A3 && end_cnt2; 264 assign A42A5_start = state_c == A4 && end_cnt2; 265 assign A52A6_start = state_c == A5 && end_cnt2; 266 assign A62A7_start = state_c == A6 && end_cnt2; 267 assign A72A0_start = state_c == A7 && end_cnt2; 268 269 //第四段, 产生输出 270 always @(posedge clk or negedge rst_n)begin 271 if(!rst_n)begin 272 din <= 1; 273 end 274 else if(end_cnt0 && cnt1 >= 0 && cnt1 < 32)begin //在SCLK的上升沿发送数据 275 din <= data[31-cnt1]; 276 end 277 end 278 279 assign data = {1'b0, 3'b000, CONTROL, dac_address, dout, 2'b00, FEATURE}; 280 281 //通道地址 , 及每个通道的数据赋值 282 always @(*)begin 283 if(state_c == A0)begin 284 dac_address = A0; 285 dout = 1000; //0.307V 286 end 287 else if(state_c == A1)begin 288 dac_address = A1; 289 dout = 2000; //0.611V 290 end 291 else if(state_c == A2)begin 292 dac_address = A2; 293 dout = 3000; //0.916V 294 end 295 else if(state_c == A3)begin 296 dac_address = A3; 297 dout = 4000; //1.221V 298 end 299 else if(state_c == A4)begin 300 dac_address = A4; 301 dout = 5000; //1.526V 302 end 303 else if(state_c == A5)begin 304 dac_address = A5; 305 dout = 6000; //1.831V 306 end 307 else if(state_c == A6)begin 308 dac_address = A6; 309 dout = 7000; //2.136V 310 end 311 else begin 312 dac_address = A7; 313 dout = 8000; //2.441V 314 end 315 end 316 317 endmodule
测试代码:
`timescale 1us/100ns module dac8168_sim(); reg clk ; reg rst_n ; wire ldac_n ; wire clr_n ; wire sclk ; wire sync_n ; wire din ; parameter CLK_CYCLE = 20; initial begin clk = 0; #CLK_CYCLE; forever #(CLK_CYCLE/2) clk = ~clk; end initial begin rst_n = 0; #(CLK_CYCLE*200); rst_n = 1; end dac8168 u1( .clk ( clk ), .rst_n ( rst_n ), .ldac_n ( ldac_n ), .clr_n ( clr_n ), .sclk ( sclk ), .sync_n ( sync_n ), .din ( din ) ); endmodule
仿真波形:
下图中的数据格式:
assign data = {1'b0, 3'b000, CONTROL, dac_address, dout, 2'b00, FEATURE};
parameter CONTROL = 4'b0010;
dac_address = 4‘b0001;
dout = 2000
parameter FEATURE = 4'b0101;
以上是脚本宝典为你收集整理的状态机练习-基于DAC8168C DAC电压输出全部内容,希望文章能够帮你解决状态机练习-基于DAC8168C DAC电压输出所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。