打印
[FPGA]

串口通信的大家走一走瞧一瞧哈,及需解决

[复制链接]
984|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小财迷|  楼主 | 2014-4-16 17:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
--文件名:reciever.vhd.
--功能:UART接受器
--系统由五个状态(r_start,r_center,r_wait,r_sample,r_stop)和两个进程构成
LIBRARY IEEE;  --调用库
USE IEEE.STD_LOGIC_1164.ALL;        --调用库中的程序包
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY receiver IS
   GENERIC(framlenr:INTEGER:=8);        --传送的数据位为8位,规定数据位为8位
   PORT(   bclkr : IN STD_LOGIC;                --时钟输入端口
                  resetr : IN STD_LOGIC;                  --复位信号端口
                    rxdr : IN STD_LOGIC ;                  --数据输入端口
             r_ready : OUT STD_LOGIC;                --每发送完一帧数据,出现一个结束时钟脉冲
                    rbuf : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); --定义输入输出信号
END ENTITY receiver;
ARCHITECTURE Behavioral OF receiver IS
    TYPE states IS (r_start,r_center,r_wait,r_sample,r_stop);--定义各子状态
       SIGNAL state:states:=r_start;
       SIGNAL rxd_sync:STD_LOGIC;    -- rxd_sync内部信号,接受rxd输入
BEGIN
   pro1:PROCESS(rxdr)
      BEGIN
          IF rxdr='0' THEN
                                rxd_sync<='0';
          ELSE rxd_sync<='1';
          END IF;           --利用同步信号检测起始位是否到来
   END PROCESS;
   pro2:PROCESS(bclkr,resetr,rxd_sync)            --主控时序、组合进程
       VARIABLE count:STD_LOGIC_VECTOR(3 DOWNTO 0); --定义中间变量
       VARIABLE  rcnt: INTEGER:=0;                 -- rcnt为接收的数据位数计数        
       VARIABLE rbufs:STD_LOGIC_VECTOR(7 DOWNTO 0);
     BEGIN
       IF resetr='1' THEN --高电平复位
                        state<=r_start; count:="0000";  --复位
       ELSIF RISING_EDGE(bclkr) THEN      --波特率信号的上升沿
  --状态机
          CASE state IS
                WHEN r_start=>                   --状态1,等待起始位
                                        IF rxd_sync='0' THEN
                                                state<=r_center;
                                                r_ready<='0'; --低电平有效起始位
                                                rcnt:=0;
                                ELSE
                                                state<=r_start; r_ready<='0';
                                END IF;  
            WHEN r_center=>                --状态2,求出每位的中点
                 IF  rxd_sync='0' THEN       --每个数据位被分为16等分,中点为8
                                                        IF count="0100" THEN
                                                                state<=r_wait; count:="0000";
                                         ELSE count:=count+1; state<=r_center;
                                    END IF;
                             ELSE state<=r_start;
                             END IF;
            WHEN r_wait=>                  --状态3,等待状态
                 IF count>="1110" THEN      
                     IF  rcnt=framlenr THEN
                                                                state<=r_stop;    -- rcnt=framlenr表示数据接收够8位
                                    ELSE state<=r_sample;
                                    END IF;
                                    count:="0000";
                           ELSE count:=count+1; state<=r_wait;
                                END IF;
            WHEN r_sample=>rbufs(rcnt):=rxd_sync;  --状态4,数据位采样检测
                                                   rcnt:=rcnt+1;
                                                   state<=r_wait;
            WHEN r_stop=>r_ready<='1'; rbuf<=rbufs; --状态5,输出帧接收完毕信号
                                                                 state<=r_start;
            WHEN others=>state<=r_start;
         END CASE;
       END IF;
   END PROCESS;
END Behavioral;
[code]--文件名:transfer.vhd
--功能:UART发送器
--说明:系统由五个状态(x_idle,x_start,x_wait,x_shift,x_stop)和一个进程构成。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY transfer IS
    GENERIC(framlent:INTEGER:=8);              --类属说明
    PORT (bclkt        :        IN STD_LOGIC;        --定义输入时钟信号
             resett         :        IN STD_LOGIC;                  --定义输入复位信号
                  xmit_cmd_p:  IN STD_LOGIC;        --发送控制信号,开始时刻设置一段高电平
             txdbuf    :  IN STD_LOGIC_VECTOR(7 DOWNTO 0); --为要发送的八位数据
              txd : OUT STD_LOGIC;                        --为发送器发出的串行信号
              txd_done :  OUT STD_LOGIC);                --定义发送结束信号,高电平有效
END transfer;
ARCHITECTURE Behavioral OF transfer IS
        TYPE states IS (x_idle,x_start,x_wait,x_shIFt,x_sTOp);     --定义5个子状态
        SIGNAL state:states:=x_idle;
        SIGNAL tcnt:INTEGER:=0;
