串口异步串行通信,异步串行是指UART(UniversalAsynchronousReceiver/Transmitter),通用异步接收/发送。UART是一个并行输入成为串行输出的芯片,通常集成在主板上。UART包含TTL电平的串口和RS232电平的串口。TTL电平是3.3V的,而RS232是负逻辑电平,它定义+5~+12V为低电平,而-12~-5V为高电平,MDS2710、MDSSD4、EL805等是RS232接口,EL806有TTL接口。串行接口按电气标准及协议来分包括RS-232-C、RS-422、RS485等。RS-232-C、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。开发板的串口通信通过USB转串口方式,是解决很多人电脑不带串口接口的问题,所以这里不涉及到电气协议标准,用法和TTL电平串口类似。FPGA芯片使用2个IO口和USB转串口芯片CP2102相连。
  串口接收模块是个参数化可配置模块,参数“CLK_FRE”定义接收模块的系统时钟频率,单位是 Mhz,参数“BAUD_RATE”是波特率。接收状态机状态转换图如下:“S_IDLE”状态为空闲状态,上电后进入“S_IDLE”,如果信号“rx_pin”有下降沿,我们认为是串口的起始位,进入状态“S_START” ,等一个 BIT 时间起始位结束后进入数据位接收状态“S_REC_BYTE” ,本实验中数据位设计是 8 位,接收完成以后进入“S_STOP”状态,在“S_STOP”没有等待一个 BIT 周期, 只等待了半个 BIT 时间,这是因为如果等待了一个周期,有可能会错过下一个数据的起始位判断,最后进入“S_DATA”状态,将接收到的数据送到其他模块。 在这个模块我们提一点:为了满足采样定理,在接受数据时每个数据都在波特率计数器的时间中点进行采样,以避免数据出错的情况:
    1.png

  
