核心内容摘要
探索日本的极致诱惑:一场身临其境的感官盛宴
fpga verilog 实现串口收发通信上板可直接通信 支持xilinx和altera这玩意儿搞过FPGA的都知道串口通信算是基本功里的战斗机了。
今天咱们直接撸代码不废话硬件原理反正就是搞个能收能发的模块Xilinx的板子和Altera的板子通吃。
先看波特率生成——这玩意是串口的命门。
拿个50MHz时钟为例要搞个115200的波特率分频系数这么算localparam CLK_FREQ 50_000_000; localparam BAUD_RATE 115200; localparam BAUD_COUNT CLK_FREQ / BAUD_RATE; reg [15:0] baud_counter; always (posedge clk) begin if(baud_counter BAUD_COUNT-
begin baud_tick 1b1; baud_counter 0; end else begin baud_tick 1b0; baud_counter baud_counter 1; end end重点在分频系数别算错尤其是Altera的Cyclone系列时钟架构和Xilinx不一样的时候实测发现有些板子需要把分频系数减1才能准确。
发送模块的核心是状态机直接上硬菜reg [3:0] tx_state; reg [7:0] tx_data; always (posedge clk) begin case(tx_state) 0: if(tx_start) begin tx_reg 0; //起始位 tx_state 1; bit_count 0; end 1: if(baud_tick) begin tx_reg tx_data[bit_count]; bit_count bit_count 1; tx_state (bit_count
? 2 : 1; end 2: if(baud_tick) begin tx_reg 1; //停止位 tx_state 3; end 3: begin tx_done 1b1; tx_state 0; end endcase end注意这里用了非标准写法状态直接用数字表示老司机都懂——状态少的时候这么写更直观。
停止位搞个
5位的骚操作别老老实实1位最稳妥。
fpga verilog 实现串口收发通信上板可直接通信 支持xilinx和altera接收模块的玄学在于抗干扰reg [7:0] rx_buffer; reg [2:0] sample_counter; always (posedge clk) begin if(rx_sync) begin //消抖后的信号 case(rx_state) 0: if(!rx_sync) begin //检测起始位 sample_counter 0; rx_state 1; end 1: if(baud_tick) begin sample_counter sample_counter 1; if(sample_counter
begin //取中间值采样 rx_buffer[bit_count] rx_sync; bit_count bit_count 1; end if(bit_count
begin rx_state 2; end end 2: begin //校验停止位 if(rx_sync) rx_valid 1b1; rx_state 0; end endcase end end重点在采样时刻选在数据位中间用3次采样的多数表决更稳。
实测发现某些Altera板子的IO延迟需要调整采样点这时候改sample_counter的触发条件就行。
跨平台兼容的骚操作在这define ALTERA_RESET 1 //Xilinx用0Altera用1 reg uart_rst; always (posedge clk) begin uart_rst ALTERA_RESET ? ~rst_n : rst_p; endXilinx的复位通常是高有效Altera习惯低有效用宏定义切换美滋滋。
记得在顶层模块例化时传对应的复位信号。
最后上板实测拿个USB转TTL模块杜邦线接好RX/TX。
用个回环测试代码always (posedge clk) begin if(rx_valid) begin tx_data rx_buffer; tx_start 1b1; end else begin tx_start 1b0; end end打开串口助手敲字母能自发自收就妥了。
注意电压匹配——