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

2020-02-23 10:44发布

  1. --文件名:reciever.vhd.
  2. --功能:UART接受器
  3. --系统由五个状态(r_start,r_center,r_wait,r_sample,r_stop)和两个进程构成
  4. LIBRARY IEEE;  --调用库
  5. USE IEEE.STD_LOGIC_1164.ALL;        --调用库中的程序包
  6. USE IEEE.STD_LOGIC_ARITH.ALL;
  7. USE IEEE.STD_LOGIC_UNSIGNED.ALL;
  8. ENTITY receiver IS
  9.    GENERIC(framlenr:INTEGER:=8);        --传送的数据位为8位,规定数据位为8位
  10.    PORT(   bclkr : IN STD_LOGIC;                --时钟输入端口
  11.                   resetr : IN STD_LOGIC;                  --复位信号端口
  12.                     rxdr : IN STD_LOGIC ;                  --数据输入端口
  13.              r_ready : OUT STD_LOGIC;                --每发送完一帧数据,出现一个结束时钟脉冲
  14.                     rbuf : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
  15. ); --定义输入输出信号
  16. END ENTITY receiver;
  17. ARCHITECTURE Behavioral OF receiver IS
  18.     TYPE states IS (r_start,r_center,r_wait,r_sample,r_stop);--定义各子状态
  19.        SIGNAL state:states:=r_start;
  20.        SIGNAL rxd_sync:STD_LOGIC;    -- rxd_sync内部信号,接受rxd输入
  21. BEGIN
  22.    pro1:PROCESS(rxdr)
  23.       BEGIN
  24.           IF rxdr='0' THEN
  25.                                 rxd_sync<='0';
  26.           ELSE rxd_sync<='1';
  27.           END IF;           --利用同步信号检测起始位是否到来
  28.    END PROCESS;
  29.    pro2:PROCESS(bclkr,resetr,rxd_sync)            --主控时序、组合进程
  30.        VARIABLE count:STD_LOGIC_VECTOR(3 DOWNTO 0); --定义中间变量
  31.        VARIABLE  rcnt: INTEGER:=0;                 -- rcnt为接收的数据位数计数        
  32.        VARIABLE rbufs:STD_LOGIC_VECTOR(7 DOWNTO 0);
  33.      BEGIN
  34.        IF resetr='1' THEN --高电平复位
  35.                         state<=r_start; count:="0000";  --复位
  36.        ELSIF RISING_EDGE(bclkr) THEN      --波特率信号的上升沿
  37.   --状态机
  38.           CASE state IS
  39.                 WHEN r_start=>                   --状态1,等待起始位
  40.                                         IF rxd_sync='0' THEN
  41.                                                 state<=r_center;
  42.                                                 r_ready<='0'; --低电平有效起始位
  43.                                                 rcnt:=0;
  44.                                 ELSE
  45.                                                 state<=r_start; r_ready<='0';
  46.                                 END IF;  
  47.             WHEN r_center=>                --状态2,求出每位的中点
  48.                  IF  rxd_sync='0' THEN       --每个数据位被分为16等分,中点为8
  49.                                                         IF count="0100" THEN
  50.                                                                 state<=r_wait; count:="0000";
  51.                                          ELSE count:=count+1; state<=r_center;
  52.                                     END IF;
  53.                              ELSE state<=r_start;
  54.                              END IF;
  55.             WHEN r_wait=>                  --状态3,等待状态
  56.                  IF count>="1110" THEN      
  57.                      IF  rcnt=framlenr THEN
  58.                                                                 state<=r_stop;    -- rcnt=framlenr表示数据接收够8位
  59.                                     ELSE state<=r_sample;
  60.                                     END IF;
  61.                                     count:="0000";
  62.                            ELSE count:=count+1; state<=r_wait;
  63.                                 END IF;
  64.             WHEN r_sample=>rbufs(rcnt):=rxd_sync;  --状态4,数据位采样检测
  65.                                                    rcnt:=rcnt+1;
  66.                                                    state<=r_wait;
  67.             WHEN r_stop=>r_ready<='1'; rbuf<=rbufs; --状态5,输出帧接收完毕信号
  68.                                                                  state<=r_start;
  69.             WHEN others=>state<=r_start;
  70.          END CASE;
  71.        END IF;
  72.    END PROCESS;
  73. END Behavioral;
  74. [code]--文件名:transfer.vhd
  75. --功能:UART发送器
  76. --说明:系统由五个状态(x_idle,x_start,x_wait,x_shift,x_stop)和一个进程构成。
  77. LIBRARY IEEE;
  78. USE IEEE.STD_LOGIC_1164.ALL;
  79. USE IEEE.STD_LOGIC_ARITH.ALL;
  80. USE IEEE.STD_LOGIC_UNSIGNED.ALL;
  81. ENTITY transfer IS
  82.     GENERIC(framlent:INTEGER:=8);              --类属说明
  83.     PORT (bclkt        :        IN STD_LOGIC;        --定义输入时钟信号
  84.              resett         :        IN STD_LOGIC;                  --定义输入复位信号
  85.                   xmit_cmd_p:  IN STD_LOGIC;        --发送控制信号,开始时刻设置一段高电平
  86.              txdbuf    :  IN STD_LOGIC_VECTOR(7 DOWNTO 0); --为要发送的八位数据
  87.               txd : OUT STD_LOGIC;                        --为发送器发出的串行信号
  88.               txd_done :  OUT STD_LOGIC);                --定义发送结束信号,高电平有效
  89. END transfer;
  90. ARCHITECTURE Behavioral OF transfer IS
  91.         TYPE states IS (x_idle,x_start,x_wait,x_shIFt,x_sTOp);     --定义5个子状态
  92.         SIGNAL state:states:=x_idle;
  93.         SIGNAL tcnt:INTEGER:=0;
  94. BEGIN
  95.         PROCESS(bclkt,resett,xmit_cmd_p,txdbuf)  --主控时序进程
  96.                 VARIABLE xcnt16:STD_LOGIC_VECTOR(4 DOWNTO 0):="00000"; --定义中间变量
  97.                 VARIABLE xbitcnt:INTEGER:=0;
  98.                 VARIABLE txds:STD_LOGIC;
  99.    BEGIN  
  100.                 IF resett='1' THEN
  101.                         state<=x_idle;    --复位,txd输出保持1
  102.                         txd_done<='0';
  103.                    txds:='1';           
  104.                 ELSIF RISING_EDGE(bclkt) THEN
  105.                         CASE state IS
  106.                                 WHEN x_idle=>                 --状态1,等待数据帧发送命令
  107.                                         IF xmit_cmd_p='1' THEN
  108.                                                 state<=x_start;txd_done<='0';       
  109.                                         ELSE state<=x_idle;               
  110.                                         END IF;
  111.                                  WHEN x_start=>    --状态2,发送信号至起始位
  112.                                         IF xcnt16="01111" THEN
  113.                                                 state<=x_shIFt;
  114.                                                 xcnt16:="00000";
  115.                                         ELSE
  116.                                                 xcnt16:=xcnt16+1;
  117.                                                 txds:='0';
  118.                                                 state<=x_start;    --输出开始位,'0'
  119.                                         END IF;                          
  120.                                 WHEN x_wait=>       --状态3,等待状态
  121.                                         IF xcnt16>="01110" THEN
  122.                                                 IF xbitcnt=framlent THEN
  123.                                                         state<=x_sTOp;
  124.                                                         xbitcnt:=0;
  125.                                                         xcnt16:="00000";
  126.                                                 ELSE state<=x_shIFt;
  127.                                            END IF;
  128.                                            xcnt16:="00000";
  129.                                         ELSE
  130.                                                 xcnt16:=xcnt16+1;
  131.                                                 state<=x_wait;
  132.                                         END IF;            
  133.                                 WHEN x_shIFt=>   --状态4,将待发数据进行并串转换
  134.                                   txds:=txdbuf(xbitcnt);
  135.                                   xbitcnt:=xbitcnt+1;
  136.                                   state<=x_wait;
  137.                                 WHEN x_sTOp=>        --状态5,停止位发送状态
  138.                                         IF xcnt16>="01111" THEN
  139.                                                 IF xmit_cmd_p='0' THEN
  140.                                                         state<=x_idle;--高电平保持时间应低于一个帧发送的时间
  141.                                                         xcnt16:="00000";
  142.                                                 ELSE xcnt16:=xcnt16; state<=x_sTOp;
  143.                                                 END IF;
  144.                                                 txd_done<='1';
  145.                                         ELSE
  146.                                                 xcnt16:=xcnt16+1;
  147.                                                 txds:='1';
  148.                                                 state<=x_sTOp;
  149.                                         END IF;
  150.                                 WHEN OTHERs=>
  151.                                         state<=x_idle;
  152.                         END CASE;               
  153.                                 END IF;
  154.                           txd<=txds;
  155.         END PROCESS;
  156. END Behavioral;
  157. [code]--文件名:uart_baud.vhd.
  158. --功能:本实验想要实现的波特率为:9600,cyclone ii开发板提供说的时钟频率为:50MHz
  159. --波特率发生器的分频数计算如下式:
  160. --50000000/(16*9600)=325;占空比非50%
  161. LIBRARY IEEE;--调用库函数
  162. USE IEEE.STD_LOGIC_1164.ALL;--调用库函数的程序包
  163. USE IEEE.STD_LOGIC_ARITH.ALL;
  164. USE IEEE.STD_LOGIC_UNSIGNED.ALL;
  165. ENTITY uart_baud IS
  166.     GENERIC(framlenr:INTEGER:=325); --利用类属说明定义分频系数,              
  167.     PORT (clk,reset:IN STD_LOGIC;--定义时钟,复位端口
  168.               bclk      :OUT STD_LOGIC);--定义输出时钟端口
  169. END ENTITY uart_baud;
  170. ARCHITECTURE Behavioral OF uart_baud IS
  171.   SIGNAL cnt:INTEGER RANGE 0 TO 325;
  172.   BEGIN
  173.   PROCESS(clk,reset)       
  174.      BEGIN
  175.        IF reset='1' THEN
  176.                         cnt<=0; bclk<='0'; --高电平复位
  177.                          ELSIF RISING_EDGE(clk) THEN
  178.                                 IF cnt<162 THEN
  179.                                         cnt<=cnt+1; bclk<='1';
  180.                                 ELSIF cnt<framlenr-1 THEN --记数从零开始,减一要
  181.                                         cnt<=cnt+1; bclk<='0';
  182.                                 ELSE cnt<=0;
  183.                                 END IF;
  184.                          END IF;
  185.      END PROCESS;
  186. END Behavioral;
  187. [code]LIBRARY IEEE;[code]--文件名:clock_div.vhd.
  188. --功能:实验开发板晶振频率为:50MHZ,经过分频后得到5Hz脉冲频率
  189. --分频数计算:50000000/5 = 10000000
  190. LIBRARY IEEE;
  191. USE IEEE.STD_LOGIC_1164.ALL;
  192. USE IEEE.STD_LOGIC_ARITH.ALL;
  193. USE IEEE.STD_LOGIC_UNSIGNED.ALL;
  194. ENTITY clock_div IS
  195.     GENERIC(framlenr:INTEGER:=10000000);  
  196.     PORT (  clk:IN STD_LOGIC;
  197.                         resetb:IN STD_LOGIC;
  198.                 bclk:INOUT STD_LOGIC);
  199. END clock_div;
  200. ARCHITECTURE Behavioral OF clock_div IS
  201.   BEGIN
  202.   PROCESS(clk,resetb)
  203.         VARIABLE cnt:INTEGER;
  204.   BEGIN
  205.         IF resetb='1' THEN
  206.                 cnt:=0; bclk<='0';   
  207.    ELSIF RISING_EDGE(clk) THEN
  208.       IF cnt>=framlenr THEN
  209.                         cnt:=0; bclk<='0';   
  210.            ELSIF cnt>=framlenr/2 THEN  
  211.                         cnt:=cnt+1;bclk<='1';
  212.            ELSE cnt:=cnt+1; bclk<='0';
  213.            END IF;
  214.     END IF;
  215.      END PROCESS;
  216.   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]
这段代码能够实现功能吗,不能改怎么改呢,我调试了好久,还是不行
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。