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;