FPGA(verilog) 最简易的RS232 建模四 (将接收到的数据返回)非常简易--高效--解决任意连续数据问题

/*************************************************************************************
此程序实现了串口的接收并将接收的发送--经过测试--完全正常工作--效率非常高
编程目的:简化各种RS232繁琐程序,在以后的工程中作为模块使用
程序优点:简易--明了---高效
程序缺点:暂时无--经过各种测试--很完美---可以发任意多的连续数据

--FPGA全局都使用clK系统时钟为50MHZ   先发低位后发高位 先接收地位后接收高位
--9600波特---8位数据--1位开始--1位结束--无停止位
*******************************************************************************************/
module uart_tx
 (
    input clk,rst_n,
 input  UART_RXD,
 output reg UART_TXD,
 output  [7:0] led
 );
 assign led= rx_data;
 reg [3:0]state;
 reg [30:0] count;
 reg [7:0] rx_data;
 reg a,b;
/****************************************************************************************************
接收程序---下降沿检测---数据中间采样---将接收到的数据返回发送使能的开关---
--使能有效一个周期--可能会在发送过程中出现使能---使得发送模块检测不到使能--致使错过丢失数据
--9600波特---8位数据--1位开始--1位结束--无停止位
*****************************************************************************************************/
always @ (posedge clk)
begin
if(!rst_n) begin rx_data<=8'h05;count<=0;tx_data<=8'ha5;end
else begin
    case (state)
 0:begin en_tx=0;a<=UART_RXD;b<=a; if(b && !a) state<=1;else state<=0;end //当无数据接收完成时关闭,使能,下降沿采样
 1:if(count==2603) begin if(UART_RXD==0)state<=2;else state<=0;count<=0;end //采集开始位 0电平的中点
   else              begin state<=1;count<=count+1;end  
 2:if(count==5208) begin state<=3;count<=0;rx_data[0]<=UART_RXD;end         //计数到数据位的中点
   else              begin state<=2;count<=count+1;end
 3:if(count==5208) begin state<=4;count<=0;rx_data[1]<=UART_RXD;end
   else              begin state<=3;count<=count+1;end 
 4:if(count==5208) begin state<=5;count<=0;rx_data[2]<=UART_RXD;end
   else              begin state<=4;count<=count+1;end 
 5:if(count==5208) begin state<=6;count<=0;rx_data[3]<=UART_RXD;end
   else              begin state<=5;count<=count+1;end  
 6:if(count==5208) begin state<=7;count<=0;rx_data[4]<=UART_RXD;end
   else              begin state<=6;count<=count+1;end
 7:if(count==5208) begin state<=8;count<=0;rx_data[5]<=UART_RXD;end
   else              begin state<=7;count<=count+1;end 
 8:if(count==5208) begin state<=9;count<=0;rx_data[6]<=UART_RXD;end
   else              begin state<=8;count<=count+1;end 
 9:if(count==5208) begin state<=10;count<=0;rx_data[7]<=UART_RXD;end
   else              begin state<=9;count<=count+1;end 
 10:if(count==5208)begin state<=11;count<=0;     end                            //采集结束位
   else              begin tx_data<=rx_data;en_tx=1;state<=10;count<=count+1;     end //提前一个周期就使能发送,解决一起发三个数据返回时,丢掉中间的现象
 11:begin tx_data<=rx_data;en_tx=1;state=0;end                 //获取接收到的数据返回给发送,并且使能发送,回状态一,检测下降沿
 default state=0;
 endcase
    end
end
/****************************************************************************************************
发送程序---上升沿发送---发完一次后在状态10等待下一次发送任务----9600波特---8位数据--1位开始--1位结束--无停止位
*****************************************************************************************************/
 reg [3:0] state2;
 reg [30:0] count2;
 reg [7:0] tx_data;
 reg en_tx;
always @ (posedge clk)
begin
if(!rst_n) begin UART_TXD=0;end
else begin

 case (state2)
 0:if(count2==5208) begin state2<=1;count2<=0;end
   else             begin state2<=0;count2<=count2+1;UART_TXD<=0;      end //开始位
 1:if(count2==5208) begin state2<=2;count2<=0;end
   else             begin state2<=1;count2<=count2+1;UART_TXD<=tx_data[0];end  
 2:if(count2==5208) begin state2<=3;count2<=0;end
   else             begin state2<=2;count2<=count2+1;UART_TXD<=tx_data[1];end
 3:if(count2==5208) begin state2<=4;count2<=0;end
   else             begin state2<=3;count2<=count2+1;UART_TXD<=tx_data[2];end 
 4:if(count2==5208) begin state2<=5;count2<=0;end
   else             begin state2<=4;count2<=count2+1;UART_TXD<=tx_data[3];end 
 5:if(count2==5208) begin state2<=6;count2<=0;end
   else             begin state2<=5;count2<=count2+1;UART_TXD<=tx_data[4];end  
 6:if(count2==5208) begin state2<=7;count2<=0;end
   else             begin state2<=6;count2<=count2+1;UART_TXD<=tx_data[5];end
 7:if(count2==5208) begin state2<=8;count2<=0;end
   else             begin state2<=7;count2<=count2+1;UART_TXD<=tx_data[6];end 
 8:if(count2==5208) begin state2<=9;count2<=0;end
   else             begin state2<=8;count2<=count2+1;UART_TXD<=tx_data[7];end 
 9:if(count2==5208) begin state2<=10;count2<=0;end
   else             begin state2<=9;count2<=count2+1;UART_TXD<=1;      end //结束位
 10:begin if(en_tx==1)state2<=0;else state2<=10;end //发完一次后在这等使能进行发送第二次
 default state2<=0;
 endcase
 
 end
end
endmodule

你可能感兴趣的:(Verilog)