MCU与FPGA串口通信

本文介绍了一个FPGA向MCU以9600波特率发送32位数据的通信过程。FPGA利用50M晶振生成波特率时钟,通过7状态发送状态机发送数据,并在发送后加入100ms延时以减轻MCU中断负担。MCU则在中断服务中接收数据并存储,通过detect-uart()函数分析数据,确保数据正确性,并采用三级缓存策略降低错误概率。
摘要由CSDN通过智能技术生成

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)
</
  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值