基于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
相关产品推荐
相关产品推荐

