求大神帮忙解释一下VHDL串口通信?解说一下每一条语句的意思,真心感谢!

求大神帮忙解释一下VHDL串口通信?解说一下每一条语句的意思,真心感谢!,第1张

library ieee

useieee.std_logic_1164.all

entity correspondis

port(

clk,en:in std_logic

Send_data:in std_logic_vector(9 downto 0)

serial:out std_logic)

end correspond

architecturecorrespond_arc of correspond is--定义结构体

begin

process(clk)

variable count:integer range 0 to 9 :=0 --定义变量,初值为0

begin

if (en='0') then

--如果信号不允许发送,即EN= ‘0’,则计数0,串口输出高电平‘1’

count:=0

serial<='1'

elsif rising_edge(clk) then

--如果允许发送,即EN= ‘1’,开始发送

if (count=9) then--如果count=9,则不停的发送数据最高位send_data[9]

serial<=Send_data(9)

else--如果count/=9,则依次从0位到9位开始发送数据

serial<=Send_data(count)

count:=count+1

end if

end if

end process

endcorrespond_arc

既然固定值可以,那就说明

h_pixel:=conv_integer(h_pixel_data) --h_pixel_data是串口接受的数据

v_pixel:=conv_integer(v_pixel_data) --v_pixel_data是串口接受的数据

出问题了。

B <= conv_integer(A) --将std_logic_vector的A转换成整数integer的B

记得USE IEEE.STD_LOGIC_ARITH.ALL;

1。可以用CPLD模拟一个RS232串口,利用这个串口与单片机通信

下面是用VHDL写的一个串口程序,你可以根据你的通信协议对这个程序略作修改即可使用

-- 本模块的功能是验证实现基本的串口通信的功能。

--

-- 程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控

--制器,10个bit是1位起始位,8个数据位,1个结束

--位。串口的波特律由程序中定义的div_par参数决定,更改该参数可以实

--现相应的波特率。程序当前设定的div_par 的值是0x104,对应的波特率是

--9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间

--划分为8个时隙以使通信同步.

:串口处于全双工工作状态,

--字符串(串口调试工具设成按ASCII码接受方式);

library IEEE

use IEEE.STD_LOGIC_1164.ALL

use IEEE.STD_LOGIC_ARITH.ALL

use IEEE.STD_LOGIC_UNSIGNED.ALL

ENTITY UART IS

PORT (

clk : IN std_logic

rst : IN std_logic

rxd : IN std_logic --串行数据接收端

txd : OUT std_logic--串行数据发送端

en : OUT std_logic-- 数码管使能

seg_data: OUT std_logic_vector(7 DOWNTO 0)--数码管数据

key_input : IN std_logic --按键输入

)

END UART

ARCHITECTURE arch OF UART IS

--//////////////////inner reg////////////////////

SIGNAL div_reg : std_logic_vector(15 DOWNTO 0)--分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟

SIGNAL div8_tras_reg: std_logic_vector(2 DOWNTO 0)--该寄存器的计数值对应发送时当前位于的时隙数

SIGNAL div8_rec_reg : std_logic_vector(2 DOWNTO 0) --寄存器的计数值对应接收时当前位于的时隙数

SIGNAL state_tras : std_logic_vector(3 DOWNTO 0) -- 发送状态寄存器

SIGNAL state_rec: std_logic_vector(3 DOWNTO 0)-- 接受状态寄存器

SIGNAL clkbaud_tras : std_logic--以波特率为频率的发送使能信号

SIGNAL clkbaud_rec : std_logic--以波特率为频率的接受使能信号

SIGNAL clkbaud8x: std_logic--以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙

SIGNAL recstart : std_logic-- 开始发送标志

SIGNAL recstart_tmp : std_logic--开始接受标志

SIGNAL trasstart: std_logic

SIGNAL rxd_reg1 : std_logic--接收寄存器1

SIGNAL rxd_reg2 : std_logic--接收寄存器2,因为接收数据为异步信号,故用两级缓存

SIGNAL txd_reg : std_logic--发送寄存器

SIGNAL rxd_buf : std_logic_vector(7 DOWNTO 0)--接受数据缓存

SIGNAL txd_buf : std_logic_vector(7 DOWNTO 0)--发送数据缓存

SIGNAL send_state : std_logic_vector(2 DOWNTO 0)--每次按键给PC发送"Welcome"字符串,这是发送状态寄存器

SIGNAL cnt_delay: std_logic_vector(19 DOWNTO 0)--延时去抖计数器

