3124|0

6892

帖子

0

TA的资源

五彩晶圆(高级)

楼主
 

【FPGA问题讨论】串口接收失步 [复制链接]

VHDL 编写的2M 波特率串口接收模块,在串口接收信号时,正常工作后,只要串口接收争取后,程序运行没问题。但重复复位或多次上电,经常有串口不能正常工作的现象?我是通过对串口接收的正确的标识信号进行翻转驱动LED灯来指示的。结果经常出现上面的问题,目前待查原因,请高手分析问题,下面是串口接收的程序代码!

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

--LIBRARY ALTERA;
--USE ALTERA.MAXPLUS2.ALL;

LIBRARY LPM;
USE LPM.LPM_COMPONENTS.ALL;
-- ****************************************************************************

ENTITY Rx_Com IS
GENERIC (Rx_D_Width : POSITIVE := 8;Check:STRING:="Even";Check_En:STRING:="En");
 PORT(
 
   Clk       : IN  STD_LOGIC;        
   Rst       : IN  STD_LOGIC; 
          
   Rx_Clk      : IN  STD_LOGIC;     -----------串口接收时钟
   Rx        : IN   STD_LOGIC;      -----------串口接收数据         
   Dout       : OUT  STD_LOGIC_VECTOR(Rx_D_Width-1 DOWNTO 0);   -------------串口接收数据输出           
   Rxrdy      : OUT  STD_LOGIC;                              -------------串口接收数据有效使能
  
   Rxerr      : OUT  STD_LOGIC;                              -------------串口接收错误标志
   Clrdiv      : OUT  STD_LOGIC                             -------------串口接收时钟产生使能标志
      
  ); 
END Rx_Com;
-- ****************************************************************************
ARCHITECTURE Arch_Rx_Com OF Rx_Com IS

CONSTANT    Bit_Valid                   : STD_LOGIC:='1';
CONSTANT    Bit_Invalid                  : STD_LOGIC:='0';
----------------接收状态机--------------------------------------------------------------------------------
TYPE       State                IS   (Idle,Start_rx,Edge_Rx,Shift_Rx,Stop_Rx,Rx_Ovf,Rx_Crc);      
SIGNAL    Rxfsm                 :   State;  

SIGNAL     Rx_Reg             :   STD_LOGIC_VECTOR(Rx_D_Width DOWNTO 0);     --------------接收数据寄存器
SIGNAL    Rxbitcnt            :   INTEGER RANGE 0 TO (Rx_D_Width+3);         --------------接收计数器
SIGNAL    Rxrdyi,Clrdivi         :   STD_LOGIC;                              --------------中间寄存器
    
SIGNAL     Rx1,Rx2,Rx3,Rx4         :   STD_LOGIC;
SIGNAL      Rxrdyi_Buf          :    STD_LOGIC;
SIGNAL      Rx_Clk_Reg          :     STD_LOGIC_VECTOR(1 DOWNTO 0);                     
BEGIN
-------------------------------------------------------------------------------


PROCESS(Clk,Rst)                  
BEGIN
IF(Rst=Bit_Valid) THEN
Rxrdy<=Bit_Invalid;
Clrdiv<=Bit_Invalid;
ELSIF Clk'EVENT and Clk=Bit_Valid THEN
 Rxrdyi_Buf<=Rxrdyi;
 IF (Rxrdyi_Buf=Bit_Valid) AND (Rxrdyi=Bit_Invalid) THEN
    Rxrdy <= Bit_Valid;
 ELSE
    Rxrdy <= Bit_Invalid;
 END IF;
 Clrdiv <= Clrdivi;
 -----------------------------------
    IF (Rx_Clk='1') THEN
        Rx_Clk_Reg<="01";
    ELSE
        Rx_Clk_Reg<="10";
    END IF;
 
END IF;
END PROCESS;                     

