程序实现了一个收发一帧10个Bit(即无奇偶校验位)的串口控制器,10个Bit是1位起始位,8个数据位,1个结束位。串口的波特律由程序中定义的Div_par参数决定,更改该参数可以实现相应的波特率。程序当前设定的Div_par 的值是0x104,对应的波特率是9600。用一个8倍波特率的时钟将发送或接受每一位Bit的周期时间划分为8个时隙以使通信同步.程序的工作过程是:串口处于全双工工作状态,按动Key2,CPLD向PC发送皐Elcome"字符串(串口调试工具设成按ASCII码接受方式);PC可随时向CPLD发送0-F的十六进制数据,CPLD接受后显示在7段数码管上。
Library IEEE;
Use IEEE.STD_LOGIC_1164.ALL;
Use IEEE.STD_LOGIC_ARITH.ALL;
Use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY UART IS
PORT (
Clk : IN Std_logic;
Rst : IN Std_logic;
Rxd : IN Std_logic; 串行数据接收端
Txd : OUT Std_logic; 串行数据发送端
En : OUT Std_logic_vector(7 Downto 0); 数码管使能
Seg_data : OUT Std_logic_vector(7 DOWNTO 0); 数码管数据
Key_input : IN Std_logic 按键输入
);
END UART;
ARCHITECTURE Arch OF UART IS
//////////////////Inner Reg////////////////////
SIGNAL Div_reg : Std_logic_vector(15 DOWNTO 0);分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟
SIGNAL Div8_tras_reg : Std_logic_vector(2 DOWNTO 0);该寄存器的计数值对应发送时当前位于的时隙数
SIGNAL Div8_rec_reg : Std_logic_vector(2 DOWNTO 0); 寄存器的计数值对应接收时当前位于的时隙数
SIGNAL State_tras : Std_logic_vector(3 DOWNTO 0); 发送状态寄存器
SIGNAL State_rec : Std_logic_vector(3 DOWNTO 0); 接受状态寄存器
SIGNAL Clkbaud_tras : Std_logic; 以波特率为频率的发送使能信号
SIGNAL Clkbaud_rec : Std_logic; 以波特率为频率的接受使能信号
SIGNAL Clkbaud8x : Std_logic; 以8倍波特率为频率的时钟,它的作用是将发送或接受一个Bit的时钟周期分为8个时隙
SIGNAL Recstart : Std_logic; 开始发送标志
SIGNAL Recstart_tmp : Std_logic; 开始接受标志
SIGNAL Trasstart : Std_logic;
SIGNAL Rxd_reg1 : Std_logic; 接收寄存器1
SIGNAL Rxd_reg2 : Std_logic; 接收寄存器2,因为接收数据为异步信号,故用两级缓存
SIGNAL Txd_reg : Std_logic; 发送寄存器
SIGNAL Rxd_buf : Std_logic_vector(7 DOWNTO 0);接受数据缓存
SIGNAL Txd_buf : Std_logic_vector(7 DOWNTO 0);发送数据缓存
SIGNAL Send_state : Std_logic_vector(2 DOWNTO 0);每次按键给PC发送"Welcome"字符串,这是发送状态寄存器
SIGNAL Cnt_delay : Std_logic_vector(19 DOWNTO 0);延时去抖计数器
SIGNAL Start_delaycnt : Std_logic; 开始延时计数标志
SIGNAL Key_entry1 : Std_logic; 确定有键按下曛?
SIGNAL Key_entry2 : Std_logic; 确定有键按下标志
//////////////////////////////////////////////
CONSTANT Div_par : Std_logic_vector(15 DOWNTO 0) := "0000000100000100";
分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8
SIGNAL Txd_xhdl3 : Std_logic;
BEGIN
En <="01010101" ;7段数码管使能信号赋值
Txd <= Txd_xhdl3;
Txd_xhdl3 <= Txd_reg ;
PROCESS(Clk,Rst)
BEGIN
IF (NOT Rst = ’1’) THEN
Cnt_delay <= "00000000000000000000";
Start_delaycnt <= ’0’;
ELSIF(Clk’EVENT AND Clk=’1’)THEN
IF (Start_delaycnt = ’1’) THEN
IF (Cnt_delay /= "11000011010100000000") THEN
Cnt_delay <= Cnt_delay + "00000000000000000001";
ELSE
Cnt_delay <= "00000000000000000000";
Start_delaycnt <= ’0’;
END IF;
ELSE
IF ((NOT Key_input=’1’) AND (Cnt_delay = "00000000000000000000")) THEN
Start_delaycnt <= ’1’;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(Clk,Rst)
BEGIN
IF (NOT Rst = ’1’) THEN
Key_entry1 <= ’0’;
ELSIF(Clk’EVENT AND Clk=’1’)THEN
IF (Key_entry2 = ’1’) THEN
Key_entry1 <= ’0’;
ELSE
IF (Cnt_delay = "11000011010100000000") THEN
IF (NOT Key_input = ’1’) THEN
Key_entry1 <= ’1’;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(Clk,Rst)
BEGIN
IF (NOT Rst = ’1’) THEN
Div_reg <= "0000000000000000";
ELSIF(Clk’EVENT AND Clk=’1’)THEN
IF (Div_reg = Div_par - "0000000000000001") THEN
Div_reg <= "0000000000000000";
ELSE
Div_reg <= Div_reg + "0000000000000001";
END IF;
END IF;
END PROCESS;
PROCESS(Clk,Rst) 分频得到8倍波特率的时钟
BEGIN
IF (NOT Rst = ’1’) THEN
Clkbaud8x <= ’0’;
ELSIF(Clk’EVENT AND Clk=’1’)THEN
IF (Div_reg = Div_par - "0000000000000001") THEN
Clkbaud8x <= NOT Clkbaud8x;
END IF;
END IF;
END PROCESS;
PROCESS(Clkbaud8x,Rst)
BEGIN
IF (NOT Rst = ’1’) THEN
Div8_rec_reg <= "000";
ELSE IF(Clkbaud8x’EVENT AND Clkbaud8x = ’1’) THEN
IF (Recstart = ’1’) THEN 接收开始标志
Div8_rec_reg <= Div8_rec_reg + "001";接收开始后,时隙数在8倍波特率的时钟下加1循环
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(Clkbaud8x,Rst)
BEGIN
IF (NOT Rst = ’1’) THEN
Div8_tras_reg <= "000";
ELSE IF(Clkbaud8x’EVENT AND Clkbaud8x = ’1’) THEN
IF (Trasstart = ’1’) THEN
Div8_tras_reg <= Div8_tras_reg + "001";发送开始后,时隙数在8倍波特率的时钟下加1循环
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(Div8_rec_reg)
BEGIN
IF (Div8_rec_reg = "111") THEN
Clkbaud_rec <= ’1’; -在第7个时隙,接收
ELSE