fpga uart串口通信 VHDL

创建 UART 发送端,创建 UART 接收端 VHDL FPGA
采用 "N81" 格式:无校验位,八位数据,1 个停止位,波特率为 115200 bps。
接收端要求:
接收端要求:

  • 记得重新同步输入信号!
  • 分频器(FDIV)按照半个比特的速度生成一个脉冲。对于 115200 波特率,它的频率应该是加倍的。该分频器应该由接收状态机进行复位(以与字符的起始同步)。
  • 编写 UART 接收状态机。可以编码以下阶段:
    • 等待字符的开始,并在输入信号下降沿时清除分频器。
    • 等待第一个半比特:开始位。
    • 等待八位数据。
    • 等待并检查停止位,发送数据有效脉冲,并返回到起始状态。

以下是一个简单的 VHDL FPGA 代码,用于创建 UART 发送端和接收端,以实现串口通信。该代码采用 "N81" 格式:无校验位,八位数据,1 个停止位,波特率为 115200 bps。

-- 导入库  
library IEEE;  
use IEEE.STD_LOGIC_1164.ALL;  
use IEEE.NUMERIC_STD.ALL;  
  
-- 实体声明  
entity uart is  
    Port ( clk : in  STD_LOGIC;  
           rst : in  STD_LOGIC;  
           tx : out  STD_LOGIC;  
           rx : inout  STD_LOGIC);  
end uart;  
  
-- 结构体  
architecture Behavioral of uart is  
    signal state : unsigned(2 downto 0) := "000"; -- 接收状态机状态  
    signal bit_count : unsigned(3 downto 0) := "0000"; -- 比特计数器  
    signal divider : unsigned(7 downto 0) := "00000000"; -- 分频器计数器  
    signal start : boolean := false; -- 起始位标志  
    signal data : array(0 to 7) of unsigned(3 downto 0); -- 数据缓冲区  
    signal stop : boolean := false; -- 停止位标志  
begin  
    -- UART 发送器  
    process(clk, rst)  
    begin  
        if rst = '1' then  
            tx <= '0';  
        elsif rising_edge(clk) then  
            if state = "001" and not start then  
                tx <= '1'; -- 发送起始位  
                start <= true;  
            elsif state = "011" and not start then  
                tx <= rx; -- 发送数据位  
                start <= false;  
                data(bit_count / 2) <= to_unsigned(std_logic_vector(data) / 256, 8); -- 清空缓冲区的高半比特  
                bit_count <= bit_count + 1;  
            elsif state = "111" and not stop then  
                tx <= '1'; -- 发送停止位  
                stop <= true;  
            elsif state = "100" and stop then  
                tx <= '0'; -- 发送空闲位  
                start <= false;  
                stop <= false;  
                data := (others => '0'); -- 清空缓冲区  
                bit_count := '0000'; -- 重置比特计数器  
            end if;  
        end if;  
    end process;  
      
    -- UART 接收器  
    process(clk, rst, rx)  
    begin  
        if rst = '1' then  
            rx <= 'Z'; -- 强制高阻态  
        elsif rising_edge(clk) then  
            if state = "000" and rx = '0' then -- 等待起始位  
                divider <= std_logic_vector(unsigned(divider) & (2^3)); -- 分频器计数器清零并开始计数  
                state <= "001";-- 进入状态机阶段1:等待起始位下降沿并清零分频器计数器  
            elsif state = "001" and rx = '1' then -- 检查起始位标志并进入状态机阶段2:等待数据位