BEGIN
        PROCESS(bclkt,resett,xmit_cmd_p,txdbuf)  --主控时序进程
                VARIABLE xcnt16:STD_LOGIC_VECTOR(4 DOWNTO 0):="00000"; --定义中间变量
                VARIABLE xbitcnt:INTEGER:=0;
                VARIABLE txds:STD_LOGIC;
   BEGIN  
                IF resett='1' THEN
                        state<=x_idle;    --复位,txd输出保持1
                        txd_done<='0';
                   txds:='1';           
                ELSIF RISING_EDGE(bclkt) THEN
                        CASE state IS
                                WHEN x_idle=>                 --状态1,等待数据帧发送命令
                                        IF xmit_cmd_p='1' THEN
                                                state<=x_start;txd_done<='0';       
                                        ELSE state<=x_idle;               
                                        END IF;
                                 WHEN x_start=>    --状态2,发送信号至起始位
                                        IF xcnt16="01111" THEN
                                                state<=x_shIFt;
                                                xcnt16:="00000";
                                        ELSE
                                                xcnt16:=xcnt16+1;
                                                txds:='0';
                                                state<=x_start;    --输出开始位,'0'
                                        END IF;                          
                                WHEN x_wait=>       --状态3,等待状态
                                        IF xcnt16>="01110" THEN
                                                IF xbitcnt=framlent THEN
                                                        state<=x_sTOp;
                                                        xbitcnt:=0;
                                                        xcnt16:="00000";
                                                ELSE state<=x_shIFt;
                                           END IF;
                                           xcnt16:="00000";
                                        ELSE
                                                xcnt16:=xcnt16+1;
                                                state<=x_wait;
                                        END IF;            
                                WHEN x_shIFt=>   --状态4,将待发数据进行并串转换
                                  txds:=txdbuf(xbitcnt);
                                  xbitcnt:=xbitcnt+1;
                                  state<=x_wait;
                                WHEN x_sTOp=>        --状态5,停止位发送状态
                                        IF xcnt16>="01111" THEN
                                                IF xmit_cmd_p='0' THEN
                                                        state<=x_idle;--高电平保持时间应低于一个帧发送的时间
                                                        xcnt16:="00000";
                                                ELSE xcnt16:=xcnt16; state<=x_sTOp;
                                                END IF;
                                                txd_done<='1';
                                        ELSE
                                                xcnt16:=xcnt16+1;
                                                txds:='1';
                                                state<=x_sTOp;
                                        END IF;
                                WHEN OTHERs=>
                                        state<=x_idle;
                        END CASE;               
                                END IF;
                          txd<=txds;
        END PROCESS;
END Behavioral;
[code]--文件名:uart_baud.vhd.
--功能:本实验想要实现的波特率为:9600,cyclone ii开发板提供说的时钟频率为:50MHz
--波特率发生器的分频数计算如下式:
--50000000/(16*9600)=325;占空比非50%
LIBRARY IEEE;--调用库函数
USE IEEE.STD_LOGIC_1164.ALL;--调用库函数的程序包
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY uart_baud IS
    GENERIC(framlenr:INTEGER:=325); --利用类属说明定义分频系数,              
    PORT (clk,reset:IN STD_LOGIC;--定义时钟,复位端口
              bclk      :OUT STD_LOGIC);--定义输出时钟端口
END ENTITY uart_baud;
ARCHITECTURE Behavioral OF uart_baud IS
  SIGNAL cnt:INTEGER RANGE 0 TO 325;
  BEGIN
  PROCESS(clk,reset)       
     BEGIN
       IF reset='1' THEN
                        cnt<=0; bclk<='0'; --高电平复位
                         ELSIF RISING_EDGE(clk) THEN
                                IF cnt<162 THEN
                                        cnt<=cnt+1; bclk<='1';
                                ELSIF cnt<framlenr-1 THEN --记数从零开始,减一要
                                        cnt<=cnt+1; bclk<='0';
                                ELSE cnt<=0;
                                END IF;
                         END IF;
     END PROCESS;
END Behavioral;
[code]LIBRARY IEEE;[code]--文件名:clock_div.vhd.
--功能:实验开发板晶振频率为:50MHZ,经过分频后得到5Hz脉冲频率
--分频数计算:50000000/5 = 10000000
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY clock_div IS
    GENERIC(framlenr:INTEGER:=10000000);  
    PORT (  clk:IN STD_LOGIC;
                        resetb:IN STD_LOGIC;
                bclk:INOUT STD_LOGIC);
END clock_div;
ARCHITECTURE Behavioral OF clock_div IS
  BEGIN
  PROCESS(clk,resetb)
        VARIABLE cnt:INTEGER;
  BEGIN
        IF resetb='1' THEN
                cnt:=0; bclk<='0';   
   ELSIF RISING_EDGE(clk) THEN
      IF cnt>=framlenr THEN
                        cnt:=0; bclk<='0';   
           ELSIF cnt>=framlenr/2 THEN  
                        cnt:=cnt+1;bclk<='1';
           ELSE cnt:=cnt+1; bclk<='0';
           END IF;
    END IF;
     END PROCESS;
  END Behavioral;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY decoder_8_8 IS

   PORT (
          a : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
                    q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
                        );
END decoder_8_8;

ARCHITECTURE Behavioral OF decoder_8_8 IS
   BEGIN
   PROCESS(a)
      BEGIN
          CASE a IS
                        WHEN x"00" => q <= "11000000";
                        WHEN x"01" => q <= "11111001";
                        WHEN x"02" => q <= "10100100";
                        WHEN x"03" => q <= "10110000";
                        WHEN x"04" => q <= "10011001";
                        WHEN x"05" => q <= "10010010";
                        WHEN x"06" => q <= "10000010";
                        WHEN x"07" => q <= "11111000";
                        WHEN x"08" => q <= "10000000";
                        WHEN x"09" => q <= "10010000";
                        WHEN x"0a" => q <= "10001000";
                        WHEN x"0b" => q <= "10000011";
                        WHEN x"0c" => q <= "11000110";
                        WHEN x"0d" => q <= "10100001";
                        WHEN x"0e" => q <= "10000110";       
                        WHEN x"0f" => q <= "10001110";
                        WHEN others => q <= "11111111";
                        END CASE;  
   END PROCESS;
END Behavioral;
[/code][/code][/code][/code]
这段代码能够实现功能吗,不能改怎么改呢,我调试了好久,还是不行

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

55

帖子

0

粉丝