您的当前位置:首页正文

FPGA实验报告3

2020-07-05 来源:步旅网


实验名称:使用状态机实现DAC芯片TLC5620的控制

姓名: 刘思波 班级: 信息与通信工程(电子)学号: 3120304012 成绩: 一、实验目的

1. 学习状态机的设计方法并进行调试。

2. 熟悉并实现CPLD/FPGA的对DAC芯片的控制 二、实验内容

1. 学习“用状态机实现TLC5620的控制”实验程序,并下载到硬件完成该实验

给定的要求。

2. 通过QUARTUS完成实验仿真。 3. 修改程序完成以下功能:

1)在四个DAC通道内,分别实现锯齿波,三角波、方波的输出; 2) 实现波形输出频率可由按键设置;使频率显示在数码管上; 三、实验结果

图1 整体多波形信号发生器RTL图

3、1关键程序及说明

输出电压数码管显示

PROCESS(clock) BEGIN

IF RISING_EDGE(clock) THEN IF div_clk='1' THEN

CASE cnt IS --

WHEN \"00\"=> disp_dat<=(\"00\" & wr_data_r(10 9))+1;--disp_dat<=

WHEN \"01\"=> disp_dat<=wr_data_r(7 DOWNTO 4);-- WHEN \"10\"=> disp_dat<=wr_data_r(3 DOWNTO 0); WHEN \"11\"=> disp_dat<=\"000\" & wr_data_r(8); END CASE;

CASE cnt IS

WHEN \"00\"=> dig_r<= \"01111111\"; WHEN \"01\"=> dig_r<= \"11011111\"; WHEN \"10\"=> dig_r<= \"11101111\"; WHEN \"11\"=> dig_r<= \"11111110\"; END CASE; END IF; END IF; END PROCESS;

PROCESS(disp_dat) BEGIN

CASE disp_dat IS

WHEN X\"0\"=> seg_r<=X\"c0\";--??0 WHEN X\"1\"=> seg_r<=X\"f9\";--??1 WHEN X\"2\"=> seg_r<=X\"a4\";--??2 WHEN X\"3\"=> seg_r<=X\"b0\";--??3 WHEN X\"4\"=> seg_r<=X\"99\";--??4 WHEN X\"5\"=> seg_r<=X\"92\";--??5 WHEN X\"6\"=> seg_r<=X\"82\";--??6 WHEN X\"7\"=> seg_r<=X\"f8\";--??7 WHEN X\"8\"=> seg_r<=X\"80\";--??8 WHEN X\"9\"=> seg_r<=X\"90\";--??9 WHEN X\"a\"=> seg_r<=X\"88\";--??a WHEN X\"b\"=> seg_r<=X\"83\";--??b WHEN X\"c\"=> seg_r<=X\"c6\";--??c WHEN X\"d\"=> seg_r<=X\"a1\";--??d WHEN X\"e\"=> seg_r<=X\"86\";--??e

DOWNTO WHEN X\"f\"=> seg_r<=X\"8e\";--??f WHEN OTHERS=> seg_r<=X\"FF\"; END CASE; END PROCESS;

wr_data<=wr_data_r; wr_act<=wr_act_r; seg<=seg_r; dig<=dig_r; END;

状态机程序

ARCHITECTURE one OF dac IS

SIGNAL counter: STD_LOGIC_VECTOR(CLK_DIV_BITS-1 DOWNTO 0); SIGNAL dac_clk_r: STD_LOGIC; SIGNAL dac_data_r: STD_LOGIC; SIGNAL dac_load_r: STD_LOGIC;

SIGNAL bit_counter: STD_LOGIC_VECTOR(4 DOWNTO 0);--DAC SIGNAL div_clk: STD_LOGIC;-- SIGNAL bit_counter_rst:STD_LOGIC;-- SIGNAL dac_dat_send_finish: STD_LOGIC;

TYPE states IS (dac_idle,dac_send,dac_store);-- SIGNAL dac_sta,dac_sta_next: states; BEGIN

PROCESS(clock,rst) BEGIN

IF RISING_EDGE(clock) THEN IF rst='1' THEN

counter<=\"000000\"; ELSE

IF countercounter<=\"000000\"; div_clk<='1'; END IF; END IF; END IF; END PROCESS; 3、2结果及分析

设计按键KEY1-KEY4调节DA输入电压值,按键KEY5按下时启动DA转换 2-1方波的实现

产生方波,是通过交替送出全0和全1实现,每32个时钟翻转一次。其VHDL代码如下: library ieee;

use ieee.std_logic_1164.all; entity square is

port(clk,clr:in std_logic;

q:out integer range 0 to 255); end square;

architecture one of square is signal a:bit; begin

process(clk,clr)

variable cnt:integer; begin

if clr='0' then a<='0';

elsif clk'event and clk='1' then if cnt<31 then cnt:=cnt+1; else

cnt:=0; a<=not a; end if; end if; end process; process(clk,a) begin

