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

DHT22与Elbert V2 FPGA接口开发:状态机无法进入end_sl状态求助

排查DHT22(代码标注DHT11)状态机无法进入end_sl终态的问题

看起来你的状态机卡壳在前期流程里,根本没机会走到end_sl,我先梳理几个代码里的关键问题,再给你排查和修复的方向:


1. 未定义的常量直接导致逻辑异常

你注释掉了TIME_70_US的定义,但在consider_logic状态里却直接用了这个常量:

elsif (index < TIME_70_US) then -- time ~70 us - logic ='1'

这要么会触发编译错误,要么编译后这个常量的值是不确定的,直接导致位数据判断失效,number_bit永远没法递减到0,自然进不了end_sl。
修复:取消注释并修正这个常量的定义(要符合DHT22的70us高电平阈值):

constant TIME_70_US: positive := 70*10**3/CLK_PERIOD_NS+1; -- DHT22高电平判定阈值

2. 总线电平检测逻辑残缺,状态机卡死在前期状态

你的状态机在wait_res_sl、response_sl这些关键状态里,没有正确更新总线电平的采样值:

  • wait_res_sl状态里完全没给next_bit_in赋值,导致bit_in寄存器永远不会更新,根本检测不到从机拉低总线的下降沿,直接卡死在这个状态,连后续的response_sl都到不了。
  • response_sl和delay_sl的边沿检测逻辑也依赖bit_in和next_bit_in的变化,但next_bit_in的赋值不连贯,没法准确捕获总线的电平跳变。

修复建议:
在所有需要检测总线的状态里,强制把next_bit_in赋值为singer_bus的实时值,同时加上超时判断避免死锁,比如修改wait_res_sl:

when wait_res_sl => -- 等待从机应答的下降沿
    next_bit_in <= singer_bus;
    if bit_in = '1' and next_bit_in = '0' then -- 捕获总线从高到低的跳变
        next_state <= response_sl;
        next_index <= DELAY_80_US;
    elsif index = 0 then -- 超时40us无应答,回到初始状态
        next_state <= reset;
    else
        next_state <= wait_res_sl;
        next_index <= index - 1;
    end if;

同样的,给response_sl、delay_sl都加上next_bit_in <= singer_bus和超时处理,确保状态机能正常推进。

3. start_sl状态的跳转逻辑顺序错误

你在start_sl里的判断顺序有问题:

elsif number_bit = 0 then 
    next_state <= end_sl;
    next_index <= DELAY_50_US;
else 
    next_state <= start_sl;

这个逻辑里,只有当总线边沿检测失败时,才会判断number_bit是否为0。但如果总线一直没有预期的边沿跳变,即使number_bit已经减到0,也永远触发不了end_sl的跳转。

修复:把number_bit的判断放在最前面,确保所有位接收完成后能直接进入终态:

when start_sl => -- 准备接收下一位数据
    next_bit_in <= singer_bus;
    if number_bit = 0 then 
        next_state <= end_sl;
        next_index <= DELAY_50_US;
    elsif (bit_in = '0') and (next_bit_in = '1') then 
        next_state <= consider_logic;
        next_index <= 0;
    else
        next_state <= start_sl;
    end if;

4. 其他潜在问题要排查

  • 命名与时序不匹配:代码里entity是DHT11,但你实际用的是DHT22,两者的时序参数有细微差别,建议统一命名并核对所有延时常量是否符合DHT22的 datasheet。
  • dataout赋值逻辑冗余:你在proces_state开头默认把dataout置0,只有end_sl状态才赋值为data_out,这会导致非终态下dataout全为0,虽然不影响状态机,但不符合预期,建议去掉开头的默认赋值,只在end_sl时更新。
  • 硬件上拉缺失:DHT22的DATA线必须加外部上拉电阻(4.7K或10K),如果硬件没加,总线电平会不稳定,状态机根本没法正确检测边沿,这是很容易忽略的硬件问题。

实操排查步骤

  1. 先修复编译错误(比如未定义的TIME_70_US),确保代码能正常生成比特流。
  2. 用FPGA工具的波形仿真功能,把state、singer_bus、number_bit、index这些信号拖到波形窗口,观察状态机的跳转路径:
    • 如果卡在wait_res_sl,说明从机没应答,要么是硬件连接错了,要么是电平检测逻辑有问题。
    • 如果number_bit一直不变,说明consider_logic状态没正确捕获位数据的结束边沿。
  3. 检查硬件:确认DHT22的VCC、GND、DATA线连接正确,DATA线的上拉电阻是否到位。

内容的提问来源于stack exchange,提问作者Thanh niên Yên Bái

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:08:30