首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

UART 串口通訊 VHDL 實現:發送器狀態機、波特率產生器與移位暖存器完整代碼解析

     編輯:關於C語言

一、 設計規格

  • 時鐘:50 MHz
  • 波特率:19200 bps (內部 14 倍過採樣,即 268.8 kHz)
  • 幀格式:1 起始位 (0) + 8 資料位 + 1 停止位 (1) = 10 位元
  • 介面:UART_TX_buf[7:0] (資料)、UART_TX_EN (啟動)、UART_TX_TI (發送中旗標)、UART_TXD (串列輸出)

二、 核心模組架構

1. 波特率產生器

-- 50MHz / (2 * 94) ≈ 265.9 kHz ≈ 19200 * 14
signal baudrate_counter : std_logic_vector(6 downto 0);
signal baudrate_out     : std_logic;

process(UART_clk)
begin
  if rising_edge(UART_clk) then
    if baudrate_counter >= "1011100" (94) then
      baudrate_counter <= "0000000";
      baudrate_out <= not baudrate_out; -- 翻轉產生方波
    else
      baudrate_counter <= baudrate_counter + 1;
    end if;
  end if;
end process;

2. 發送器狀態機 (兩進程法)

type TX_STATE is (TX_idle, TX_transfer);
signal TX_current_state, TX_next_state : TX_STATE;

-- 同步進程:狀態暖存器 (baudrate_out 下降沿觸發)
sync_proc_tx: process(baudrate_out, UART_rst)
begin
  if UART_rst = '1' then TX_current_state <= TX_idle;
  elsif falling_edge(baudrate_out) then TX_current_state <= TX_next_state;
  end if;
end process;

-- 組合進程:下一狀態邏輯 + 輸出邏輯 (baudrate_out 上升沿)
comb_proc_tx: process(baudrate_out, UART_rst)
begin
  if UART_rst = '1' then -- 重置所有暖存器/旗標
    TX_next_state <= TX_idle; TX_counter <= "0000"; TXD_buf <= '1';
    TX_start <= '0'; TX_TI <= '1'; TX_clk_counter <= "0000";
    TX_buf_shift <= "1111111111";
  elsif rising_edge(baudrate_out) then
    case TX_current_state is
      when TX_idle =>
        if UART_TX_EN = '1' and TX_TI = '1' then
          TX_next_state <= TX_transfer;
          TX_counter <= "1010"; -- 10 位元
          TX_buf_shift <= '1' & UART_TX_buf & '0'; -- 停止位 + 資料 + 起始位
          TX_start <= '1'; TX_TI <= '0'; TX_clk_counter <= "1101"; -- 13 週期分頻
        else -- 保持 idle 預設值
        end if;

      when TX_transfer =>
        if TX_start = '1' and TX_TI = '0' and TX_counter /= "0000" then
          if TX_clk_counter >= "1101" then -- 分頻完成,發送 1 位元
            TX_counter <= TX_counter - 1;
            TXD_buf <= TX_buf_shift(0); -- 發送 LSB
            TX_buf_shift <= '1' & TX_buf_shift(9 downto 1); -- 右移並補 1 (線路保持高)
            TX_clk_counter <= "0000";
          else
            TX_clk_counter <= TX_clk_counter + 1;
          end if;
        else -- 發送結束或異常
          TX_next_state <= TX_idle; -- 復位所有
        end if;

      when others => TX_next_state <= TX_idle;
    end case;
  end if;
end process;

UART_TXD <= TXD_buf;
UART_TX_TI <= TX_TI;

三、 關鍵設計細節解析

  1. 過採樣:14 倍波特率採樣,發送端用 13 週期分頻 (TX_clk_counter) 模擬位元週期,接收端通常在中間採樣點 (第 7 個過採樣) 讀取。
  2. 移位暖存器預載:'1' & DATA & '0' → 停止位(1) 在最左 (MSB),起始位(0) 在最右 (LSB)。右移發送順序:起始位 → D0~D7 → 停止位。發送結束後線路拉高 (補 1)。
  3. 雙沿同步:狀態暖存器在 falling_edge 更新,組合邏輯在 rising_edge 計算,避免建立/保持時間違例,提升時序邊緣。
  4. TX_TI (Transmitter Idle) 旗標:高電平表示可接受新資料,低電平表示忙碌。上層邏輯需輪詢此旗標決定何時寫入 UART_TX_buf 並拉高 UART_TX_EN。

四、 精簡版發送器 (備選架構)

第二段代碼展示單進程、計數器驅動的簡化版 (transmitter 實體),邏輯相似但無明確狀態機枚舉,適合資源受限場景。

五、 驗證與擴展建議

  • Testbench 驗證:發送已知字節 (如 0x55),示波器/模擬器觀察 TXD 波形、起始/停止位、位元週期精度。
  • 加入接收器 (RX):同樣用過採樣 + 狀態機 (IDLE → START → DATA → STOP),中間採樣、多數決濾波。
  • 支援可配置波特率:將分頻係數參數化 (generic),支援運行時切換。
  • FIFO 緩衝:高吞吐場景加入 TX/RX FIFO,解耦用戶邏輯與 UART 速率。

總結

本 VHDL 實現展示了工業級 UART 發送器的核心要素:精確波特率分頻、雙沿同步狀態機、帶起停位的移位暖存器、忙碌旗標交互。代碼結構清晰、可綜合、易擴展,可直接作為 FPGA/ASIC 專案的串口通訊 IP 核心模組。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved