UART的异步串口通信协议的VHDL语言实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UART的异步串口通信协议的VHDL语言实现
异步串行通信的采用的波特率为9600b/s,外配晶体振荡器的频率为3.6864MHZ,故采用分频电路
package width is
constant 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 is
GENERIC (N:integer:=6);
port(clkin: in std_logic;
clkout: out std_logic);
end fredivn;
architecture behav of fredivn is
signal count : integer;
begin
process(clkin)
begin
if (clkin'event and clkin=1)then
if(count
else count<=0;
end if;
if (count
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位
RXD data 8bit
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity rxd3 is
port(clk,rx: in std_logic;
sig1:buffer std_logic; --接收中断标志
q:out std_logic_vector(7 downto 0)); --并行数据输出
end rxd3;
architecture behav of rxd3 is
signal 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 ,空挡为0
begin
process(clk)
begin
if (clk'event and clk='1') then
if (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) then
sig2<='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;
process(sig4) --此进程完成接收数据的串并转换
begin
if (sig4'event and sig4='1') then
for i in tempreg8'high downto tempreg8'low+1 loop
tempreg8(i)<=tempreg8(i-1);
end loop;
tempreg8( tempreg8'low)<=rx;
end if;
end process;
process
begin
for i in 7 downto 0 loop
q(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 is
port(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 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(clk)
begin
if (clk'event and clk='1')then
if (cs='0') then
if (sig_buffer='0')then --发送中断为0,即发送不忙
if (wr='1') then --读入数据准备发送
for i in 8 downto 1 loop
sig_txddata(i)<=indata(i-1); --并行输入数据送sig_txddata
end loop;
sig_txddata(9)<='0'; --加起始位
sig_txddata(0)<='1'; --加偶校验位
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 --此if句用于设置ti状态
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 --txd赋值过程
begin
if (sig_ti='0') then
txd<='1';
else txd<=sig_txd;
end if;
end process
ti<= not sig_ti;
end behav;