一、定义串口传输协议帧
控制字的数据大小为一字节,定义帧头为(0xFE 0xDF)帧尾为(0xEF)
模块框图
内模块:串口接收,output:8位data
串口命令:对单字节数据接收进行缓存,5字节数据判断数据帧是否有效,提取正确的控制字
根据控制字解析,控制8位led的亮灭
二、串口命令转换模块设计(uart_cmd)
reg[7:0] data_str [4:0];//5个位宽为8的元素
//reg [7:0] count [3:0] 4个位宽为8元素的一维数组
reg rx_done_r;
//移位数据缓存
always@(posedge clk)
if(rx_done) begin
data_str[4] <= rx_data;
data_str[3] <= data_str[4];
data_str[2] <= data_str[3];
data_str[1] <= data_str[2];
data_str[0] <= data_str[1];
end
always@(posedge clk )
rx_done_r <= rx_done;
//数据包解析,提取指令
always@(posedge clk or negedge reset)
if(!reset)begin
en <= 0;
ctrl <= 0;
end
else if(rx_done_r)begin
if(data_str[0]==8'hFE&&data_str[1]==8'hDF&&data_str[4]==8'hEF)begin
en <= data_str[2];
ctrl <= data_str[3];
end
end
//仿真文件
initial clk = 1;
always#10 clk = ~clk;
initial begin
reset = 0;
rx_data = 8'h0;
rx_done = 0;
#21;
reset = 1;
rx_done = 1;
#20;
rx_done = 0;
rx_data = 8'hFE;
#5208
rx_done = 1;
#20;
rx_done = 0;
rx_data = 8'hDF;
#5208
rx_done = 1;
#20;
rx_done = 0;
rx_data = 8'h01;
#5208
rx_done = 1;
#20;
rx_done = 0;
rx_data = 8'haa;
#5208
rx_done = 1;
#20;
rx_done = 0;
rx_data = 8'hef;
#5208
rx_done = 1;
#20;
rx_done = 0;
#5208
$finish;
end
三、串口指令控制led
initial clk = 1;
always#10 clk =~clk;
initial begin
reset = 0;
en = 8'h00;
ctrl = 8'h00;
#21;
reset = 1;
#120;
en = 8'h01;
#200
ctrl = 8'hff;
#200
$finish;
end
四、串口接收(uart_rx)
五、顶层模块
//初始化系统时钟、全局复位和输入信号
initial begin
clk = 1'b1;
reset <= 1'b0;
rx <= 1'b1;
#20;
reset <= 1'b1;
#1000_000_00;
$finish;
end
//模拟发送8次数据,分别为0~7
initial begin
#200
rx_bit(8'hfe); //任务的调用,任务名+括号中要传递进任务的参数
rx_bit(8'hdf);
rx_bit(8'h1);
rx_bit(8'hff);
rx_bit(8'hef);
end
//clk:每10ns电平翻转一次,产生一个50MHz的时钟信号
always #10 clk = ~clk;
//定义一个名为rx_bit的任务,每次发送的数据有10位
//data的值分别为0~7由j的值传递进来
//任务以task开头,后面紧跟着的是任务名,调用时使用
task rx_bit(
//传递到任务中的参数,调用任务的时候从外部传进来一个8位的值
input [7:0] data
);
integer i; //定义一个常量
//用for循环产生一帧数据,for括号中最后执行的内容只能写i=i+1
//不可以写成C语言i=i++的形式
for(i=0; i<10; i=i+1) begin
case(i)
0: rx <= 1'b0;
1: rx <= data[0];
2: rx <= data[1];
3: rx <= data[2];
4: rx <= data[3];
5: rx <= data[4];
6: rx <= data[5];
7: rx <= data[6];
8: rx <= data[7];
9: rx <= 1'b1;
endcase
#(5208*20); //每发送1位数据延时5208个时钟周期
end
endtask //任务以endtask结束
写在最后:波特率9600bps