UART 的异步串口通信协议的VHDL 语言实现异步串行通信的采用的波特率为9600b/s,外配晶体振荡器的频率为3.6864MHZ ,故采用分频电路package width isconstant N:integer:=8;end width;use work.width.all;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity fredivn isGENERIC (N:integer:=6);port(clkin: in std_logic;clkout: out std_logic);end fredivn;architecture behav of fredivn issignal count : integer;beginprocess(clkin)beginif (clkin'event and clkin=1)thenif(count<N-1)thencount<=count+1;else count<=0;end if;if (count<N/2)thenclkout<='1';else clkout<='0';end if;end if;end process;end behav;异步接收模块 RXD 的端口clk 为输入时钟,rx 为串行数据接收,sig1为接收中断标志,q 为并行数据输出程序流程如下:sig1是接收中断标志位,当是低电平时,说明接收过程并未启动,于是检测电平,当rx 电平为低时,sig2开始计数,若连续8次采样rx 都是低电平,则说明是起始位,启动接收过程,每隔16个接收时钟接收1位数据直至11位接收完毕,并行输出口是一个串并转换。
本例中的数据位8位E C N CRXD data 8bitlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity rxd3 isport(clk,rx: in std_logic;sig1:buffer std_logic; --接收中断标志q:out std_logic_vector(7 downto 0)); --并行数据输出end rxd3;architecture behav of rxd3 issignal tmpreg8: std_logic_vector(8 downto 0);signal sig2: integer range 0 to 16 ; --接收时钟计数signal sig3: integer range 0 to 9 ; --接收数据位数signal sig4: std_logic; --串并转换时钟,接收是为1 ,空挡为0beginprocess(clk)beginif (clk'event and clk='1') thenif (sig1='0') then --ri 状态if (rx='0') then --此句判断是否是起始位,是则 sig1<='1'if (sig2=7) then --对应起始位的处理 sig2<='0'; sig1<='1'; sig4<='1';else sig2<=sig2+1; sig4<='0';end if;else sig2<='0';end if;else --ri 为1,对应的数据接收 if (sig2=15) thensig2<='0';if (sig3=8) then --接收完一帧否?若接收完则sig1置0,表示空闲sig3<='0' ; sig1<='0'; sig4<='0';else sig3<=sig3+1; sig4<='1';end if;else sig2<=sig2+1; sig4<='0';end if;end if;end if;end process; E C N Cprocess(sig4) --此进程完成接收数据的串并转换 beginif (sig4'event and sig4='1') thenfor i in tempreg8'high downto tempreg8'low+1 looptempreg8(i)<=tempreg8(i-1);end loop;tempreg8( tempreg8'low)<=rx;end if;end process;processbeginfor i in 7 downto 0 loopq(i)<=tempreg8(i);end loop;end process;end behav;异步发送模块TXD5的端口中,indata 为8位数据输入端口。
cs 为片选信号,低电平有效。
wr 是输出允许,高电平有效。
clk 为输入时钟信号,为发送提供时钟,txd 是串行发送端,ti 是发送中断标志,高电平表示正在发送低电平表示空闲library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity txd5 isport(indata: in std_logic_vector(7 downto 0); --8位数据输入端口cs,wr,clk:in std_logic;txd,ti: out std_logic); --txd 串行发送,ti 发送中断信号end txd5;architecture behav of txd5 issignal 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);beginprocess(clk)begin E C N Cif (clk'event and clk='1')thenif (cs='0') thenif (sig_buffer='0')then --发送中断为0,即发送不忙if (wr='1') then --读入数据准备发送for i in 8 downto 1 loopsig_txddata(i)<=indata(i-1); --并行输入数据送sig_txddataend loop;sig_txddata (9)<='0'; --加起始位 sig_txddata (0)<='1'; --加偶校验位 sig_data<=indata;sig_buffer<='1';end if;else --正在发送数据for i in 9 downto 1 loopsig_txddata (i )<=sig_txddata (i-1); --数据串行输出 end loop;sig_txd<=sig_txddata (9);sig_txddata (0)<='1'; --加结束位if (sig_count="1000") then --此if 句用于设置ti 状态sig_count<="0000";elsif (sig_count<="0000"and sig_ti='1') thensig_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 --txd 赋值过程beginif (sig_ti='0') thentxd<='1';else txd<=sig_txd;end if;end processti<= not sig_ti;end behav; E C N C。