⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 新建 文本文档.txt

📁 UART 处理的是并行数据转换为串行信号和串行信号转换为并行数据。现有的时钟不精确,这就需要用一个远高于波特率的本地时钟信号对输入信号不断采样,以不断让接收器与发送器保持同步。
💻 TXT
字号:
波特率发生器实际上就是一个简单的分频器,它的程序如程序1所示。
程序1
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity baud is
 generic(num:integer:=16);
port (clk : in std_logic;
      reset : in std_logic;
bclk: out std_logic);
end baud;
architecture one of baud is
signal baud_sig:std_logic:='0';
begin
process(clk,reset)
variable cnt:integer:=0;
begin
if reset='1' then cnt:=0;baud_sig<='0';
elsif clk='1' and clk'event then
cnt:=cnt+1;
if cnt=(num/2) then cnt:=0;baud_sig<=not baud_sig;
end if;
end if;
bclk<=baud_sig;
end process;
end one;

窄脉冲发生器程序如程序3-4所示:
程序3-4
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity fpq is
    port (clk,reset:in std_logic;
              xmit_cmd_p:out std_logic);
end fpq;
architecture one of fpq is
begin
process(clk,reset)
variable cnt:integer;
begin
  if reset='1' then                                         
     cnt:=0; xmit_cmd_p<='0';
  elsif rising_edge(clk) then
     if cnt>=200 then cnt:=0; xmit_cmd_p<='1';                     
         else cnt:=cnt+1; xmit_cmd_p<='0';
         end if;
  end if;
end process;
end one;

发送器相对于接收器要容易处理,只要每隔16个CLK16时钟周期输出1位即可,次序遵循1位起始位、8位数据位(假定数据位为8位)、1位停止位、1位校验位(可选)。当UART被复位后,发送器就一直在等待一个数据桢发送命令xmit_cmd。微处理器给出xmit_cmd_p 信号,在数据发送过程中用输出信号xmit_done作为标志信号,当一帧数据发送完毕时,xmit_done信号为1,通知CPU在下个时钟装入新数据。发送器程序如程序2所示:
程序2
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity u_xmit is
   generic(framlent:integer:=8);
 port( bclk ,reset ,xmit_cmd_p: in std_logic;
       xbuf : in std_logic_vector( 7 downto 0);
       txd  : out std_logic;
       xmit_done : out  std_logic:='1');
end u_xmit;
architecture one of u_xmit is
 type xmitstate is (x_Idle,x_start,x_wait,x_shift,x_stop);
 signal current_state: xmitstate;
  begin
com: process (current_state,xbuf,bclk,reset,xmit_cmd_p)
         variable xcnt16 : std_logic_vector ( 4 downto 0):="00000"; 
         variable xbitcnt:integer:=0;
         variable txds:std_logic;
           begin
            if reset='1' then 
                         current_state<=x_Idle;  
                         xmit_done<='0';
                         txds:='1';          
              elsif rising_edge(bclk) then
               case current_state is
                 when x_Idle =>
                       if xmit_cmd_p='1' then 
                              current_state<=x_start;
                              xmit_done<='0';
                       else current_state<=x_Idle;
                       end if;
                 when x_start => 
                       if xcnt16="01111" then 
                           current_state<=x_shift; xbitcnt:=0;        
                           xcnt16:="00000";
                       else current_state<=x_start;
                            xcnt16:=xcnt16+1;
                            txds:='0';
                       end if;
                 when x_wait =>
                       if xcnt16="01110" then
                           if xbitcnt=framlent then
                              current_state<=x_stop;
                              xbitcnt:=0;
                           else current_state<=x_shift;
                           end if;
                          xcnt16:="00000";
                          else xcnt16:=xcnt16+1;
                               current_state<=x_wait;
                           end if;
                  when x_shift=>
                        txds:=xbuf(xbitcnt);
                        xbitcnt:=xbitcnt+1;
                        current_state<=x_wait;
                  when x_stop=>
                        if xcnt16>="01111" then
                               if xmit_cmd_p='0' then
                                  current_state<=x_Idle;
                                  xcnt16:="00000";
                               else xcnt16:=xcnt16;
                                    current_state<=x_stop;
                               end if;
                               xmit_done<='1';
                        else xcnt16:=xcnt16+1;
                             txds:='1';
                             current_state<=x_stop;
                        end if;
                   when others=>current_state<=x_Idle;
                  end case; 
             end if;               
               txd<=txds;
     end process;
end one;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -