• Verilog之串口(UART)通信


    0:起始位,低电平;1~8:数据位;9:校验位,高电平;10:停止位,高电平。

    波特率 “9600bps”表示每秒可以传输9600位。  

    波特率定时计数器由时钟频率除以波特率。

    采集1~8位,忽略0、9、10位。

    发送“0、8位数据、1、1”

    串口传输数据,从最低位开始,到最高位结束。

    串口发送:

    module tx_bps_module            
    (            
        CLK, RSTn,            
         Count_Sig,         
         BPS_CLK        
    );            
                
        input CLK;            
         input RSTn;        
         input Count_Sig;        
         output BPS_CLK;        
                 
         /***************************/        
                 
         reg [12:0]Count_BPS;        
                 
         always @ ( posedge CLK or negedge RSTn )        
            if( !RSTn )        
                 Count_BPS <= 13'd0;    
             else if( Count_BPS == 13'd5207 )    
                 Count_BPS <= 13'd0;    
             else if( Count_Sig )    
                 Count_BPS <= Count_BPS + 1'b1;    
             else    
                 Count_BPS <= 13'd0;    
                  
         /********************************/        
                
        assign BPS_CLK = ( Count_BPS == 13'd2604 ) ? 1'b1 : 1'b0;            
                
        /*********************************/            
                
    endmodule            
    module tx_control_module                                
    (                                
        CLK, RSTn,                                
         TX_En_Sig, TX_Data, BPS_CLK,                             
        TX_Done_Sig, TX_Pin_Out                                
                                     
    );                                
                                    
        input CLK;                                
         input RSTn;                            
                                     
         input TX_En_Sig;                            
         input [7:0]TX_Data;                            
         input BPS_CLK;                            
                                     
         output TX_Done_Sig;                            
         output TX_Pin_Out;                            
                                     
         /********************************************************/                            
                                    
         reg [3:0]i;                            
         reg rTX;                            
         reg isDone;                            
                                    
         always @ ( posedge CLK or negedge RSTn )                            
             if( !RSTn )                            
                  begin                        
                      i <= 4'd0;                        
                         rTX <= 1'b1;            
                         isDone     <= 1'b0;        
                    end                
              else if( TX_En_Sig )                        
                  case ( i )                        
                                    
                       4'd0 :                    
                         if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b0; end            
                                     
                         4'd1, 4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 :            
                         if( BPS_CLK ) begin i <= i + 1'b1; rTX <= TX_Data[ i - 1 ]; end            
                                     
                         4'd9 :            
                         if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end            
                                      
                         4'd10 :            
                         if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end            
                                     
                         4'd11 :            
                         if( BPS_CLK ) begin i <= i + 1'b1; isDone <= 1'b1; end            
                                     
                         4'd12 :            
                         begin i <= 4'd0; isDone <= 1'b0; end            
                                     
                    endcase                
                                    
        /********************************************************/                                
                                     
         assign TX_Pin_Out = rTX;                            
         assign TX_Done_Sig = isDone;                            
                                     
         /*********************************************************/                            
                                     
    endmodule                                
    module tx_module            
    (            
        CLK, RSTn,            
         TX_Data, TX_En_Sig,        
         TX_Done_Sig, TX_Pin_Out        
    );            
                 
         input CLK;            
          input RSTn;        
          input [7:0]TX_Data;        
          input TX_En_Sig;        
          output TX_Done_Sig;        
          output TX_Pin_Out;        
                  
                  
          /********************************/        
                  
          wire BPS_CLK;        
                  
          tx_bps_module U1        
          (        
              .CLK( CLK ),        
                .RSTn( RSTn ),
                .Count_Sig( TX_En_Sig ),    // input - from U2
                .BPS_CLK( BPS_CLK )         // output - to U2
          );        
                  
          /*********************************/        
                  
          tx_control_module U2        
          (        
              .CLK( CLK ),        
                .RSTn( RSTn ),
                .TX_En_Sig( TX_En_Sig ),    // input - from top
                .TX_Data( TX_Data ),        // input - from top
                .BPS_CLK( BPS_CLK ),        // input - from U2
                .TX_Done_Sig( TX_Done_Sig ),  // output - to top
                .TX_Pin_Out( TX_Pin_Out )     // output - to top
          );        
                  
          /***********************************/        
                
    endmodule            

    串口接受

    module detect_module                     
    (                    
        CLK, RSTn,                    
         RX_Pin_In,                
         H2L_Sig                
    );                    
        input CLK;                    
         input RSTn;                
         input RX_Pin_In;                
         output H2L_Sig;                
                         
         /******************************/                
                         
         reg H2L_F1;                
         reg H2L_F2;                
                         
         always @ ( posedge CLK or negedge RSTn )                
             if( !RSTn )                
                  begin            
                        H2L_F1 <= 1'b1;    
                         H2L_F2 <= 1'b1;
                    end    
              else            
                  begin            
                        H2L_F1 <= RX_Pin_In;    
                         H2L_F2 <= H2L_F1;
                    end    
                        
        /***************************************/                
                        
        assign H2L_Sig = H2L_F2 & !H2L_F1;                
                        
        /***************************************/                
                        
    endmodule                    
    module rx_control_module                        
    (                        
        CLK, RSTn,                        
         H2L_Sig, RX_Pin_In, BPS_CLK, RX_En_Sig,                    
        Count_Sig, RX_Data, RX_Done_Sig                        
                             
    );                        
                            
        input CLK;                        
         input RSTn;                    
                             
         input H2L_Sig;                    
         input RX_En_Sig;                    
         input RX_Pin_In;                    
         input BPS_CLK;                    
                             
         output Count_Sig;                    
         output [7:0]RX_Data;                    
         output RX_Done_Sig;                    
                             
                             
         /********************************************************/                    
                            
         reg [3:0]i;                    
         reg [7:0]rData;                    
         reg isCount;                    
         reg isDone;                    
                            
         always @ ( posedge CLK or negedge RSTn )                    
             if( !RSTn )                    
                  begin                 
                      i <= 4'd0;                
                         rData <= 8'd0;    
                         isCount <= 1'b0;    
                         isDone <= 1'b0;     
                    end        
              else if( RX_En_Sig )                
                  case ( i )                
                            
                       4'd0 :            
                         if( H2L_Sig ) begin i <= i + 1'b1; isCount <= 1'b1; end         /*进入第0位,同时驱动bps_module开始计数。又以bps_module驱动状态1~11*/
                             
                         4'd1 :     
                         if( BPS_CLK ) begin i <= i + 1'b1; end                          /*第0位中部,BPS_CLK发出第一个脉冲,忽略第0位*/
                             
                         4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8, 4'd9 :    
                         if( BPS_CLK ) begin i <= i + 1'b1; rData[ i - 2 ] <= RX_Pin_In; end    
                             
                         4'd10 :    
                         if( BPS_CLK ) begin i <= i + 1'b1; end    
                             
                         4'd11 :    
                         if( BPS_CLK ) begin i <= i + 1'b1; end    
                             
                         4'd12 :    
                         begin i <= i + 1'b1; isDone <= 1'b1; isCount <= 1'b0; end    
                             
                         4'd13 :    
                         begin i <= 4'd0; isDone <= 1'b0; end    
                             
                    endcase        
                            
        /********************************************************/                        
                             
         assign Count_Sig = isCount;                    
         assign RX_Data = rData;                    
         assign RX_Done_Sig = isDone;                    
                             
                             
         /*********************************************************/                    
                             
    endmodule                        
    module rx_bps_module            
    (            
        CLK, RSTn,            
         Count_Sig,         
         BPS_CLK        
    );            
                
        input CLK;            
         input RSTn;        
         input Count_Sig;        
         output BPS_CLK;        
                 
         /***************************/        
                 
         reg [12:0]Count_BPS;        
                 
         always @ ( posedge CLK or negedge RSTn )        
            if( !RSTn )        
                 Count_BPS <= 13'd0;    
             else if( Count_BPS == 13'd5207 )    
                 Count_BPS <= 13'd0;    
             else if( Count_Sig )    
                 Count_BPS <= Count_BPS + 1'b1;    
             else    
                 Count_BPS <= 13'd0;    
                  
         /********************************/        
                
        assign BPS_CLK = ( Count_BPS == 12'd2604 ) ? 1'b1 : 1'b0;            /*周期中间开始采集数据*/
                
        /*********************************/            
                
    endmodule            
    module rx_module        
    (        
        CLK, RSTn,        
        RX_Pin_In, RX_En_Sig,        
         RX_Done_Sig, RX_Data    
    );        
            
        input CLK;        
         input RSTn;    
             
         input RX_Pin_In;    
         input RX_En_Sig;    
             
         output [7:0]RX_Data;    
         output RX_Done_Sig;    
             
             
         /**********************************/    
             
         wire H2L_Sig;    
             
         detect_module U1    
         (    
             .CLK( CLK ),    
              .RSTn( RSTn ),
              .RX_Pin_In( RX_Pin_In ),    // input - from top
              .H2L_Sig( H2L_Sig )         // output - to U3
         );    
             
         /**********************************/    
             
         wire BPS_CLK;    
             
         rx_bps_module U2    
         (    
             .CLK( CLK ),    
              .RSTn( RSTn ),
              .Count_Sig( Count_Sig ),   // input - from U3
              .BPS_CLK( BPS_CLK )        // output - to U3
         );    
             
         /**********************************/    
             
         wire Count_Sig;    
             
         rx_control_module U3    
         (    
             .CLK( CLK ),    
              .RSTn( RSTn ),
              
              .H2L_Sig( H2L_Sig ),      // input - from U1
              .RX_En_Sig( RX_En_Sig ),  // input - from top
              .RX_Pin_In( RX_Pin_In ),  // input - from top
              .BPS_CLK( BPS_CLK ),      // input - from U2
              
              .Count_Sig( Count_Sig ),    // output - to U2
              .RX_Data( RX_Data ),        // output - to top
              .RX_Done_Sig( RX_Done_Sig ) // output - to top
              
         );    
             
         /************************************/    
             
            
    endmodule        
  • 相关阅读:
    centos 8 yum 重装
    Flask 和 Vue.js 开发及整合部署实例
    git报错fatal: unable to access 'https://****.com/c*****5/ecmall.git/': Could not resolve host: gitlab.***k.com
    CentOs服务器下安装两个个MySql数据库踩坑日记
    10-网络芯片CH395Q学习开发-模块使用Socket0作为UDP广播通信
    9-网络芯片CH395Q学习开发-模块使用Socket0作为UDP和电脑上位机UDP局域网通信
    8-网络芯片CH395Q学习开发-模块使用Socket0作为TCP服务器和电脑上位机TCP客户端局域网通信(单连接和多连接)
    7-网络芯片CH395Q学习开发-模块使用Socket0-5作为6路TCP客户端和电脑上位机TCP服务器局域网通信(Socket缓存区配置)
    6-网络芯片CH395Q学习开发-模块使用Socket0-3作为4路TCP客户端和电脑上位机TCP服务器局域网通信
    5-网络芯片CH395Q学习开发-模块使用Socket0作为TCP客户端和电脑上位机TCP服务器局域网通信
  • 原文地址:https://www.cnblogs.com/shaogang/p/4107818.html
Copyright © 2020-2023  润新知