FPGA以9600的波特率向单片机发送32位数据,然后单片机对数据进行解析,显示在显示屏上面
波特率的产生 : 9600bps是指每秒钟发送9600个bit,即1bit的时间为1/9600,fpga板子自带50M晶振,那么一bit的时间时1/9600/1/50M
在没有检验位的情况下,每一帧数据是10位 第一位起始位 0 2-9位 数据(低位在前,高位在后),第十位 终止位 1
FPGA程序思路 : 首先由fpga计数,每隔一段时间产生一个bps_clk,也就是波特率的驱动时钟,发送状态机共分为7个状态
IDLE : 发送起始标志为 TX_1 : 发送32数据的高八位,其中低位在前,高位在后 ...... STOP : 终止标志位 STOP_1 : 是专门用来延时的,刚开始没有延时状态
的情况下,FPGA向单片机发送数据过快,非常占用单片机的中断资源,所以加了一个延时模块 stop ,作用是:每发完一次数据等待100ms然后再发第二次数据,这样的
单片机就有时间干别的事情了。
MCU程序思路 : 首先在中断函数里面将FPGA发送过来的数据存到一个数组里面来处理,detect-uart()函数是用来分析数组的,首先检测数组里面的起始标志 ‘t’,如果没有检测到
终止标志位‘x’的话,对中间数据进行移位处理,还原以前的32位宽的数据,由于在数据传送时有误码的情况,所以在display中加了三级缓存,来减少出错的可能性。
module uart_tx( //global clock input clk, input rst_n, //uart interface output reg uart_tx, //user interface input [31:0] pinlv, input pinlv_value ); parameter BPS_9600 = 5208; //parameter BPS_9600 = 10; //count for bps_clk reg [14:0] cnt_bps_clk; always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt_bps_clk <= 1'b0; else if(pinlv_value == 0) cnt_bps_clk <= 1'b0; else if(cnt_bps_clk == BPS_9600 - 1) cnt_bps_clk <= 1'b0; else cnt_bps_clk <= cnt_bps_clk + 1; end reg [31:0] cnt_bps_stop; wire stop_done; always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt_bps_stop <= 0; else if(state == STOP) cnt_bps_stop <= 0; else if(cnt_bps_stop > 50_000_00) cnt_bps_stop <= 0; else cnt_bps_stop <= cnt_bps_stop + 1; end assign stop_done = (cnt_bps_stop == 49_000_00)? 1 : 0; //clk for bps reg bps_clk; always @(posedge clk or negedge rst_n) begin if(!rst_n) bps_clk <= 1'b0; else if(cnt_bps_clk == 1) bps_clk <= 1'b1; else bps_clk <= 1'b0; end //cnt for bps reg [14:0] bps_cnt; always @(posedge clk or negedge rst_n) begin if(!rst_n) bps_cnt <= 1'b0; else if(bps_cnt == 10) bps_cnt <= 0; else if(bps_clk) bps_cnt <= bps_cnt + 1'b1; else bps_cnt <= bps_cnt; end //tx state localparam IDLE = 4'd0; localparam TX_1 = 4'd1; localparam TX_2 = 4'd2; localparam TX_3 = 4'd3; localparam TX_4 = 4'd4; localparam STOP = 4'd5; localparam STOP_1 = 4'd6; //cnt state reg [3:0] state; always @(posedge clk or negedge rst_n) </