PROCESS(Rst,Clk)
VARIABLE Rxbitcnt : INTEGER RANGE 0 TO (Rx_D_Width+3);
VARIABLE Highcnt    : INTEGER RANGE 0 TO 20;
VARIABLE     Par               :  STD_LOGIC;
VARIABLE     Par_Reg ,Rx4_Reg           :  STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
 IF Rst=Bit_Valid THEN
  Rx_Reg <= (OTHERS=> Bit_Invalid);  
  Dout <= (OTHERS=> Bit_Invalid);
  Rxbitcnt := 0;
  Rxfsm <= Idle;               
  Rxrdyi <= Bit_Invalid;
  Clrdivi <= Bit_Invalid;
  Rxerr <= Bit_Invalid;
  Par   := Bit_Invalid;
     Rx1<=Bit_Valid;
     Rx2<=Bit_Valid;
     Rx3<=Bit_Valid;
     Rx4<=Bit_Valid;
     Highcnt:=0;
 ELSIF Clk'EVENT and Clk=Bit_Valid THEN
      Rx1<=rx;                                                                                                      
      Rx2<=Rx1;
      Rx3<=Rx2;
      Rx4<=Rx3;
      
       
                    
 -- CASE Rxfsm IS
  
 -- WHEN Idle =>  
 IF (Rxfsm=Idle) THEN                   
   Par:=Bit_Invalid;
   Rxbitcnt := 0;
   Rxrdyi <= Bit_Invalid; 
   Clrdivi <= Bit_Valid; 
   
   IF (Rx4 = Bit_Invalid) THEN
    Rxfsm <= start_rx;
    Clrdivi <= Bit_Invalid; 
                    
   END IF;
   
    
   
   
 -- WHEN start_rx =>  
 ELSIF   (Rxfsm=start_rx) THEN                 
   
   IF Rx_Clk = Bit_Valid THEN
   --  IF Rx_Clk_Reg="01" THEN
    IF Rx4 = Bit_Valid THEN               
     Rxfsm <= Rx_Ovf;
    ELSE
     Rxfsm <= Edge_Rx;
    END IF;
   END IF;
  
 -- WHEN Edge_Rx =>
  ELSIF   (Rxfsm=Edge_Rx) THEN  
   
   IF Rx_Clk = Bit_Valid THEN
   --  IF Rx_Clk_Reg="01" THEN
    Rxfsm <= Shift_Rx;
      IF(Check_En="En")THEN
    IF Rxbitcnt = Rx_D_Width+1 THEN    
     Rxfsm <= Stop_Rx;
    ELSE
     Rxfsm <= Shift_Rx;
    END IF;
      ELSE
       IF Rxbitcnt = Rx_D_Width THEN  
     Rxfsm <= Stop_Rx;
    ELSE
     Rxfsm <= Shift_Rx;
    END IF;
      END IF;
   END IF;
       
  --WHEN Shift_Rx => 
  ELSIF   (Rxfsm=Shift_Rx) THEN             
   
   IF Rx_Clk = Bit_Valid THEN
   --  IF Rx_Clk_Reg="01" THEN
    Rxbitcnt := Rxbitcnt + 1;
    IF (Rxbitcnt=1) THEN
        Par:=Rx4;  
       END IF;
    Rx_Reg <= Rx4 & Rx_Reg(Rx_Reg'high DOWNTO 1);                                                                   
    Rxfsm <= Edge_Rx;
    
   END IF;
  
  --WHEN Stop_Rx =>  
  ELSIF   (Rxfsm=Stop_Rx) THEN                
   
   IF Rx_Clk = Bit_Valid THEN
   
       IF (Rx4 = Bit_Valid) THEN                  
      Rxfsm <= Rx_Crc;     
             ELSE                 
      Rxfsm <= Rx_Ovf; 
           END IF;    
  END IF;                  
 -- WHEN Rx_Ovf =>
     ELSIF   (Rxfsm=Rx_Crc) THEN
         FOR i IN 1 TO  (Rx_D_Width) LOOP
            Par:=Par XOR  Rx_Reg(i);
         END LOOP;
         IF ((Check="Even") AND (Par='0')) OR ((Check="Odd") AND (Par='1')) THEN 
            Rxrdyi <= Bit_Valid; 
         ELSE
            Rxrdyi <= Bit_Invalid; 
         END IF; 
         Dout <=Rx_Reg((Rx_D_Width-1) DOWNTO 0); 
      --//   Rxrdyi <= Bit_Valid;      
         Rxfsm<=Rx_Ovf ;    
  ELSIF   (Rxfsm=Rx_Ovf) THEN 
         Rxrdyi <= Bit_Invalid;             
  -- Rxerr <= Bit_Valid;
   IF (Highcnt=15) then
              Highcnt:=0;
              Rxfsm <= Idle; 
   ELSIF Rx4 = Bit_Valid THEN
     Highcnt:= Highcnt+1;           
   END IF;
   
       
 -- WHEN OTHERS =>
    ELSE
   Rxfsm <= Idle;
   
  --END CASE;
    END IF;
  
  
  
 END IF;
END PROCESS;

 


  

END Arch_Rx_Com;

此帖出自FPGA/CPLD论坛
点赞 关注
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表