一、定义串口传输协议帧
控制字的数据大小为一字节,定义帧头为(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) begindata_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];
endalways@(posedge clk )rx_done_r <= rx_done;//数据包解析,提取指令
always@(posedge clk or negedge reset)
if(!reset)beginen <= 0;ctrl <= 0;
end
else if(rx_done_r)beginif(data_str[0]==8'hFE&&data_str[1]==8'hDF&&data_str[4]==8'hEF)beginen <= 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 beginclk = 1'b1;reset <= 1'b0;rx <= 1'b1;#20;reset <= 1'b1;
#1000_000_00;
$finish;end//模拟发送8次数据,分别为0~7initial begin#200rx_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) begincase(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个时钟周期endendtask //任务以endtask结束
写在最后:波特率9600bps