⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.v

📁 FPGA上实现UART串口原程序
💻 V
字号:
module uart(rx,tx,rxdata,txdata,ce,rxok,txok,sysclk,reset);
input sysclk,reset,txok;
input rx;
output tx,rxok;
output[7:0] rxdata;
output[3:0] ce;
input[7:0] txdata;

reg rxok;
//reg[7:0] data;
reg[3:0] ce;
wire[9:0] tx_buf;

parameter  Baud1=4800;    //波特率设置 650
parameter  Baud2=9600;    //*16=325
parameter  Baud3=19200;  //*16=162
parameter  Baud4=57600;  //*16=53
parameter  Baud5=115200; //*16=26
parameter  data_n=8;        //8 bit 数据

reg[16:0] count;
reg[10:0] Baudcount;
reg[4:0]  tx_clk;
reg[8:0]  Buffer;
reg[3:0]  rx_databit,tx_databit;
reg sample_16x;             //采样时钟
reg rx1,rx2;
reg start,stop;
reg rxdatastart;
reg txok1,txok2,txstop,txstart;
reg rxrun,txrun,tx_tx;    

assign  Baudrate=Baud2;
assign  Samplerate=325;

always @(posedge sysclk)
begin
  if (reset==0)
   begin
    count=0;
    sample_16x=0;
    end
    else    begin
    sample_16x=0;
    count=count+1;
    if(count==Samplerate)
      begin
      count=0;
      sample_16x=1;
      end
   end
end

always @(posedge sysclk)         //检测起始边沿
begin
  if(reset==0)
     begin
     rx1<=0;
     rx2<=0;
     start=0;
     end
   else  begin
     rx1<=rx;
     rx2<=rx1;
     if(!rx1&rx2&stop)
      start=1;
     if(rxrun)
      start=0;
     end
end

always @(posedge sample_16x)    // 16倍时钟采样接收
 begin
 if (reset==0)
  begin
    Baudcount=0;
   rxrun=0;
    stop=1;
  end
  else  begin
    if(start)                     //检测到起始边沿,启动接收程序
      begin
       rxrun=1;
       stop=0;
       rxdatastart=0;
       rxok=0;
       rx_databit<=0;
       end
    if(rxrun)
    begin
       Baudcount=Baudcount+1;
       if(Baudcount[3]==1&rxdatastart==0) //8次后采集起始位
         begin
         rxdatastart=1;   
         Baudcount=0;     
         end 
       if(Baudcount[3]&Baudcount[2]&Baudcount[1]&Baudcount[0]==1)
        begin
         Buffer[rx_databit]=rx;          //每16次采一次数据
         rx_databit<=rx_databit+1;
         if(rx_databit==8&Buffer[rx_databit]==1)  //共采9次,最后一次位停止位
           begin
           rxrun=0;                       //结束接收程序
           Baudcount=0;
           rxok=1;                        //数据就绪
           stop=1;
           end      
        end
    end
  end
 end 
 
  assign   rxdata=rxok?Buffer:rxdata; 
///发送数据  
  always @(posedge sample_16x)  //发送时钟
  begin
   if(reset==0)
    tx_clk<=0;
    else
    tx_clk<=tx_clk+1;
  end
  
 always @(posedge sysclk)        //检测数据就绪
 begin
  if(reset==0)
  begin
  txok1<=0;
  txok2<=0;
  end 
 else  begin
  txok1<=txok;
  txok2<=txok1;
  if(!txok1&txok2&txstop)
    txstart=1;
   if(txrun)
    txstart=0;
   end
end
  
  always @(posedge tx_clk[4])  //发送
  begin
   if(reset==0)
     begin
     //tx_startbit=1;
     txstop=1;
     txrun=0;
     tx_databit<=0;
     end
     else begin
   if(txstart&!txrun)
    txrun=1;
    if(txrun)
    begin
     tx_tx=tx_buf[tx_databit]; // 依次发送
     tx_databit<=tx_databit+1;
     if(tx_databit==10)
      begin
      txstop=1;
      txrun=0;
     end
   end
 end
end          
    
 assign  tx_buf={0,txdata,1};    //起始位 数据 停止位
 assign  tx=txok?tx_tx:1;
         
       
       
        
endmodule
     
   
  
    
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -