[table]
018 parameter system_clk = 50_000_000; /*输入时钟频率设定,默认50M*/
019
020 /*根据输入时钟频率计算生成各波特率时分频计数器的计数最大值*/
021 localparam bps9600 = system_clk/9600 - 1;
022 localparam bps19200 = system_clk/19200 - 1;
023 localparam bps38400 = system_clk/38400 - 1;
024 localparam bps57600 = system_clk/57600 - 1;
025 localparam bps115200 = system_clk/115200 - 1;
026 localparam bps230400 = system_clk/230400 - 1;
027 localparam bps460800 = system_clk/460800 - 1;
028 localparam bps921600 = system_clk/921600 - 1;
029
030 reg [31:0]BPS_PARA;/*波特率分频计数器的计数最大值*/
031
032 always@(posedge Clk or negedge Rst_n)
033 if(!Rst_n)begin
034 BPS_PARA <= bps9600;/*复位时波特率默认为9600bps*/
035 end
036 else begin
037 case(Baud_Set)/*根据波特率控制信号选择不同的波特率计数器计数最大值*/
038 3'd0: BPS_PARA <= bps9600;
039 3'd1: BPS_PARA <= bps19200;
040 3'd2: BPS_PARA <= bps38400;
041 3'd3: BPS_PARA <= bps57600;
042 3'd4: BPS_PARA <= bps115200;
043 3'd5: BPS_PARA <= bps230400;
044 3'd6: BPS_PARA <= bps460800;
045 3'd7: BPS_PARA <= bps921600;
046 default: BPS_PARA <= bps9600;
047 endcase
048 end
049
050 //=========================================================
051 reg[12:0]Count;
052
053 reg n_state;
054 localparam IDEL_1 = 1'b0,
055 SEND = 1'b1;
056
057 reg BPS_EN;
058
059 /*-------波特率时钟生成控制逻辑--------------*/
060 always@(posedge Clk or negedge Rst_n)
061 if(!Rst_n)begin
062 BPS_EN <= 1'b0;
063 n_state <= IDEL_1;
064 end
065 else begin
066 case(n_state)
067 IDEL_1:
068 if(Byte_En)begin/*检测到字节发送使能信号,则启动波特率生成进程,同时进入发送状态*/
069 BPS_EN <= 1'b1;
070 n_state <= SEND;
071 end
072 else begin
073 n_state <= IDEL_1;
074 BPS_EN <= 1'b0;
075 end
076 SEND:
077 if(Tx_Done == 1)begin/*发送完成,关闭波特率生成进程,回到空闲状态*/
078 BPS_EN <= 1'b0;
079 n_state <= IDEL_1;
080 end
081 else begin
082 n_state <= SEND;
083 BPS_EN <= 1'b1;
084 end
085 default:n_state <= IDEL_1;
086 endcase
087 end
088
089 /*-------波特率时钟生成定时器--------------*/
090 always@(posedge Clk or negedge Rst_n)
091 if(!Rst_n)
092 Count <= 13'd0;
093 else if(BPS_EN == 1'b0)
094 Count <= 13'd0;
095 else begin
096 if(Count == BPS_PARA)
097 Count <= 13'd0;
098 else
099 Count <= Count + 1'b1;
100 end
101
102 /*输出数据接收采样时钟*/
103 //-----------------------------------------------
104 always @(posedge Clk or negedge Rst_n)
105 if(!Rst_n)
106 Bps_Clk <= 1'b0;
107 else if(Count== 1)
108 Bps_Clk <= 1'b1;
109 else
110 Bps_Clk <= 1'b0;
第18行“parameter system_clk = 50_000_000;”,这里用一个全局参数定义了系统时钟,暂时设定为50M,可根据实际使用的板卡上的工作时钟进行修改。
所谓波特率生成,就是用一个定时器来定时,产生频率与对应波特率时钟频率相同的时钟信号。例如,我们使用波特率为115200bps,则我们需要产生一个频率为115200Hz的时钟信号。那么如何产生这样一个115200Hz的时钟信号呢?这里,我们首先将115200Hz时钟信号的周期计算出来,1秒钟为1000_000_000ns,因此波特率时钟的周期Tb=1000000000/115200 =8680.6ns,即115200信号的一个周期为8680.6ns,那么,我们只需要设定我们的定时器定时时间为8680.6ns,每当定时时间到,产生一个系统时钟周期长度的高脉冲信号即可。系统时钟频率为50MHz,即周期为20ns,那么,我们只需要计数8680/20个系统时钟,就可获得8680ns的定时,即bps115200=Tb/Tclk- 1=Tb*fclk - 1=fclk/115200-1。相应的,其它波特率定时值的计算与此类似,这里小梅哥就不再一一分析。20行至28行为波特率定时器定时值的计算部分。
为了能够通过外部控制波特率,设计中使用了一个3位的波特率选择端口:Baud_Set。通过给此端口不同的值,就能选择不同的波特率,此端口控制不同波特率的原理很简单,就是一个多路选择器,第32行至第48行即为此多路选择器的控制代码, Baud_Set的值与各波特率的对应关系如下:
000 : 9600bps;
001 : 19200bps;
010 :38400bps;
011 :57600bps;
100 :115200bps;
101 :230400bps;
110 :460800bps;
111
:921600bps;