uart串口环回(加校验位)

发布时间:2026/5/21 16:53:19

uart串口环回(加校验位) 文章目录一.校验位原理1.奇校验2.偶校验二.设计思路三.代码1.uart_tx2.uart_rx四.仿真1.无校验位1.1无校验位总仿真1.2无校验位rx1.3无校验位tx2.奇校验位2.1奇校验位正确总仿真2.2奇校验位正确rx2.3奇校验位正确tx2.4奇校验位错误总仿真2.5奇校验位错误rx2.6奇校验位错误tx3.偶校验位2.1偶校验位正确总仿真2.2偶校验位正确rx2.3偶校验位正确tx2.4偶校验位错误总仿真2.5偶校验位错误rx2.6偶校验位错误tx五.效果5.1如何在串口助手中设置校验位5.2奇校验5.3偶校验一.校验位原理校验分为无校验位奇校验位和偶校验位1.奇校验数据位中1的个数为奇数则校验位为0否则校验位为12.偶校验数据为中1的个数为偶数则校验位为0否则校验位为1二.设计思路根据传输的数据计算出一个校验位和我们传输的校验位做对比。使能信号需要保证在传输的校验位和计算的校验位相等时才有效根据无校验位奇校验位偶校验位三种情况需要改变状态转移图uart_txuart_rx三.代码1.uart_tx/**************************************功能介绍*********************************** Date : 2023年8月16日17:07:11 Author : Alegg xy. Version : 2.0 Description: FPGA向上位机发送数据【8bit变1bit波形】 *********************************************************************************/ //---------模块及端口声名------------------------------------------------------ module uart_tx( input clk , input rst_n , input [7:0] tx_data , input tx_data_vld, output ready , output reg tx ); //---------参数定义--------------------------------------------------------- parameter MAX_BPS 115200; parameter CLOCK 50_000_000; parameter MAX_1bit CLOCK/MAX_BPS;//1bit要计434次 parameter CHECK_BIT None;//None无校验Odd奇校验Even偶校验 //状态机参数定义 localparam IDLE b00001,//空闲状态 START b00010,//起始位 DATA b00100,//数据位 CHECK b01000,//校验位 STOP b10000;//停止位 //---------内部信号定义----------------------------------------------------- reg [4:0] cstate ;//现态 reg [4:0] nstate ;//次态 wire IDLE_START; wire START_DATA; wire DATA_CHECK; wire CHECK_STOP; wire STOP_IDLE; reg [8:0] cnt_baud ;//波特计数器波特率115200 wire add_cnt_baud ; wire end_cnt_baud ; reg [2:0] cnt_bit ;//bit计数器起始位1bit数据位8bit结束位1bit wire add_cnt_bit ; wire end_cnt_bit ; reg [3:0] bit_max;//bit最大值复用需要考察每个状态的bit值 reg [7:0] tx_data_r; wire check_val; //计434次 always (posedge clk or negedge rst_n)begin if(!rst_n)begin cnt_baud d0; end else if(add_cnt_baud)begin if(end_cnt_baud)begin cnt_baud d0; end else begin cnt_baud cnt_baud 1d1; end end end assign add_cnt_baud cstate ! IDLE; assign end_cnt_baud add_cnt_baud cnt_baud MAX_1bit - 1d1; //bit计数器 always (posedge clk or negedge rst_n)begin if(!rst_n)begin cnt_bit d0; end else if(add_cnt_bit)begin if(end_cnt_bit)begin cnt_bit d0; end else begin cnt_bit cnt_bit 1d1; end end end assign add_cnt_bit end_cnt_baud; assign end_cnt_bit add_cnt_bit cnt_bit bit_max -1d1; //计数器复用 always (*)begin case (cstate) IDLE :bit_max d0; START:bit_max d1;//起始位1bit DATA :bit_max d8;//数据位7bit CHECK:bit_max d1;//校验位1bit STOP :bit_max d1;//结束位1bit default: bit_max d0; endcase end assign IDLE_START (cstate IDLE) tx_data_vld;//考察到开始传输信号 assign START_DATA (cstate START) end_cnt_bit;//计1bit数据 assign DATA_STOP (cstate DATA) end_cnt_bit CHECK_BIT None; assign DATA_CHECK (cstate DATA) end_cnt_bit;//计8bit数据 assign CHECK_STOP (cstate CHECK) end_cnt_bit;//计1bit数据 assign STOP_IDLE (cstate STOP) end_cnt_bit;//计1bit数据 //第一段时序逻辑描述状态转移 always (posedge clk or negedge rst_n)begin if(!rst_n)begin cstate IDLE; end else begin cstate nstate; end end //第二段组合逻辑描述状态转移规律和状态转移条件 always (*) begin case(cstate) IDLE :begin if (IDLE_START) begin nstate START; end else begin nstate cstate; end end START :begin if (START_DATA) begin nstate DATA; end else begin nstate cstate; end end DATA :begin if (DATA_CHECK) begin nstate CHECK; end else if (DATA_STOP) begin nstate STOP; end else begin nstate cstate; end end CHECK :begin if (CHECK_STOP) begin nstate STOP; end else begin nstate cstate; end end STOP :begin if (STOP_IDLE) begin nstate IDLE; end else begin nstate cstate; end end default : nstate cstate; endcase end //寄存一拍 always (posedge clk or negedge rst_n) begin if (!rst_n) begin tx_data_r d0; end else if (tx_data_vld) begin tx_data_r tx_data; end else begin tx_data_r tx_data_r; end end assign check_val (CHECK_BIT Odd) ? ~^tx_data_r : ^tx_data_r; //第三段描述输出时序逻辑或组合逻辑皆可 always (*)begin case (cstate) IDLE : tx 1b1; START: tx 1b0;//起始位为0 DATA : tx tx_data_r[cnt_bit]; CHECK: tx check_val; STOP : tx 1b1;//结束位为1 default: tx 1b1; endcase end assign ready cstate IDLE;//当状态为IDLE时表示tx端可以接收数据 endmodule2.uart_rx/**************************************功能介绍*********************************** Date : 2023年8月16日18:25:03 Author : Alegg xy. Version : 1.0 Description: FPGA收上位机发来的数据【1bit波形变8bit】 *********************************************************************************/ //---------模块及端口声名------------------------------------------------------ module uart_rx( input clk , input rst_n , input rx , output rx_data_vld, output [7:0] rx_data ); //---------参数定义--------------------------------------------------------- parameter MAX_BPS 115200; parameter CLOCK 50_000_000; parameter MAX_1bit CLOCK/MAX_BPS;//1bit要计434次 parameter CHECK_BIT None;//None无校验Odd奇校验Even偶校验 //状态机参数定义 localparam IDLE b0001,//空闲状态 START b0010,//起始位 DATA b0100,//数据位 CHECK b1000; //---------内部信号定义----------------------------------------------------- reg [3:0] cstate ;//现态 reg [3:0] nstate ;//次态 wire IDLE_START; wire START_DATA; wire DATA_IDLE; wire DATA_CHECK; wire CHECK_IDLE; reg [8:0] cnt_baud ;//波特计数器波特率115200 wire add_cnt_baud ; wire end_cnt_baud ; reg [2:0] cnt_bit ;//bit计数器起始位1bit数据位8bit结束位1bit wire add_cnt_bit ; wire end_cnt_bit ; reg [3:0] bit_max;//bit最大值复用需要考察每个状态的bit值 reg [7:0] rx_temp; reg rx_check; wire check_val; reg rx_r1; reg rx_r2; wire rx_nege; //打两拍 always (posedge clk or negedge rst_n) begin if (!rst_n) begin rx_r1 1; rx_r2 1; end else begin rx_r1 rx; rx_r2 rx_r1; end end assign rx_nege ~rx_r1 rx_r2; //计434次 always (posedge clk or negedge rst_n)begin if(!rst_n)begin cnt_baud d0; end else if(add_cnt_baud)begin if(end_cnt_baud)begin cnt_baud d0; end else begin cnt_baud cnt_baud 1d1; end end end assign add_cnt_baud cstate ! IDLE; assign end_cnt_baud add_cnt_baud cnt_baud MAX_1bit - 1d1; //bit计数器 always (posedge clk or negedge rst_n)begin if(!rst_n)begin cnt_bit d0; end else if(add_cnt_bit)begin if(end_cnt_bit)begin cnt_bit d0; end else begin cnt_bit cnt_bit 1d1; end end end assign add_cnt_bit end_cnt_baud; assign end_cnt_bit add_cnt_bit cnt_bit bit_max -1d1; //计数器复用 always (*)begin case (cstate) IDLE :bit_max d0; START:bit_max d1;//起始位1bit DATA :bit_max d8;//数据位8bit CHECK:bit_max d1; default: bit_max d0; endcase end assign IDLE_START (cstate IDLE) rx_nege;//识别到起始位0 assign START_DATA (cstate START) end_cnt_bit;//计1bit数据 assign DATA_IDLE (cstate DATA) end_cnt_bit CHECK_BIT None;//计8bit数据 assign DATA_CHECK (cstate DATA) end_cnt_bit; assign CHECK_IDLE (cstate CHECK) end_cnt_bit; //第一段时序逻辑描述状态转移 always (posedge clk or negedge rst_n)begin if(!rst_n)begin cstate IDLE; end else begin cstate nstate; end end //第二段组合逻辑描述状态转移规律和状态转移条件 always (*) begin case(cstate) IDLE :begin if (IDLE_START) begin nstate START; end else begin nstate cstate; end end START :begin if (START_DATA) begin nstate DATA; end else begin nstate cstate; end end DATA :begin if (DATA_IDLE) begin nstate IDLE; end else if (DATA_CHECK) begin nstate CHECK; end else begin nstate cstate; end end CHECK:begin if (CHECK_IDLE) begin nstate IDLE; end else begin nstate cstate; end end default : nstate IDLE; endcase end //接受校验位 always (posedge clk or negedge rst_n) begin if (!rst_n) begin rx_check 0; end else if (cstate CHECK cnt_baud MAX_1bit 1) begin rx_check rx_r1; end end //计算校验位 assign check_val (CHECK_BIT Odd) ? ~^rx_temp : ^rx_temp; //第三段描述输出时序逻辑或组合逻辑皆可 always (posedge clk or negedge rst_n) begin if (!rst_n) begin rx_temp 0; end else if (cstate DATA cnt_baud MAX_1bit 1) begin//电平中间值采样边沿采样容易出错 rx_temp[cnt_bit] rx_r1; end else begin rx_temp rx_temp; end end assign rx_data rx_temp; assign rx_data_vld (CHECK_BIT None) ? DATA_IDLE :(CHECK_IDLE (check_val rx_check)) ? 1 : 0; endmodule其中可以通过top重定义MAX_BPS和CHECK_BIT来修改波特率和校验位四.仿真仿真有多种情况1.无校验位1.1无校验位总仿真1.2无校验位rx1.3无校验位tx2.奇校验位2.1奇校验位正确总仿真2.2奇校验位正确rx2.3奇校验位正确tx2.4奇校验位错误总仿真2.5奇校验位错误rx2.6奇校验位错误tx3.偶校验位2.1偶校验位正确总仿真2.2偶校验位正确rx2.3偶校验位正确tx2.4偶校验位错误总仿真2.5偶校验位错误rx2.6偶校验位错误tx五.效果5.1如何在串口助手中设置校验位选择左下角的更多串口设置后弹窗中调整校验位None无校验位、Odd奇校验位、Even偶校验位5.2奇校验这里代码中设置奇校验串口设置无校验位时会有一些问题大家如果发现了我的错误在哪可以私信或者评论我一下谢谢大家了5.3偶校验

相关新闻