duty_cycle <= duty_cycle_io;
PROCESS(clock_48M) BEGIN
IF RISING_EDGE(clock_48m) THEN
IF count<120000 THEN
count<=count+1; clk<='0';
count<=B\clk<='1';
ELSE
END IF;
END IF;
-------------------------------------------<<按键消抖部分
END PROCESS; PROCESS (clock_48m) BEGIN
PROCESS (clock_48M) BEGIN
IF RISING_EDGE(clock_48M) THEN
k_debounce<=dout1 OR dout2 OR dout3;--按键消抖输出. END IF;
IF RISING_EDGE(clock_48M) THEN
IF clk='1' THEN
dout1<=key; dout2<=dout1; dout3<=dout2;
END IF;
END IF;
END PROCESS;
END PROCESS;
key_edge<=NOT (dout1 OR dout2 OR dout3) AND k_debounce;
PROCESS(clock_48M)--按键1 控制电动机速度 BEGIN
PROCESS(clock_48M)--按键2,控制电动机启动、停止
IF RISING_EDGE(clock_48M) THEN
IF key_edge(0)='1' THEN
duty_cycle_io<=duty_cycle_io+1; END IF;
END IF;
END PROCESS;
26
BEGIN
PROCESS(clock_48M)--按键3,控制电动机正/反转 IF RISING_EDGE(clock_48M) THEN
IF key_edge(1)='1' THEN
pwm_en_io<=NOT pwm_en_io; END IF;
END IF;
END PROCESS;
BEGIN IF RISING_EDGE(clock_48M) THEN IF key_edge(2)='1' THEN
moto_dir <=NOT moto_dir;
END IF;
END IF;
END PROCESS;
motoa<=pwm_in WHEN moto_dir='1' ELSE '0'; motob<='0' WHEN moto_dir='1' ELSE pwm_in; END;
27
实验 用状态机实现对TLC549的采样控制(A/D实验)
1. 实验目的
熟悉串行模/数转换芯片TLC549的使用方法,掌握利用有限状态机实现一般的时序逻辑分析的方法,了解一般状态机的设计与应用。
2. 实验内容
本实验的内容是利用状态机实现对TLC549的采样控制,制作一个简易电压表。在实验箱上进行硬件测试。实验时利用调节电位器RW1改变ADC的模拟输入值,数据采样读取后由数码管LEDD3显示。最后用万用表测量输入电压,并与读到的数据做比较。 3. 实验原理
TLC549是一个8位的串行模/数转换器,A/D转换时间最大17us,I/O时钟频率可达1.1MHz。如下图为TLC549的访问时序,从图中可以看出当CS拉低时,ADC前一次的转换数据(A) 的最高位A7立即出现在数据线DATA OUT上,之后的数据在时钟I/O CLOCK的下降沿改变,可在I/O CLOCK的上升沿读数据。读完8位数据后,ADC开始转换这一次的采样信号(B),以便在下一次读取。转换时,片选信号CS要置高电平。设计操作时序要注意Tsu(CS)、Tconv、I/O CLOCK的频率等几个参数。Tsu(CS) 为CS拉低到I/O CLOCK第一个时钟到来时间,至少要1.4us;Tconv为ADC的转换时钟,不超过1.7us;I/O CLOCK不能超过1.1MHz。其他参数参考数据手册。
图 TLC549访问时序
由于ADC是8位的,所以采样的电压值为
V?D256?VREF
VREF为参考电压值,其中V为采样值;D为ADC转换后读取的8位二进制数,这里是2.5V。
4. 实验步骤
(1) 启动Quartus II,建立一个空白工程,然后命名为tlc549.qpf。
(2) 新建adc.vhd源程序文件,源代码如下。然后进行综合编译。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。生产符号文件adc.bsf (File→ Create/_Update → Create Symbol Files for Current File)。 程序参考
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_Arith.ALL;
28
USE IEEE.STD_LOGIC_Unsigned.ALL; ENTITY adc IS GENERIC( CLK_DIV_BITS: ); PORT( clock: reset: enable: sdat_in: adc_clk: cs_n:
IN IN
IN IN
STD_LOGIC;--系统时钟 STD_LOGIC;--转换使能 STD_LOGIC;--复位,高电平有效 STD_LOGIC;--TLC549串行数据输入
Integer:=5;
CLK_DIV_VALUE: Integer:=31
OUT STD_LOGIC;--TLC549 I/O时钟 OUT STD_LOGIC;--TLC549 片选控制
data_ready:OUT STD_LOGIC;--指示有新的数据输出
data_out: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)--AD转换数据输出 ); END;
ARCHITECTURE one OF adc IS SIGNAL adc_clk_r: SIGNAL cs_n_r:
STD_LOGIC; STD_LOGIC;
SIGNAL data_ready_r:STD_LOGIC;
SIGNAL data_out_r: STD_LOGIC_VECTOR(7 DOWNTO 0);--AD转换数据输出. SIGNAL sdat_in_r: SIGNAL q:
SIGNAL bit_count: SIGNAL div_clk: SIGNAL clk_count: SIGNAL buf1,buf2: SIGNAL rec_done:
STD_LOGIC;--数据输出锁存
STD_LOGIC_VECTOR(7 DOWNTO 0);--移位寄存器,用于接收或发送数据 STD_LOGIC_VECTOR(5 DOWNTO 0);--移位计数器
STD_LOGIC;
SIGNAL bit_count_rst:STD_LOGIC;--ADC时钟计数全能控制.
STD_LOGIC_VECTOR(CLK_DIV_BITS-1 DOWNTO 0);--时钟盼频计数器 STD_LOGIC;
STD_LOGIC;--数据读取完毕的标志
SIGNAL ready_done: STD_LOGIC;--cs_n拉低(大于1.4us)后的标志 SIGNAL conv_done: STD_LOGIC;--数据转换完毕的标志
TYPE states IS(idle,adc_ready,adc_receive,adc_conversion,adc_data_load); SIGNAL adc_state,adc_next_state:states; BEGIN
adc_clk<=adc_clk_r; cs_n<=cs_n_r; data_out<=data_out_r; data_ready<=data_ready_r; PROCESS (clock) BEGIN
IF RISING_EDGE(clock) THEN
sdat_in_r<=sdat_in; END IF;
29
END PROCESS;
-----------------------------------------<<时钟分频计数器 PROCESS (clock) BEGIN
IF RISING_EDGE(clock) THEN
IF reset='1' THEN
clk_count<=\IF clk_count<
CLK_DIV_VALUE THEN
ELSE
clk_count<=clk_count+1; div_clk<='0'; clk_count<=\div_clk<='1';
ELSE
END IF;
END IF;
END IF;
END PROCESS;
--------------------------------------------<<状态机ADC PROCESS (clock) BEGIN
IF RISING_EDGE(clock) THEN
IF reset='1' THEN
adc_state<=idle;
adc_state<=adc_next_state; ELSE END IF;
END IF;
END PROCESS;
--------------------------------------------<
cs_n_r<='0'; bit_count_rst<='0'; data_ready_r<='0'; CASE adc_state IS
WHEN idle=>
cs_n_r<='1'; bit_count_rst<='1'; IF
--复位移位计数器.
enable='1' THEN
adc_next_state<=adc_ready; adc_next_state<=idle;
--初始状态
ELSE END IF;
30