if clk'event and clk='1' then if a='1' then

q<=255; else q<=0; end if; end if;

end process; end one;

2-2 三角波的实现

该模块产生的三角波以64个时钟为一个周期,输出q每次加减8。其VHDL代码如下: library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all; entity delta is

port(clk,reset:in std_logic;

q:out std_logic_vector(7 downto 0)); end delta;

architecture delta_arc of delta is begin

process(clk,reset)

variable tmp:std_logic_vector(7 downto 0); variable a:std_logic; begin

if reset='0' then tmp:=\"00000000\";

elsif clk'event and clk='1' then if a='0' then

if tmp=\"11111000\" then tmp:=\"11111111\"; a:='1'; else

tmp:=tmp+8; end if; else

if tmp=\"00000111\" then tmp:=\"00000000\"; a:='0'; else

tmp:=tmp-8; end if; end if; end if; q<=tmp; end process;

end delta_arc; 2-3正弦波的实现

该模块产生以64个时钟为一个周期的正弦波。其VHDL代码如下: library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all; entity sin is

port(clk,clr:in std_logic;

d:out integer range 0 to 255); end sin;

architecture sin_arc of sin is begin

process(clk,clr)

variable tmp:integer range 0 to 63; begin

if clr='0' then d<=0;

elsif clk'event and clk='1' then if tmp=63 then tmp:=0; else

tmp:=tmp+1; end if;

case tmp is

when 00=>d<=255; when 01=>d<=254; when 02=>d<=252; when 03=>d<=249; when 04=>d<=245; when 05=>d<=239; when 06=>d<=233; when 07=>d<=225; when 08=>d<=217; when 09=>d<=207; when 10=>d<=197; when 11=>d<=186; when 12=>d<=174; when 13=>d<=162; when 14=>d<=150; when 15=>d<=137; when 16=>d<=124; when 17=>d<=112; when 18=>d<=99; when 19=>d<=87; when 20=>d<=75; when 21=>d<=64; when 22=>d<=53; when 23=>d<=43; when 24=>d<=34; when 25=>d<=26; when 26=>d<=19; when 27=>d<=13; when 28=>d<=8; when 29=>d<=4; when 30=>d<=1; when 31=>d<=0; when 32=>d<=0; when 33=>d<=1; when 34=>d<=4; when 35=>d<=8; when 36=>d<=13; when 37=>d<=19; when 38=>d<=26; when 39=>d<=34; when 40=>d<=43; when 41=>d<=53; when 42=>d<=64; when 43=>d<=75; when 44=>d<=87; when 45=>d<=99; when 46=>d<=112; when 47=>d<=124; when 48=>d<=137; when 49=>d<=150; when 50=>d<=162; when 51=>d<=174; when 52=>d<=186; when 53=>d<=197; when 54=>d<=207; when 55=>d<=217; when 56=>d<=225; when 57=>d<=233; when 58=>d<=239; when 59=>d<=245; when 60=>d<=249; when 61=>d<=252; when 62=>d<=254;

when 63=>d<=255; when others=>null; end case; end if; end process; 2-4锯齿波的实现

改变该模块递增的常数,可以改变锯齿的个数。其VHDL代码如下: library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all; entity ladder is

port(clk,reset:in std_logic;

q:out std_logic_vector(7 downto 0)); end ladder;

architecture ladder_arc of ladder is begin

process(clk,reset)

variable tmp:std_logic_vector(7 downto 0); variable a:std_logic; begin

if reset='0' then tmp:=\"00000000\";

elsif clk'event and clk='1' then if a='0' then

if tmp=\"11111111\" then

tmp:=\"00000000\"; a:='1';

else tmp:=tmp+16; --锯齿常数为16,可修改 a:='1'; end if; else

a:='0'; --循环计数 end if; end if; q<=tmp; end process;

end ladder_arc[5];

2.1 结果及分析

图3 方波仿真图

图4 方波元器件生成图

图5 三角波仿真图

图6 三角波元器件生成图

图7

正弦波仿真图

图8 正弦波元器件生成图

其仿真波形如图9所示:

图9 锯齿波仿真图

其生成元器件如图10所示:

图10 锯齿波元器件生成图

3、实验总结与问题

本次试验算是对前两次实验的一次综合,通过这次课程设计,我全面熟悉、掌握VHDL语言的基本知识,掌握利用VHDL语言对信号发生器的编程和时序逻辑电路编程,把编程和实际结合起来,熟悉编制和调试程序的技巧,掌握分析结果的若干有效方法, 8位DAC芯片TLC5620,芯片操作程序为11位的命令字包括8位数据位,2位DAC选择位和1位范围位,后者用来选择输出范围是1倍还是2倍。锯齿波、三角波的实现,为一个计数器进行一个循环的累加计数,然后给计数器赋予TLC5620转换输出模拟电压,而方波的实现只用给个最大与最小转换值即可,在程序中设置高低电平的时间。

因篇幅问题不能全部显示,请点此查看更多更全内容