//////////////////////////////////////////////////////////////////////////////////
  • //                                                                              //
  • //                                                                              //
  • //  Author: lhj                                                               //
  • //                                                                             //
  • //          ALINX(shanghai) Technology Co.,Ltd                                  //
  • //          heijin                                                              //
  • //     WEB: http://www.alinx.cn/                                                //
  • //     BBS: http://www.heijin.org/                                              //
  • //                                                                              //
  • //////////////////////////////////////////////////////////////////////////////////
  • //                                                                              //
  • // Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd                        //
  • //                    All rights reserved                                       //
  • //                                                                              //
  • // This source file may be used and distributed without restriction provided    //
  • // that this copyright statement is not removed from the file and that any      //
  • // derivative work contains the original copyright notice and the associated    //
  • // disclaimer.                                                                  //
  • //                                                                              //
  • //////////////////////////////////////////////////////////////////////////////////
  • //================================================================================
  • //  Revision History:
  • //  Date          By            Revision    Change Description
  • //--------------------------------------------------------------------------------
  • //2018/1/3                    1.0          Original
  • //*******************************************************************************/
  • module uart_test(
  • input                           sys_clk,
  • input                           rst_n,
  • input                           uart_rx,
  • output                          uart_tx
  • );
  • parameter                      CLK_FRE = 50;//Mhz
  • localparam                       IDLE =  0;
  • localparam                       SEND =  1;   //send HELLO ALINX\r\n
  • localparam                       WAIT =  2;   //wait 1 second and send uart received data
  • reg[7:0]                         tx_data;
  • reg[7:0]                         tx_str/*synthesis syn_keep=1*/;
  • reg                              tx_data_valid;
  • wire                             tx_data_ready;
  • reg[7:0]                         tx_cnt;
  • wire[7:0]                        rx_data;
  • wire                             rx_data_valid;
  • wire                             rx_data_ready;
  • reg[31:0]                        wait_cnt;
  • reg[3:0]                         state;
  • assign rx_data_ready = 1'b1;//always can receive data,
  •                                                         //if HELLO ALINX\r\n is being sent, the received data is discarded
  • always@(posedge sys_clk or negedge rst_n)
  • begin
  •         if(rst_n == 1'b0)
  •         begin
  •                 wait_cnt <= 32'd0;
  •                 tx_data <= 8'd0;
  •                 state <= IDLE;
  •                 tx_cnt <= 8'd0;
  •                 tx_data_valid <= 1'b0;
  •         end
  •         else
  •         case(state)
  •                 IDLE:
  •                         state <= SEND;
  •                 SEND:
  •                 begin
  •                         wait_cnt <= 32'd0;
  •                         tx_data <= tx_str;
  •                         if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1 && tx_cnt < 8'd12)//Send 12 bytes data
  •                         begin
  •                                 tx_cnt <= tx_cnt + 8'd1; //Send data counter
  •                         end
  •                         else if(tx_data_valid && tx_data_ready)//last byte sent is complete
  •                         begin
  •                                 tx_cnt <= 8'd0;
  •                                 tx_data_valid <= 1'b0;
  •                                 state <= WAIT;
  •                         end
  •                         else if(~tx_data_valid)
  •                         begin
  •                                 tx_data_valid <= 1'b1;
  •                         end
  •                 end
  •                 WAIT:
  •                 begin
  •                         wait_cnt <= wait_cnt + 32'd1;
  •                         if(rx_data_valid == 1'b1)
  •                         begin
  •                                 tx_data_valid <= 1'b1;
  •                                 tx_data <= rx_data;   // send uart received data
  •                         end
  •                         else if(tx_data_valid && tx_data_ready)
  •                         begin
  •                                 tx_data_valid <= 1'b0;
  •                         end
  •                         else if(wait_cnt >= CLK_FRE * 1000000) // wait for 1 second
  •                                 state <= SEND;
  •                 end
  •                 default:
  •                         state <= IDLE;
  •         endcase
  • end
  • //combinational logic
  • //Send "HELLO ALINX\r\n"
  • always@(*)
  • begin
  •         case(tx_cnt)
  •                 8'd0 :  tx_str <= "H";
  •                 8'd1 :  tx_str <= "E";
  •                 8'd2 :  tx_str <= "L";
  •                 8'd3 :  tx_str <= "L";
  •                 8'd4 :  tx_str <= "O";
  •                 8'd5 :  tx_str <= " ";
  •                 8'd6 :  tx_str <= "A";
  •                 8'd7 :  tx_str <= "L";
  •                 8'd8 :  tx_str <= "I";
  •                 8'd9 :  tx_str <= "N";
  •                 8'd10:  tx_str <= "X";
  •            // 8'd11:  tx_str <= "\r";
  •         8'd11:  tx_str <= 8'h0d;
  •                 8'd12:  tx_str <= "\n";
  •                 default:tx_str <= 8'd0;
  •         endcase
  • end
  • uart_rx#
  • (
  •         .CLK_FRE(CLK_FRE),
  •         .BAUD_RATE(115200)
  • ) uart_rx_inst
  • (
  •         .clk                        (sys_clk                  ),
  •         .rst_n                      (rst_n                    ),
  •         .rx_data                    (rx_data                  ),
  •         .rx_data_valid              (rx_data_valid            ),
  •         .rx_data_ready              (rx_data_ready            ),
  •         .rx_pin                     (uart_rx                  )
  • );
  • uart_tx#
  • (
  •         .CLK_FRE(CLK_FRE),
  •         .BAUD_RATE(115200)
  • ) uart_tx_inst
  • (
  •         .clk                        (sys_clk                  ),
  •         .rst_n                      (rst_n                    ),
  •         .tx_data                    (tx_data                  ),
  •         .tx_data_valid              (tx_data_valid            ),
  •         .tx_data_ready              (tx_data_ready            ),
  •         .tx_pin                     (uart_tx                  )
  • );
  • endmodule
  • 复制代码
    仿真图   
    2.png