--文件名:reciever.vhd.
--功能:UART接受器
--系统由五个状态(r_start,r_center,r_wait,r_sample,r_stop)和两个进程构成
LIBRARY IEEE; --调用库
USE IEEE.STD_LOGIC_1164.ALL; --调用库中的程序包
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY receiver IS
GENERIC(framlenr:INTEGER:=8); --传送的数据位为8位,规定数据位为8位
PORT( bclkr : IN STD_LOGIC; --时钟输入端口
resetr : IN STD_LOGIC; --复位信号端口
rxdr : IN STD_LOGIC ; --数据输入端口
r_ready : OUT STD_LOGIC; --每发送完一帧数据,出现一个结束时钟脉冲
rbuf : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); --定义输入输出信号
END ENTITY receiver;
ARCHITECTURE Behavioral OF receiver IS
TYPE states IS (r_start,r_center,r_wait,r_sample,r_stop);--定义各子状态
SIGNAL state:states:=r_start;
SIGNAL rxd_sync:STD_LOGIC; -- rxd_sync内部信号,接受rxd输入
BEGIN
pro1:PROCESS(rxdr)
BEGIN
IF rxdr='0' THEN
rxd_sync<='0';
ELSE rxd_sync<='1';
END IF; --利用同步信号检测起始位是否到来
END PROCESS;
pro2:PROCESS(bclkr,resetr,rxd_sync) --主控时序、组合进程
VARIABLE count:STD_LOGIC_VECTOR(3 DOWNTO 0); --定义中间变量
VARIABLE rcnt: INTEGER:=0; -- rcnt为接收的数据位数计数
VARIABLE rbufs:STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
IF resetr='1' THEN --高电平复位
state<=r_start; count:="0000"; --复位
ELSIF RISING_EDGE(bclkr) THEN --波特率信号的上升沿
--状态机
CASE state IS
WHEN r_start=> --状态1,等待起始位
IF rxd_sync='0' THEN
state<=r_center;
r_ready<='0'; --低电平有效起始位
rcnt:=0;
ELSE
state<=r_start; r_ready<='0';
END IF;
WHEN r_center=> --状态2,求出每位的中点
IF rxd_sync='0' THEN --每个数据位被分为16等分,中点为8
IF count="0100" THEN
state<=r_wait; count:="0000";
ELSE count:=count+1; state<=r_center;
END IF;
ELSE state<=r_start;
END IF;
WHEN r_wait=> --状态3,等待状态
IF count>="1110" THEN
IF rcnt=framlenr THEN
state<=r_stop; -- rcnt=framlenr表示数据接收够8位
ELSE state<=r_sample;
END IF;
count:="0000";
ELSE count:=count+1; state<=r_wait;
END IF;
WHEN r_sample=>rbufs(rcnt):=rxd_sync; --状态4,数据位采样检测
rcnt:=rcnt+1;
state<=r_wait;
WHEN r_stop=>r_ready<='1'; rbuf<=rbufs; --状态5,输出帧接收完毕信号
state<=r_start;
WHEN others=>state<=r_start;
END CASE;
END IF;
END PROCESS;
END Behavioral;
[code]--文件名:transfer.vhd
--功能:UART发送器
--说明:系统由五个状态(x_idle,x_start,x_wait,x_shift,x_stop)和一个进程构成。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY transfer IS
GENERIC(framlent:INTEGER:=8); --类属说明
PORT (bclkt : IN STD_LOGIC; --定义输入时钟信号
resett : IN STD_LOGIC; --定义输入复位信号
xmit_cmd_p: IN STD_LOGIC; --发送控制信号,开始时刻设置一段高电平
txdbuf : IN STD_LOGIC_VECTOR(7 DOWNTO 0); --为要发送的八位数据
txd : OUT STD_LOGIC; --为发送器发出的串行信号
txd_done : OUT STD_LOGIC); --定义发送结束信号,高电平有效
END transfer;
ARCHITECTURE Behavioral OF transfer IS
TYPE states IS (x_idle,x_start,x_wait,x_shIFt,x_sTOp); --定义5个子状态
SIGNAL state:states:=x_idle;
SIGNAL tcnt:INTEGER:=0;
BEGIN
PROCESS(bclkt,resett,xmit_cmd_p,txdbuf) --主控时序进程
VARIABLE xcnt16:STD_LOGIC_VECTOR(4 DOWNTO 0):="00000"; --定义中间变量
VARIABLE xbitcnt:INTEGER:=0;
VARIABLE txds:STD_LOGIC;
BEGIN
IF resett='1' THEN
state<=x_idle; --复位,txd输出保持1
txd_done<='0';
txds:='1';
ELSIF RISING_EDGE(bclkt) THEN
CASE state IS
WHEN x_idle=> --状态1,等待数据帧发送命令
IF xmit_cmd_p='1' THEN
state<=x_start;txd_done<='0';
ELSE state<=x_idle;
END IF;
WHEN x_start=> --状态2,发送信号至起始位
IF xcnt16="01111" THEN
state<=x_shIFt;
xcnt16:="00000";
ELSE
xcnt16:=xcnt16+1;
txds:='0';
state<=x_start; --输出开始位,'0'
END IF;
WHEN x_wait=> --状态3,等待状态
IF xcnt16>="01110" THEN
IF xbitcnt=framlent THEN
state<=x_sTOp;
xbitcnt:=0;
xcnt16:="00000";
ELSE state<=x_shIFt;
END IF;
xcnt16:="00000";
ELSE
xcnt16:=xcnt16+1;
state<=x_wait;
END IF;
WHEN x_shIFt=> --状态4,将待发数据进行并串转换
txds:=txdbuf(xbitcnt);
xbitcnt:=xbitcnt+1;
state<=x_wait;
WHEN x_sTOp=> --状态5,停止位发送状态
IF xcnt16>="01111" THEN
IF xmit_cmd_p='0' THEN
state<=x_idle;--高电平保持时间应低于一个帧发送的时间
xcnt16:="00000";
ELSE xcnt16:=xcnt16; state<=x_sTOp;
END IF;
txd_done<='1';
ELSE
xcnt16:=xcnt16+1;
txds:='1';
state<=x_sTOp;
END IF;
WHEN OTHERs=>
state<=x_idle;
END CASE;
END IF;
txd<=txds;
END PROCESS;
END Behavioral;
[code]--文件名:uart_baud.vhd.
--功能:本实验想要实现的波特率为:9600,cyclone ii开发板提供说的时钟频率为:50MHz
--波特率发生器的分频数计算如下式:
--50000000/(16*9600)=325;占空比非50%
LIBRARY IEEE;--调用库函数
USE IEEE.STD_LOGIC_1164.ALL;--调用库函数的程序包
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY uart_baud IS
GENERIC(framlenr:INTEGER:=325); --利用类属说明定义分频系数,
PORT (clk,reset:IN STD_LOGIC;--定义时钟,复位端口
bclk :OUT STD_LOGIC);--定义输出时钟端口
END ENTITY uart_baud;
ARCHITECTURE Behavioral OF uart_baud IS
SIGNAL cnt:INTEGER RANGE 0 TO 325;
BEGIN
PROCESS(clk,reset)
BEGIN
IF reset='1' THEN
cnt<=0; bclk<='0'; --高电平复位
ELSIF RISING_EDGE(clk) THEN
IF cnt<162 THEN
cnt<=cnt+1; bclk<='1';
ELSIF cnt<framlenr-1 THEN --记数从零开始,减一要
cnt<=cnt+1; bclk<='0';
ELSE cnt<=0;
END IF;
END IF;
END PROCESS;
END Behavioral;
[code]LIBRARY IEEE;[code]--文件名:clock_div.vhd.
--功能:实验开发板晶振频率为:50MHZ,经过分频后得到5Hz脉冲频率
--分频数计算:50000000/5 = 10000000
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY clock_div IS
GENERIC(framlenr:INTEGER:=10000000);
PORT ( clk:IN STD_LOGIC;
resetb:IN STD_LOGIC;
bclk:INOUT STD_LOGIC);
END clock_div;
ARCHITECTURE Behavioral OF clock_div IS
BEGIN
PROCESS(clk,resetb)
VARIABLE cnt:INTEGER;
BEGIN
IF resetb='1' THEN
cnt:=0; bclk<='0';
ELSIF RISING_EDGE(clk) THEN
IF cnt>=framlenr THEN
cnt:=0; bclk<='0';
ELSIF cnt>=framlenr/2 THEN
cnt:=cnt+1;bclk<='1';
ELSE cnt:=cnt+1; bclk<='0';
END IF;
END IF;
END PROCESS;
END Behavioral;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY decoder_8_8 IS
PORT (
a : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END decoder_8_8;
ARCHITECTURE Behavioral OF decoder_8_8 IS
BEGIN
PROCESS(a)
BEGIN
CASE a IS
WHEN x"00" => q <= "11000000";
WHEN x"01" => q <= "11111001";
WHEN x"02" => q <= "10100100";
WHEN x"03" => q <= "10110000";
WHEN x"04" => q <= "10011001";
WHEN x"05" => q <= "10010010";
WHEN x"06" => q <= "10000010";
WHEN x"07" => q <= "11111000";
WHEN x"08" => q <= "10000000";
WHEN x"09" => q <= "10010000";
WHEN x"0a" => q <= "10001000";
WHEN x"0b" => q <= "10000011";
WHEN x"0c" => q <= "11000110";
WHEN x"0d" => q <= "10100001";
WHEN x"0e" => q <= "10000110";
WHEN x"0f" => q <= "10001110";
WHEN others => q <= "11111111";
END CASE;
END PROCESS;
END Behavioral;
[/code][/code][/code][/code]
这段代码能够实现功能吗,不能改怎么改呢,我调试了好久,还是不行 |