03_串口 RS232( 三 )


:区分10 bit,一帧数据中10 bit的数据
提取数据,找到最稳定的状态 。
提取8bit 数据,有效的数据 1-8,
有效信号结束后,拉低,计数器也清0
然后进行数据的拼接操作,最后输出数据并且把信号拉高 。
6.2 串口数据发送模块
7. RTL 7.1
`timescale1ns/1nsmoduleuart_rx#(parameterUART_BPS='d9600,//串口波特率parameterCLK_FREQ='d50_000_000//时钟频率)(inputwiresys_clk,//系统时钟50MHzinputwiresys_rst_n,//全局复位inputwirerx,//串口接收数据outputreg[7:0]po_data,//串转并后的8bit数据outputregpo_flag//串转并后的数据有效标志信号);//********************************************************************////****************** Parameter and Internal Signal *******************////********************************************************************////localparamdefinelocalparamBAUD_CNT_MAX=CLK_FREQ/UART_BPS;//regdefineregrx_reg1;regrx_reg2;regrx_reg3;regstart_nedge ;regwork_en;reg [12:0]baud_cnt;regbit_flag;reg [3:0]bit_cnt;reg [7:0]rx_data;regrx_flag;//********************************************************************////***************************** Main Code ****************************////********************************************************************////插入两级寄存器进行数据同步,用来消除亚稳态//rx_reg1:第一级寄存器,寄存器空闲状态复位为1always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rx_reg1 <= 1'b1;elserx_reg1 <= rx;//rx_reg2:第二级寄存器,寄存器空闲状态复位为1always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rx_reg2 <= 1'b1;elserx_reg2 <= rx_reg1;//rx_reg3:第三级寄存器和第二级寄存器共同构成下降沿检测always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rx_reg3 <= 1'b1;elserx_reg3 <= rx_reg2;//start_nedge:检测到下降沿时start_nedge产生一个时钟的高电平always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)start_nedge <= 1'b0;elseif((~rx_reg2) && (rx_reg3))start_nedge <= 1'b1;elsestart_nedge <= 1'b0;//work_en:接收数据工作使能信号always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)work_en <= 1'b0;elseif(start_nedge == 1'b1)work_en <= 1'b1;elseif((bit_cnt == 4'd8) && (bit_flag == 1'b1))work_en <= 1'b0;//baud_cnt:波特率计数器计数,从0计数到BAUD_CNT_MAX - 1always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)baud_cnt <= 13'b0;elseif((baud_cnt == BAUD_CNT_MAX - 1) || (work_en == 1'b0))baud_cnt <= 13'b0;elseif(work_en == 1'b1)baud_cnt <= baud_cnt + 1'b1;//bit_flag:当baud_cnt计数器计数到中间数时采样的数据最稳定,//此时拉高一个标志信号表示数据可以被取走always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)bit_flag <= 1'b0;elseif(baud_cnt == BAUD_CNT_MAX/2 - 1)bit_flag <= 1'b1;elsebit_flag <= 1'b0;//bit_cnt:有效数据个数计数器,当8个有效数据(不含起始位和停止位)//都接收完成后计数器清零always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)bit_cnt <= 4'b0;elseif((bit_cnt == 4'd8) && (bit_flag == 1'b1))bit_cnt <= 4'b0;elseif(bit_flag ==1'b1)bit_cnt <= bit_cnt + 1'b1;//rx_data:输入数据进行移位always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rx_data <= 8'b0;elseif((bit_cnt >= 4'd1)&&(bit_cnt <= 4'd8)&&(bit_flag == 1'b1))rx_data <= {rx_reg3, rx_data[7:1]};//rx_flag:输入数据移位完成时rx_flag拉高一个时钟的高电平always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)rx_flag <= 1'b0;elseif((bit_cnt == 4'd8) && (bit_flag == 1'b1))rx_flag <= 1'b1;elserx_flag <= 1'b0;//po_data:输出完整的8位有效数据always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)po_data <= 8'b0;elseif(rx_flag == 1'b1)po_data