实验名称:使用状态机实现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 counter 设计按键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转换输出模拟电压,而方波的实现只用给个最大与最小转换值即可,在程序中设置高低电平的时间。 因篇幅问题不能全部显示,请点此查看更多更全内容