这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » 分享一下FPGA的串口通信程序

共11条 1/2 1 2 跳转至

分享一下FPGA的串口通信程序

助工
2011-10-12 21:32:29     打赏

串口通信 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;




关键词: 分享     一下     串口     通信     程序     logic     down    

工程师
2011-10-13 11:41:34     打赏
2楼

好东西,不错


菜鸟
2011-10-13 13:35:02     打赏
3楼
可惜我学的是verilog语言

助工
2011-10-13 22:31:12     打赏
4楼

   我先是学习的VHDL后也学过verilog.相比较来说,如果有C语言背后者容易上手,编写测试程序相对容易。


专家
2011-10-13 22:51:09     打赏
5楼
有C语言的话Verilog比较容易一些

菜鸟
2011-11-23 14:42:22     打赏
6楼
不错啊,厉害的很啊!

菜鸟
2011-12-22 12:00:07     打赏
7楼
tks

专家
2011-12-22 12:27:48     打赏
8楼

学习了。


专家
2013-04-11 08:12:22     打赏
9楼
好东西,。。。。

院士
2013-04-11 08:49:35     打赏
10楼
这个是传说中的VHDL语言 好高级的样子啊~~

共11条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]