You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Verilog的Nexys 2 FPGA与HC-06蓝牙LED同步问题咨询

解决HC-06蓝牙与Nexys 2 FPGA的波特率同步问题

你碰到的问题十有八九是波特率不匹配导致的串行通信错位——毕竟HC-06默认波特率是9600,如果FPGA这边的波特率生成模块参数算错了,接收端采样时钟不对,解析出来的数据就会完全混乱,自然出现发送全1却只亮单颗LED的情况。

先看波特率计算的核心问题

Nexys 2的系统时钟是50MHz,UART接收通常需要16倍波特率的采样时钟(用来在数据位的中间时刻采样,保证同步),发送时钟可以用波特率本身。我们来重新计算9600波特率对应的参数:

  • 16倍采样时钟频率:16 * 9600 = 153600 Hz
  • 接收累加最大值:50,000,000 / 153600 ≈ 325
  • 发送累加最大值:50,000,000 / 9600 ≈ 5208

你代码里写的RX_ACC_MAX = 50000...明显偏差太大,这会让采样时钟频率远低于预期,直接导致接收数据错位。

修正后的波特率生成模块示例

module baud_rate_gen(
    input wire clk_50m,
    output wire rxclk_en,
    output wire txclk_en
);
    // 针对9600波特率的参数计算(基于50MHz系统时钟)
    parameter RX_ACC_MAX = 50000000 / (16 * 9600); // 结果为325
    parameter TX_ACC_MAX = 50000000 / 9600;       // 结果为5208
    parameter ACC_WIDTH = 16; // 足够容纳最大累加值的位宽,避免溢出

    reg [ACC_WIDTH-1:0] rx_acc = 0;
    reg [ACC_WIDTH-1:0] tx_acc = 0;

    // 当累加器归零时输出时钟使能脉冲
    assign rxclk_en = (rx_acc == 0);
    assign txclk_en = (tx_acc == 0);

    always @(posedge clk_50m) begin
        // 生成接收采样时钟使能(16倍波特率)
        if (rx_acc == RX_ACC_MAX)
            rx_acc <= 0;
        else
            rx_acc <= rx_acc + 1;
        
        // 生成发送时钟使能(波特率本身)
        if (tx_acc == TX_ACC_MAX)
            tx_acc <= 0;
        else
            tx_acc <= tx_acc + 1;
    end
endmodule

额外调试建议

  • 验证蓝牙模块波特率:用AT指令确认HC-06的波特率确实是9600——发送AT+BAUD?,模块返回+BAUD=1就对应9600(如果不是,用AT+BAUD1改回默认)。
  • 单bit测试:先发送0x01看LED0是否点亮,0x02看LED1,逐步确认每一位数据解析是否正确,这样能快速定位是波特率问题还是其他逻辑问题。
  • 波形观测:如果有逻辑分析仪或者示波器,直接看FPGA的RX引脚波形,对比手机发送的波形,看波特率是否匹配(比如一个数据位的时长应该是约104us,对应9600波特率)。

内容的提问来源于stack exchange,提问作者Murat Tekin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:30:57