程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 串口通信 UART通信之VHDL描述

串口通信 UART通信之VHDL描述

編輯:關於C語言
 

串口通信 UART通信

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity UART is --通用異步串行收發器實體

Port ( UART_clk : in STD_LOGIC; --收發器時鐘輸入,50MHz

UART_rst : in std_logic;

 

UART_TX_buf : in STD_LOGIC_VECTOR(7 downto 0);

UART_TX_TI : out std_logic;

UART_TX_EN : in std_logic;

UART_TXD : out std_logic;

 

UART_baudrate : out STD_LOGIC); --收發器波特率輸出19200的14倍頻(測試完成後可以取消)

end UART;

architecture Behavioral of UART is

signal baudrate_counter :std_logic_vector(6 downto 0):="0000000"; --波特率發生器分頻計數器

signal baudrate_out :std_logic:='0'; --波特率發生器波特率信號

signal TX_clk : std_logic:='0';

signal tx_clk_counter : std_logic_vector(3 downto 0) :="0000";

type TX_STATE is (TX_idle,TX_transfer);

signal TX_current_state,TX_next_state : Tx_state;

signal TX_buf_shift : std_logic_vector(9 downto 0):= "0111111111";

signal TX_counter :std_logic_vector(3 downto 0):="0000";

signal TX_start : std_logic:='0';

signal TXD_buf: std_logic:='0';

signal TX_TI : std_logic:='1';

begin

baudrate: process (UART_clk) --波特率發生器進程

begin

if rising_edge(UART_clk) then --對輸入時鐘進行分頻獲得所需波特率的14倍頻

if (baudrate_counter >= "1011100") then

baudrate_counter <= "0000000";

baudrate_out <= not baudrate_out;

else

baudrate_counter <= baudrate_counter + '1';

baudrate_out <= baudrate_out;

end if;

end if;

end process;

UART_baudrate <= 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;

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"; --發送bit計數器置數,發送10個bit,8bit數據加上開始結束位

TXD_buf <= '1'; --發送寄存器發送‘1’

TX_start <= '1'; --發送過程標志

TX_TI <= '0'; --發送進行中標志,表示發送器不可用

TX_clk_counter <= "1101"; --分頻計數器置數

TX_buf_shift <= '1' & UART_TX_buf & '0'; --寄存器保存數據與開始結束位

else

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";

end if;

when TX_transfer =>

if (TX_start = '1' and TX_TI = '0' and TX_counter /= "0000") then --進入正常發送狀態

if (TX_clk_counter >= "1101") then --如果分頻完成

TX_next_state <= TX_transfer; --沒有發送完成,繼續進入發送狀態

TX_counter <= TX_counter - '1'; --發送bit計數器自減

TXD_buf <= TX_buf_shift(0); --發送數據

TX_start <= '1'; --發送過程標志繼續允許

TX_TI <= '0'; --發送器不允許使用

TX_clk_counter <= "0000"; --分頻計數器清靈,繼續下一次

TX_buf_shift <= '1' & TX_buf_shift(9 downto 1); --數據移位

else

TX_next_state <= TX_transfer;

TX_counter <= TX_counter;

TXD_buf <= TXD_buf;

TX_start <= '1';

TX_TI <= '0';

TX_clk_counter <= TX_clk_counter + '1';

TX_buf_shift <= TX_buf_shift;

end if;

else

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";

end if;

when others =>

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";

end case;

end if;

end process;

UART_TXD <= TXD_buf;

UART_TX_TI <= TX_TI;

end Behavioral;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity transmitter is
port(cs,clk,rx:in std_logic;
indata:in std_logic_vector(7 downto 0);
txd,ti:out std_logic);
end transmitter;
architecture tr1 of transmitter is
signal sig_count:std_logic_vector(3 downto 0);
signal sig_ti,sig_ti1,sig_txd,sig_buffer:std_logic;
signal sig_data:std_logic_vector(7 downto 0);
signal sig_txddata:std_logic_vector(9 downto 0);
begin
process(cs,clk,rx)
begin
if(clk'event and clk='1')then
if(cs='0')then
if(sig_buffer='0')then
if(rx='0')then
for i in 8 downto 1 loop
sig_txddata(i)<=indata(i-1);
end loop;
sig_txddata(9)<='0'; --加起始位

sig_data<=indata;
sig_buffer<='1';
end if;
else
for i in 9 downto 1 loop
sig_txddata(i)<=sig_txddata(i-1);
end loop;
sig_txd<=sig_txddata(9);
sig_txddata(0)<='1'; --加停止位

if(sig_count="1000")then
sig_count<="0000";
elsif(sig_count="0000"and sig_ti='1')then
sig_buffer<='0';
sig_ti<='0';
else
sig_count<=sig_count+'1';
sig_ti<='1';
end if;
end if;
end if;
end if;

end process;
process
begin
if(sig_ti='0')then
txd<='1';
else txd<=sig_txd;
end if;
end process;
ti<=not sig_ti;
end tr1;
 

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved