1.数模转换器即DAC,一般情况下由四个部分组成,权电阻网络,运算放大器,基准电源和模拟开关。是一种以二进制显示的数字量转换成以参考电压为基准的模拟量转换器。
2.设计原理:
TLC5620是一个拥有4路输出的数模转换器,时钟频率最高可以达到1MHZ,在本实例中它可以将输入的数字量转换为实际的模拟量(电压),并通过4个按键控制4路输出电压,每按一次,电压随之上升,同时数码管上依次显示相应的值:A1,A0,RNG,以及输入的数字量,采用开发板的基准电压2.5v。
芯片端口图:
点击此处添加图片说明文字
实际的电压公式是:V = REF*(CODE/256)*(1+RNG)
REF为基准电压,CODE为输入的8位数据,RNG为输入范围
3.key_test模块:按键控制通道选择
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74module key_test( input clk, input rst_n, input [3:0] key, //4个按键组合信号 output [10:0] wr_data, //输出一帧数据 output [19:0] out_data //输出数码管的显示数据 ); reg [30:0] cnt; //计数器分频 reg clk_r; //分频时钟:在消抖的时钟频率下进行按键检测 reg [7:0] data; //按键输入的数据 reg [1:0] channel; //通道选择 reg [7:0] key1,key2,key3,key4; //4个按键 always @(posedge clk or negedge rst_n) //按键消抖,每0.2s进行一次检测 begin if(!rst_n) begin cnt <= 0; clk_r <= 0; end else if(cnt < 30'd1000_0000) //系统时钟5M,要0.2检测一次,就用50000000/(1/0.2) cnt <= cnt + 1; else begin cnt <= 0; clk_r <= ~clk_r; end end always @(posedge clk_r or negedge rst_n) //按键低电平有效,当检测到相应的按键按下时, //相应数值加一,并显示相应的通道 begin if(!rst_n) begin data <= 0; channel <= 0; key1 <= 0; key2 <= 0; key3 <= 0; key4 <= 0; end else case(key) 4'b1110:begin //按键1:选择通道A,输入数字量加一 channel <= 2'b00; key1 <= key1 + 1'b1; data <= key1; end 4'b1101:begin //选择通道B,输入数字量加一 channel <= 2'b01; key2 <= key2 + 1'b1; data <= key2; end 4'b1011:begin //选择通道C,输入数字量加一 channel <= 2'b10; key3 <= key3 + 1'b1; data <= key3; end 4'b0111:begin //选择通道D,输入数字量加一 channel <= 2'b11; key4 <= key4 + 1'b1; data <= key4; end default : ; endcase end //用赋值语句将需要的数据组合起来,在此例中RNG默认为1 assign wr_data = {channel,1'b1,data}; assign out_data = {3'b000,channel[1],3'b000,channel[0],4'h1,data}; endmodule
4.TLC_DA模块:数模转换芯片的驱动程序
点击此处添加图片说明文字
点击此处添加图片说明文字
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85module TLC_DA( input clk, input rst_n, input [10:0] data_in, //输入一帧数据 output da_data, //串行数据接口 output da_clk, //串行时钟接口 output reg da_ladc, //更新控制信号 output reg da_load //串行加载控制接口 ); reg [30:0] cnt; wire da_clk_r; //TLC5620内部的时钟信号 //计时器时钟分频:根据芯片内部的时序要求进行分频 always @(posedge clk or negedge rst_n) //频率不大于1MHZ begin if(!rst_n) cnt <= 6'd0; else cnt <= cnt + 1'b1; end assign da_clk_r = cnt[5]; //接受时序的序列机 reg [2:0] state; reg [3:0] cnt_da; reg da_data_r; reg da_data_en; //限定da_data和da_clk的有效区域 always @(posedge da_clk_r or negedge rst_n) begin if(!rst_n) begin state <= 0; cnt_da <= 0; da_data_r <= 1'b1; da_data_en <= 0; da_load <= 1; da_ladc <= 0; end else case(state) 0:state <= 1; 1:begin da_data_en <= 1; da_load <= 1; if(cnt_da <= 10) begin cnt_da <= cnt_da + 1'b1; case(cnt_da) 0:da_data_r <= data_in[10]; 1:da_data_r <= data_in[9]; 2:da_data_r <= data_in[8]; 3:da_data_r <= data_in[7]; 4:da_data_r <= data_in[6]; 5:da_data_r <= data_in[5]; 6:da_data_r <= data_in[4]; 7:da_data_r <= data_in[3]; 8:da_data_r <= data_in[2]; 9:da_data_r <= data_in[1]; 10:da_data_r <= data_in[0]; endcase state <= 1; end else begin cnt_da <= 0; state <= 2; da_data_en <= 0; end end 2:begin da_load <= 0; state <= 3; end 3:begin da_load <= 1; state <= 0; end default : state <= 0; endcase end assign da_data = (da_data_en) ? da_data_r:1'b1; assign da_clk = (da_data_en) ? da_clk_r:1'b0; endmodule
5.seg_sum模块:数码管显示
处添加图片说明文字
点击此处添加图片说明文字
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51module seg_sum( input clk, input rst_n, input [19:0] data_in, //20位输入数据 output reg [7:0] seg, output reg [2:0] sel ); reg [3:0] num; //数码管的位数 always@(*) case(sel) 4:num = data_in[3:0]; //第5个数码管显示数据的低四位 3:num = data_in[7:4]; 2:num = data_in[11:8]; 1:num = data_in[15:12]; 0:num = data_in[19:16]; default:; endcase always @(*) case(num) 0:seg <= 8'hC0; 1:seg <= 8'hF9; 2:seg <= 8'hA4; 3:seg <= 8'hB0; 4:seg <= 8'h99; 5:seg <= 8'h92; 6:seg <= 8'h82; 7:seg <= 8'hF8; 0:seg <= 8'h80; 0:seg <= 8'h90; default:seg <= 8'hFF; endcase //计数器分频:用cnt在第10位的变化作为分频时钟 reg [23:0] cnt; always @(posedge clk or negedge rst_n) if(!rst_n) cnt <= 4'b0; else cnt <= cnt + 1'b1; //在分频时钟下,数码管的0~4位依次循环 always @(posedge cnt[10] or negedge rst_n) //分频时钟为2的10次方除以50M if(!rst_n) sel <= 0; else if(sel < 4) sel <= sel + 1'b1; else sel <= 0; endmodule
6.顶层文件:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46module top( input clk, input rst_n, input [3:0] key, output da_data, //串行数据接口 output da_clk, //串行时钟接口 output da_ladc, //更新控制信号 output da_load, //串行加载控制接口 output [7:0] seg, output [2:0] sel ); //内部信号 wire [10:0] wr_data; //输出一帧数据 wire [19:0] out_data; //输出数码管的显示数据 //实例化 TLC_DA TLC_DA( .clk(clk), .rst_n(rst_n), .da_data(da_data), .da_clk(da_clk), .da_ladc(da_ladc), .da_load(da_load), .data_in(wr_data) ); key_test key_test( .clk(clk), .rst_n(rst_n), .key(key), .out_data(out_data), .wr_data(wr_data) ); seg_sum seg_sum( .clk(clk), .rst_n(rst_n), .data_in(out_data), .sel(sel), .seg(seg) ); endmodule
7.仿真测试文件
点击此处添加图片说明文字
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56`timescale 1 ns/ 1 ps module TLC_DA_tb(); parameter T = 20; /********************系统输入**********************/ reg clk; reg rst_n; reg [3:0] key; /*********************系统输出*****************/ wire da_data; wire da_clk; wire da_ladc; wire da_load; initial begin clk = 1'b0; rst_n = 1'b0; key = 4'b1111; #1000.1 rst_n = 1'b1; #100 key = 4'b1110; $stop; end always #(T/2) clk = ~clk; TLC_DA TLC_DA( .clk(clk), .rst_n(rst_n), .da_data(da_data), .da_clk(da_clk), .da_ladc(da_ladc), .da_load(da_load), .data_in(wr_data) ); key_test key_test( .clk(clk), .rst_n(rst_n), .key(key), .out_data(out_data), .wr_data(wr_data) ); seg_sum seg_sum( .clk(clk), .rst_n(rst_n), .data_in(out_data), .sel(sel), .seg(seg) ); endmodule
8.RTL图
点击此处添加图片说明文字
工程文件上传至qq群:868412045
最后
以上就是沉静路灯最近收集整理的关于FPGA学习之数模转换(TLC5620)(通过4个按键输入,输出数模转换需要的数据和数码管显示需要的数据)的全部内容,更多相关FPGA学习之数模转换(TLC5620)(通过4个按键输入,输出数模转换需要内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复