top模块
`timescale 1ns / 1ps
module top(
input sys_clk,
input rst_n,
input rx,
output tx,
output reg led,
output pwm
);
wire BaundClk_x16;
wire [7:0] DataCon;
wire TxFlag;
wire [15:0] period_data;
wire [15:0] h_time_data;
wire pwm_en;
clkdiv u_clkdiv(
.sys_clk(sys_clk),
.rst_n(rst_n),
.clk_out(BaundClk_x16)
);
rx_module u_rx(
.Clk16x(BaundClk_x16),
.rst_n(rst_n),
.rx(rx),
.DataReady(TxFlag),
.DataOut(DataCon)
);
tx_module u_tx(
.Clk16x(BaundClk_x16),
.rst_n(rst_n),
.TransEn(TxFlag),
.DataToTrans(DataCon),
.tx(tx)
);
pwm_register u_pwm_register(
.rst_n(rst_n),
.sysclk(sys_clk),
.rx_data(DataCon),
.rx_data_ready(TxFlag),
.period(period_data),
.h_time(h_time_data),
.pwm_en(pwm_en)
);
pwm_gen u_pwm_gen(
.rst_n(rst_n),
.sysclk(sys_clk),
.en(pwm_en),
.period(period_data),
.h_time(h_time_data),
.pwm(pwm)
);
always@(negedge rst_n , posedge TxFlag)
begin
if (!rst_n)
led <= 1'd0;
else
if(TxFlag)
led <= ~led;
end
endmodule
波特率频率产生模块
`timescale 1ns / 1ps
//输出16倍的波特率
module clkdiv(
input sys_clk,
input rst_n,
output reg clk_out
);
reg [7:0] counter;
parameter BaudRate = 115200;
parameter SysClk = 15360000;
localparam BaudACC = SysClk / BaudRate/16/2-1; //计数50次翻转
always @(posedge sys_clk or negedge rst_n)
begin
if (!rst_n)
begin
clk_out <= 0;
counter <= 0;
end
else if (counter == BaudACC)
begin
clk_out <= ~clk_out;
counter <= 8'd0;
end
else
counter <= counter + 1 ;
end
endmodule
串口接受模块
`timescale 1ns / 1ps
module rx_module(
//input SysClk, /* system topest clock */
input Clk16x, /* sample clock,16×115200 */
input rst_n, /* glabol reset signal */
input rx, /* serial data in */
output reg DataReady, /* a complete byte has been received */
output reg [7:0] DataOut //output reg [7:0] DataReceived /* Bytes received */
);
reg [7:0] cnt;
reg [7:0] DataReceived;
//---------------------------------------------
/* 捕获rx的下降沿,即起始信号 */
reg trigger_r0;
wire neg_tri;
assign neg_tri = trigger_r0 & ~rx;
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
trigger_r0<=1'b0;
else
trigger_r0<=rx;
end
//---------------------------------------------
/* counter control */
reg cnt_en;
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
cnt_en<=1'b0;
else if(neg_tri==1'b1) /*如果捕获到下降沿,则开始计数*/
cnt_en<=1'b1;
else if(cnt==8'd152)
cnt_en<=1'b0;
end
//---------------------------------------------
/* counter module ,对采样时钟进行计数 */
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
cnt<=8'd0;
else if(cnt_en)
cnt<=cnt+1'b1;
else
cnt<=8'd0;
end
//---------------------------------------------
/* receive module */
reg StopBit_r;
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
begin
DataReceived<=8'b0;
end
else if(cnt_en)
case(cnt)
8'd24: DataReceived[0] <= rx; /*在各个采样时刻,读取接收到的数据*/
8'd40: DataReceived[1] <= rx;
8'd56: DataReceived[2] <= rx;
8'd72: DataReceived[3] <= rx;
8'd88: DataReceived[4] <= rx;
8'd104: DataReceived[5] <= rx;
8'd120: DataReceived[6] <= rx;
8'd136: DataReceived[7] <= rx;
default:DataReceived <= DataReceived;
endcase
end
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
DataReady<=1'b0;
else if (cnt==8'd152)
begin
DataReady<=1'b1; //接收到停止位后,给出数据准备好标志位
DataOut <=DataReceived;
end
else
DataReady<=1'b0;
end
endmodule
串口发送模块
`timescale 1ns / 1ps
module tx_module(
input Clk16x, /* transmit clock,16×115200 */
input rst_n, /* glabol reset signal */
input TransEn, /* transmit enable */
input [7:0] DataToTrans, /* Data prepared for transmitting */
output reg BufFull, /* Data buffer is full */
output reg tx /* serial data out */
);
reg [7:0] cnt;
//----------------------------------------------
/* TransEn上升沿捕获 */
reg TransEn_r;
wire pos_tri;
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
TransEn_r <= 1'b0;
else
TransEn_r <= TransEn;
end
assign pos_tri = ~TransEn_r & TransEn;
//----------------------------------------------
/*when the rising edge of DataEn comes up, load the Data to buffer*/
reg [7:0] ShiftReg;
always@(posedge pos_tri or negedge rst_n)
begin
if(!rst_n)
ShiftReg <= 8'b0;
else
ShiftReg <= DataToTrans;
end
//----------------------------------------------
/* counter control */
reg cnt_en;
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
begin
cnt_en <= 1'b0;
BufFull <= 1'b0;
end
else if(pos_tri==1'b1)
begin
cnt_en <=1'b1;
BufFull <=1'b1;
end
else if(cnt==8'd160)
begin
cnt_en<=1'b0;
BufFull <=1'b0;
end
end
//---------------------------------------------
/* counter module */
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
cnt<=8'd0;
else if(cnt_en)
cnt<=cnt+1'b1;
else
cnt<=8'd0;
end
//---------------------------------------------
/* transmit module */
always@(posedge Clk16x or negedge rst_n)
begin
if(!rst_n)
begin
tx <= 1'b1;
end
else if(cnt_en)
case(cnt)
8'd0 : tx <= 1'b0;
8'd16 : tx <= ShiftReg[0];
8'd32 : tx <= ShiftReg[1];
8'd48 : tx <= ShiftReg[2];
8'd64 : tx <= ShiftReg[3];
8'd80 : tx <= ShiftReg[4];
8'd96 : tx <= ShiftReg[5];
8'd112 : tx <= ShiftReg[6];
8'd128 : tx <= ShiftReg[7];
8'd144 : tx <= 1'b1;
endcase
else
tx <= 1'b1;
end
endmodule
串口传送PWM数据,寄存模块
`timescale 1ns / 1ps
module pwm_register(
input rst_n,
input sysclk,
input [7:0] rx_data,
input rx_data_ready,
output reg [15:0] period,
output reg [15:0] h_time,
output reg pwm_en
);
reg[7:0] rx_reg;
always@(posedge rx_data_ready or negedge rst_n)
if(!rst_n)
begin
rx_reg <= 8'b0;
end
else
begin
rx_reg <= rx_data; //帧尾
h_time[7:0] <= rx_reg; //底位
h_time[15:8]<= h_time[7:0];
period[7:0] <= h_time[15:8];
period[15:8]<= period[7:0]; //高位
end
always @ (posedge sysclk or negedge rst_n)
begin
if(!rst_n)
pwm_en <= 1'b0;
else if (rx_reg == 8'b1111_1111)
pwm_en <= 1'b1;
else
pwm_en <= 1'b0;
end
endmodule
PWM产生模块
`timescale 1ns / 1ps
module pwm_gen(
input rst_n,
input sysclk,
input en,
input [15:0] period,
input [15:0] h_time,
output reg pwm
);
reg [31:0] cnt;
always @ (posedge sysclk or negedge rst_n)
begin
if(!rst_n)
cnt <= 0;
else
begin
if(cnt >= period - 1 )
cnt <= 0;
else
cnt <= cnt + 1;
end
end
always @ (posedge sysclk or negedge rst_n)
begin
if(!rst_n)
pwm <= 0;
else //rst_n = 1
begin
if(en == 0)
pwm <= 0;
else //en = 1
begin
if(cnt <= h_time - 1)
pwm <= 1;
else
pwm <= 0;
end
end
end
endmodule
发送数据HEX例如:7800(period) 3c00(h_time) FF (end)