• nexys4-DDR开发板温度传感器ADT7420U


    1. 用这个板子做个什么功能来学习?板子上有个温度传感器,看下官方是否有例程,板子售价1780元,相当的贵,下面是I2C接口,

    看下芯片的引脚图

    2. 资料下载地址,得注册账号

    https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/start?redirect=1

    3. 下面的例程,包括温度传感器的参考代码

    4. 找到温度传感器的参考代码

    5. 研究下代码吗,不过我VHDL不太懂,所以要研究下代码

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.math_real.all;
    use IEEE.std_logic_arith.all;
    
    
    -- Use the package defined in the TWICtl.vhd file
    use work.TWIUtils.ALL;
    
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    --use IEEE.NUMERIC_STD.ALL;
    
    -- Uncomment the following library declaration if instantiating
    -- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;
    
    entity TempSensorCtl is
        Generic (CLOCKFREQ : natural := 100); -- input CLK frequency in MHz
        Port (
            TMP_SCL : inout STD_LOGIC;
            TMP_SDA : inout STD_LOGIC;
    --        TMP_INT : in STD_LOGIC; -- Interrupt line from the ADT7420, not used in this project
    --        TMP_CT : in STD_LOGIC;  -- Critical Temperature interrupt line from ADT7420, not used in this project
            
            TEMP_O : out STD_LOGIC_VECTOR(12 downto 0); --12-bit two's complement temperature with sign bit
            RDY_O : out STD_LOGIC;    --'1' when there is a valid temperature reading on TEMP_O
            ERR_O : out STD_LOGIC; --'1' if communication error
            
            CLK_I : in STD_LOGIC;
            SRST_I : in STD_LOGIC
        );
    end TempSensorCtl;
    
    architecture Behavioral of TempSensorCtl is
    
    -- TWI Controller component declaration
        component TWICtl
       generic 
       (
            CLOCKFREQ : natural := 50;  -- input CLK frequency in MHz
            ATTEMPT_SLAVE_UNBLOCK : boolean := false --setting this true will attempt
            --to drive a few clock pulses for a slave to allow to finish a previous
            --interrupted read transfer, otherwise the bus might remain locked up        
        );
        port (
            MSG_I : in STD_LOGIC; --new message
            STB_I : in STD_LOGIC; --strobe
            A_I : in  STD_LOGIC_VECTOR (7 downto 0); --address input bus
            D_I : in  STD_LOGIC_VECTOR (7 downto 0); --data input bus
            D_O : out  STD_LOGIC_VECTOR (7 downto 0); --data output bus
            DONE_O : out  STD_LOGIC; --done status signal
          ERR_O : out  STD_LOGIC; --error status
            ERRTYPE_O : out error_type; --error type
            CLK : in std_logic;
            SRST : in std_logic;
    ----------------------------------------------------------------------------------
    -- TWI bus signals
    ----------------------------------------------------------------------------------
            SDA : inout std_logic; --TWI SDA
            SCL : inout std_logic --TWI SCL
        );
    end component;
    
    ----------------------------------------------------------------------------------
    -- Definitions for the I2C initialization vector
    ----------------------------------------------------------------------------------
        constant IRD : std_logic := '1'; -- init read
        constant IWR : std_logic := '0'; -- init write
        
        constant ADT7420_ADDR : std_logic_vector(7 downto 1)     := "1001011"; -- TWI Slave Address
        constant ADT7420_RID : std_logic_vector(7 downto 0)      := x"0B"; -- ID Register Address for the ADT7420
        constant ADT7420_RRESET : std_logic_vector(7 downto 0)   := x"2F"; -- Software Reset Register
        constant ADT7420_RTEMP : std_logic_vector(7 downto 0)    := x"00"; -- Temperature Read MSB Address
        constant ADT7420_ID : std_logic_vector(7 downto 0)       := x"CB"; -- ADT7420 Manufacturer ID
        
        constant DELAY : NATURAL := 1; --ms
        constant DELAY_CYCLES : NATURAL := natural(ceil(real(DELAY*1000*CLOCKFREQ)));
        constant RETRY_COUNT : NATURAL := 10;
    
       -- State MAchine states definition
       type state_type is (
                            stIdle, -- Idle State
                            stInitReg,  -- Send register address from the init vector
                            stInitData, -- Send data byte from the init vector
                            stRetry,    -- Retry state reached when there is a bus error, will retry RETRY_COUNT times
                            stReadTempR,  -- Send temperature register address
                            stReadTempD1, -- Read temperature MSB
                            stReadTempD2, -- Read temperature LSB
                            stError -- Error state when reached when there is a bus error after a successful init; stays here until reset
                            ); 
       signal state, nstate : state_type; 
    
        
       constant NO_OF_INIT_VECTORS : natural := 3; -- number of init vectors in TempSensInitMap
        constant DATA_WIDTH : integer := 1 + 8 + 8; -- RD/WR bit + 1 byte register address + 1 byte data
        constant ADDR_WIDTH : natural := natural(ceil(log(real(NO_OF_INIT_VECTORS), 2.0)));
        
        type TempSensInitMap_type is array (0 to NO_OF_INIT_VECTORS-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
        signal TempSensInitMap: TempSensInitMap_type := (
            IRD & x"0B" & x"CB", -- Read ID R[0x0B]=0xCB
            IWR & x"2F" & x"00", -- Reset R[0x2F]=don't care
            IRD & x"0B" & x"CB" -- Read ID R[0x0B]=0xCB
            );    
        
        signal initWord: std_logic_vector (DATA_WIDTH-1 downto 0);
        signal initA : natural range 0 to NO_OF_INIT_VECTORS := 0; --init vector index
        signal initEn : std_logic;
        
        --Two-Wire Controller signals
        signal twiMsg, twiStb, twiDone, twiErr : std_logic;
        signal twiDi, twiDo, twiAddr : std_logic_vector(7 downto 0);
    
        --Wait counter used between retry attempts
        signal waitCnt : natural range 0 to DELAY_CYCLES := DELAY_CYCLES;
        signal waitCntEn : std_logic;
       
        --Retry counter to count down attempts to get rid of a bus error
        signal retryCnt : natural range 0 to RETRY_COUNT := RETRY_COUNT;
        signal retryCntEn : std_logic;    
        -- Temporary register to store received data
        signal tempReg : std_logic_vector(15 downto 0) := (others => '0');
        -- Flag indicating that a new temperature data is available
       signal fReady : boolean := false;
    begin
    
    ----------------------------------------------------------------------------------
    -- Outputs
    ----------------------------------------------------------------------------------
    TEMP_O <= tempReg(15 downto 3);
    
    RDY_O <= '1' when fReady else
                '0';
    ERR_O <= '1' when state = stError else
                '0';
    
    ----------------------------------------------------------------------------------
    -- I2C Master Controller
    ----------------------------------------------------------------------------------
    Inst_TWICtl : TWICtl
        generic map (
            ATTEMPT_SLAVE_UNBLOCK => true,
            CLOCKFREQ => 100
        )
        port map (
            MSG_I => twiMsg,
            STB_I => twiStb,
            A_I => twiAddr,
            D_I => twiDi,
            D_O => twiDo,
            DONE_O => twiDone,
          ERR_O => twiErr,
            ERRTYPE_O => open,
            CLK => CLK_I,
            SRST => SRST_I,
            SDA => TMP_SDA,
            SCL => TMP_SCL
        );
    
    ----------------------------------------------------------------------------------
    -- Initialiation Map RAM
    ----------------------------------------------------------------------------------
        initWord <= TempSensInitMap(initA);
    
        InitA_CNT: process (CLK_I) 
        begin
            if Rising_Edge(CLK_I) then
                if (state = stIdle or initA = NO_OF_INIT_VECTORS) then
                    initA <= 0;
                elsif (initEn = '1') then
                    initA <= initA + 1;
                end if;
            end if;
        end process;
        
    ----------------------------------------------------------------------------------
    -- Delay and Retry Counters
    ----------------------------------------------------------------------------------    
        Wait_CNT: process (CLK_I) 
        begin
            if Rising_Edge(CLK_I) then
                if (waitCntEn = '0') then
                    waitCnt <= DELAY_CYCLES;
                else
                    waitCnt <= waitCnt - 1;
                end if;
            end if;
        end process;
        
        Retry_CNT: process (CLK_I) 
        begin
            if Rising_Edge(CLK_I) then
                if (state = stIdle) then
                    retryCnt <= RETRY_COUNT;
                elsif (retryCntEn = '1') then
                    retryCnt <= retryCnt - 1;
                end if;
            end if;
        end process;
    
    ----------------------------------------------------------------------------------
    -- Temperature Registers
    ----------------------------------------------------------------------------------    
        TemperatureReg: process (CLK_I) 
        variable temp : std_logic_vector(7 downto 0);
        begin
            if Rising_Edge(CLK_I) then
                --MSB
                if (state = stReadTempD1 and twiDone = '1' and twiErr = '0') then
                    temp := twiDo;
                end if;
                --LSB
                if (state = stReadTempD2 and twiDone = '1' and twiErr = '0') then
                    tempReg <= temp & twiDo;
                end if;
            end if;
        end process;
        
    ----------------------------------------------------------------------------------
    -- Ready Flag
    ----------------------------------------------------------------------------------    
        ReadyFlag: process (CLK_I) 
        begin
            if Rising_Edge(CLK_I) then
                if (state = stIdle or state = stError) then
                    fReady <= false;
                elsif (state = stReadTempD2 and twiDone = '1' and twiErr = '0') then
                    fReady <= true;
                end if;
            end if;
        end process;    
        
    ----------------------------------------------------------------------------------
    -- Initialization FSM & Continuous temperature read
    ----------------------------------------------------------------------------------    
       SYNC_PROC: process (CLK_I)
       begin
          if (CLK_I'event and CLK_I = '1') then
             if (SRST_I = '1') then
                state <= stIdle;
             else
                state <= nstate;
             end if;        
          end if;
       end process;
     
       OUTPUT_DECODE: process (state, initWord, twiDone, twiErr, twiDo, retryCnt, waitCnt, initA)
       begin
            twiStb <= '0'; --byte send/receive strobe
            twiMsg <= '0'; --new transfer request (repeated start)
            waitCntEn <= '0'; --wait countdown enable
            twiDi <= "--------"; --byte to send
            twiAddr <= ADT7420_ADDR & '0'; --I2C device address with R/W bit
            initEn <= '0'; --increase init map address
            retryCntEn <= '0'; --retry countdown enable
            
            case (state) is
             when stIdle =>
                
             when stInitReg => --this state sends the register address from the current init vector
                twiStb <= '1';
                    twiMsg <= '1';
                    twiAddr(0) <= IWR; --Register address is a write
                    twiDi <= initWord(15 downto 8);
                when stInitData => --this state sends the data byte from the current init vector
                twiStb <= '1';
                    twiAddr(0) <= initWord(initWord'high); --could be read or write
                    twiDi <= initWord(7 downto 0);
                    if (twiDone = '1' and
                        (twiErr = '0' or (initWord(16) = IWR and initWord(15 downto 8) = ADT7420_RRESET)) and
                        (initWord(initWord'high) = IWR or twiDo = initWord(7 downto 0))) then
                        initEn <= '1';
                    end if;
                when stRetry=> --in case of an I2C error during initialization this state will be reached
                    if (retryCnt /= 0) then                
                        waitCntEn <= '1';
                        if (waitCnt = 0) then
                            retryCntEn <= '1';
                        end if;
                    end if;
                
                when stReadTempR => --this state sends the temperature register address
                    twiStb <= '1';
                    twiMsg <= '1';
                    twiDi <= ADT7420_RTEMP;
                    twiAddr(0) <= IWR; --Register address is a write                
                when stReadTempD1 => --this state reads the temperature MSB
                    twiStb <= '1';
                    twiAddr(0) <= IRD;
                when stReadTempD2 => --this state reads the temperature LSB
                twiStb <= '1';
                    twiAddr(0) <= IRD;
                    
                when stError => --in case of an I2C error during temperature poll
                    null; --stay here
            end case;
                
       end process;
     
       NEXT_STATE_DECODE: process (state, twiDone, twiErr, initWord, twiDo, retryCnt, waitCnt)
       begin
          --declare default state for nstate to avoid latches
          nstate <= state;  --default is to stay in current state
    
          case (state) is
             when stIdle =>
                nstate <= stInitReg;
                    
             when stInitReg =>
                if (twiDone = '1') then
                        if (twiErr = '1') then
                            nstate <= stRetry;
                        else
                            nstate <= stInitData;
                        end if;
                    end if;
                    
                when stInitData =>
                if (twiDone = '1') then
                        if (twiErr = '1') then
                            nstate <= stRetry;
                        else
                            if (initWord(initWord'high) = IRD and twiDo /= initWord(7 downto 0)) then
                                nstate <= stRetry;
                            elsif (initA = NO_OF_INIT_VECTORS-1) then
                                nstate <= stReadTempR;
                            else
                                nstate <= stInitReg;
                            end if;
                        end if;
                    end if;                
                when stRetry =>
                    if (retryCnt = 0) then
                        nstate <= stError;
                    elsif (waitCnt = 0) then
                        nstate <= stInitReg; --new retry attempt
                    end if;
                    
                when stReadTempR =>
                if (twiDone = '1') then
                        if (twiErr = '1') then
                            nstate <= stError;
                        else
                            nstate <= stReadTempD1;
                        end if;
                    end if;
                when stReadTempD1 =>
                if (twiDone = '1') then
                        if (twiErr = '1') then
                            nstate <= stError;
                        else
                            nstate <= stReadTempD2;
                        end if;
                    end if;
                when stReadTempD2 =>
                if (twiDone = '1') then
                        if (twiErr = '1') then
                            nstate <= stError;
                        else
                            nstate <= stReadTempR;
                        end if;
                    end if;
    
             when stError =>
                    null; --stay
                    
             when others =>
                nstate <= stIdle;
          end case;      
       end process;
    
    end Behavioral;
  • 相关阅读:
    简单的sql注入3
    简单的sql注入2
    简单的sql注入1
    python安装request及更新pip
    kali linux上安装ssh
    看起来有点难
    猫抓老鼠
    头有点大
    貌似有点难
    这个看起来有点简单!
  • 原文地址:https://www.cnblogs.com/429512065qhq/p/8908029.html
Copyright © 2020-2023  润新知