SIGNAL start_delaycnt : std_logic --开始延时计数标志

SIGNAL key_entry1 : std_logic --确定有键按下标志

SIGNAL key_entry2 : std_logic --确定有键按下标志

--//////////////////////////////////////////////

CONSTANT div_par : std_logic_vector(15 DOWNTO 0) := "0000000100000100"

--分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8

SIGNAL txd_xhdl3: std_logic

BEGIN

en <='0' --7段数码管使能信号赋值

txd <= txd_xhdl3

txd_xhdl3 <= txd_reg

PROCESS(clk,rst)

BEGIN

IF (NOT rst = '1') THEN

cnt_delay <= "00000000000000000000"

start_delaycnt <= '0'

ELSIF(clk'EVENT AND clk='1')THEN

IF (start_delaycnt = '1') THEN

IF (cnt_delay /= "11000011010100000000") THEN

cnt_delay <= cnt_delay + "00000000000000000001"

ELSE

cnt_delay <= "00000000000000000000"

start_delaycnt <= '0'

END IF

ELSE

IF ((NOT key_input='1') AND (cnt_delay = "00000000000000000000")) THEN

start_delaycnt <= '1'

END IF

END IF

END IF

END PROCESS

PROCESS(clk,rst)

BEGIN

IF (NOT rst = '1') THEN

key_entry1 <= '0'

ELSIF(clk'EVENT AND clk='1')THEN

IF (key_entry2 = '1') THEN

key_entry1 <= '0'

ELSE

IF (cnt_delay = "11000011010100000000") THEN

IF (NOT key_input = '1') THEN

key_entry1 <= '1'

END IF

END IF

END IF

END IF

END PROCESS

PROCESS(clk,rst)

BEGIN

IF (NOT rst = '1') THEN

div_reg <= "0000000000000000"

ELSIF(clk'EVENT AND clk='1')THEN

IF (div_reg = div_par - "0000000000000001") THEN

div_reg <= "0000000000000000"

ELSE

div_reg <= div_reg + "0000000000000001"

END IF

END IF

END PROCESS

PROCESS(clk,rst) --分频得到8倍波特率的时钟

BEGIN

IF (NOT rst = '1') THEN

clkbaud8x <= '0'

ELSIF(clk'EVENT AND clk='1')THEN

IF (div_reg = div_par - "0000000000000001") THEN

clkbaud8x <= NOT clkbaud8x

END IF

END IF

END PROCESS

PROCESS(clkbaud8x,rst)

BEGIN

IF (NOT rst = '1') THEN

div8_rec_reg <= "000"

ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN

IF (recstart = '1') THEN --接收开始标志

div8_rec_reg <= div8_rec_reg + "001"--接收开始后,时隙数在8倍波特率的时钟下加1循环

END IF

END IF

END IF

END PROCESS

PROCESS(clkbaud8x,rst)

BEGIN

IF (NOT rst = '1') THEN

div8_tras_reg <= "000"

ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN

IF (trasstart = '1') THEN

div8_tras_reg <= div8_tras_reg + "001"--发送开始后,时隙数在8倍波特率的时钟下加1循环

END IF

END IF

END IF

END PROCESS

PROCESS(div8_rec_reg)

BEGIN

IF (div8_rec_reg = "111") THEN

clkbaud_rec <= '1'---在第7个时隙,接收使能信号有效,将数据打入

ELSE

clkbaud_rec <= '0'

END IF

END PROCESS

PROCESS(div8_tras_reg)

BEGIN

IF (div8_tras_reg = "111") THEN

clkbaud_tras <= '1' --在第7个时隙,发送使能信号有效,将数据发出

ELSE

clkbaud_tras <= '0'

END IF

END PROCESS

PROCESS(clkbaud8x,rst)

BEGIN

IF (NOT rst = '1') THEN

txd_reg <= '1'

trasstart <= '0'

txd_buf <= "00000000"

state_tras <= "0000"

send_state <= "000"

key_entry2 <= '0'

ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN

IF (NOT key_entry2 = '1') THEN

IF (key_entry1 = '1') THEN

key_entry2 <= '1'

txd_buf <= "01110111" --"w"

END IF

ELSE

CASE state_tras IS

WHEN "0000" => --发送起始位

IF ((NOT trasstart='1') AND (send_state <"111") ) THEN

trasstart <= '1'

ELSE

IF (send_state <"111") THEN

IF (clkbaud_tras = '1') THEN

txd_reg <= '0'

state_tras <= state_tras + "0001"

END IF

ELSE

key_entry2 <= '0'

state_tras <= "0000"

END IF

END IF

WHEN "0001" =>--发送第1位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "0010" => --发送第2位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "0011" => --发送第3位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "0100" =>--发送第4位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "0101" =>--发送第5位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "0110" =>--发送第6位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "0111" =>--发送第7位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "1000" => --发送第8位

IF (clkbaud_tras = '1') THEN

txd_reg <= txd_buf(0)

txd_buf(6 DOWNTO 0) <= txd_buf(7 DOWNTO 1)

state_tras <= state_tras + "0001"

END IF

WHEN "1001" => --发送停止位

IF (clkbaud_tras = '1') THEN

txd_reg <= '1'

txd_buf <= "01010101"

state_tras <= state_tras + "0001"

END IF

WHEN "1111" =>

IF (clkbaud_tras = '1') THEN

state_tras <= state_tras + "0001"

send_state <= send_state + "001"

trasstart <= '0'

CASE send_state IS

WHEN "000" =>

txd_buf <= "01100101"--"e"

WHEN "001" =>

txd_buf <= "01101100"--"l"

WHEN "010" =>

txd_buf <= "01100011" --"c"

WHEN "011" =>

txd_buf <= "01101111"--"o"

WHEN "100" =>

txd_buf <= "01101101" --"m"

WHEN "101" =>

txd_buf <= "01100101"-- "e"

WHEN OTHERS =>

txd_buf <= "00000000"

END CASE

END IF

WHEN OTHERS =>

IF (clkbaud_tras = '1') THEN

state_tras <= state_tras + "0001"

trasstart <= '1'

END IF

END CASE

END IF

END IF

END IF

END PROCESS

PROCESS(clkbaud8x,rst) --接受PC机的数据

BEGIN

IF (NOT rst = '1') THEN

rxd_reg1 <= '0'

rxd_reg2 <= '0'

rxd_buf <= "00000000"

state_rec <= "0000"

recstart <= '0'

recstart_tmp <= '0'

ELSE IF(clkbaud8x'EVENT AND clkbaud8x = '1') THEN

rxd_reg1 <= rxd

rxd_reg2 <= rxd_reg1

IF (state_rec = "0000") THEN

IF (recstart_tmp = '1') THEN

recstart <= '1'

recstart_tmp <= '0'

state_rec <= state_rec + "0001"

ELSE

IF ((NOT rxd_reg1 AND rxd_reg2) = '1') THEN --检测到起始位的下降沿,进入接受状态

recstart_tmp <= '1'

END IF

END IF

ELSE

IF (state_rec >= "0001" AND state_rec<="1000") THEN

IF (clkbaud_rec = '1') THEN

rxd_buf(7) <= rxd_reg2

rxd_buf(6 DOWNTO 0) <= rxd_buf(7 DOWNTO 1)

state_rec <= state_rec + "0001"

END IF

ELSE

IF (state_rec = "1001") THEN

IF (clkbaud_rec = '1') THEN

state_rec <= "0000"

recstart <= '0'

END IF

END IF

END IF

END IF

END IF

END IF

END PROCESS

PROCESS(rxd_buf) --将接受的数据用数码管显示出来

BEGIN

CASE rxd_buf IS

WHEN "00110000" =>

seg_data <= "00000011"

WHEN "00110001" =>

seg_data <= "10011111"

WHEN "00110010" =>

seg_data <= "00100101"

WHEN "00110011" =>

seg_data <= "00001101"

WHEN "00110100" =>

seg_data <= "10011001"

WHEN "00110101" =>

seg_data <= "01001001"

WHEN "00110110" =>

seg_data <= "01000001"

WHEN "00110111" =>

seg_data <= "00011111"

WHEN "00111000" =>

seg_data <= "00000001"

WHEN "01000001" =>

seg_data <= "00011001"

WHEN "01000010" =>

seg_data <= "00010001"

WHEN "01000011" =>

seg_data <= "11000001"

WHEN "01000100" =>

seg_data <= "01100011"

WHEN "01000101" =>

seg_data <= "10000101"

WHEN "01000110" =>

seg_data <= "01100001"

WHEN "01000111" =>

seg_data <= "01110001"

WHEN OTHERS =>

seg_data <= "11111111"

END CASE

END PROCESS

END arch

2。可利用单片机的IO口与CPLD实现通信,其他人已经回答过了,我不再赘述。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7974881.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-12
下一篇 2023-04-12

发表评论

登录后才能评论

评论列表(0条)

保存