Thông báo

Collapse
No announcement yet.

Đọc 1 byte nhiệt độ từ TEMP275, code VHDL

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Đọc 1 byte nhiệt độ từ TEMP275, code VHDL

    Chào các bạn !
    Mình đang phải đọc nhiệt độ từ con cảm biến nhiệt số TEMP275. Hiện là code VHDL đã viết xong, mo phỏng bằng Modelsim thì thấy là được. Nhưng cho vào mạch thật , sử dụng Kit Alter DE2-115 để test và mo phỏng bằng SIGNALTAB thì chưa đọc được nhiệt độ.
    Rất mong nhận được sự giúp đỡ của các bạn trên diễn đàn này !!!
    -- doc 1byte nhiet do tu TEMP275
    Library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    use ieee.std_logic_arith.all;

    entity TEMP275 is
    generic( input_clk: integer := 50_000_000;
    bus_clk: integer:= 400_000
    );
    port ( clk: in std_logic;
    clk1: out std_logic; -- xung clock = 1200_000 Hz de soi tren signaltab
    SCL: out std_logic;
    SDA: inout std_logic;
    data_out: out std_logic_vector(7 downto 0)
    );
    end TEMP275;

    architecture arch of TEMP275 is

    signal ena: std_logic := '0'; -- cho phep qua trinh lam viec bat dau
    signal addr: std_logic_vector(6 downto 0):= "1001000";
    signal rw: std_logic; -- viet khi rw =0, doc khi rw =1
    signal data_rd: std_logic_vector(7 downto 0):= "00000000"; -- thanh ghi doc du lieu tu TEMP275

    constant divider : integer := (input_clk/bus_clk)/4; -- number of clocks in 1/4 cycle of SCL
    constant divider1 : integer := divider*4/8;
    TYPE machine is (ready, start, command, slv_ack1, wr1, slv_ack2, wr2, slv_ack3,stop, ready1, start1, command1, slv_ack4, rd, mstr_ack, stop1, ready2, start2, command2, slv_ack5); -- mo ta trang thai

    signal state : machine := ready; -- state machine
    signal data_clk : std_logic; -- xung clock cho SDA
    SIGNAL scl_clk : STD_LOGIC; --constantly running internal scl
    SIGNAL scl_ena : STD_LOGIC := '0'; --enables internal scl to output
    SIGNAL sda_out : STD_LOGIC := '1'; --internal sda
    --signal sda_int : std_logic:= '1';
    SIGNAL sda_ena_n : STD_LOGIC; --enables internal sda
    SIGNAL data_tx : STD_LOGIC_VECTOR(7 DOWNTO 0); --latched in data to write to slave
    SIGNAL data_rx : STD_LOGIC_VECTOR(7 DOWNTO 0); --data received from slave
    SIGNAL bit_cnt : INTEGER RANGE 0 TO 7 := 7; --tracks bit number in transaction
    SIGNAL addr_rw : STD_LOGIC_VECTOR(7 DOWNTO 0); --latched in address and read/write


    begin

    --generate the timing for the bus clock (scl_clk) and the data clock (data_clk)
    PROCESS(clk)
    VARIABLE count : INTEGER RANGE 0 TO divider*4 := 0; --timing for clock generation
    BEGIN

    IF(clk'EVENT AND clk = '1') THEN
    count := count + 1;
    IF(count = divider*4-1) THEN --end of timing cycle
    count := 0; --reset timer
    END IF;
    CASE count IS
    WHEN 0 TO divider-1 => --first 1/4 cycle of clocking
    scl_clk <= '0';
    data_clk <= '0';
    WHEN divider TO divider*2-1 => --second 1/4 cycle of clocking
    scl_clk <= '0';
    data_clk <= '1';
    WHEN divider*2 TO divider*3-1 => --third 1/4 cycle of clocking
    scl_clk <= '1'; --release scl
    data_clk <= '1';
    WHEN OTHERS => --last 1/4 cycle of clocking
    scl_clk <= '1';
    data_clk <= '0';
    END CASE;
    END IF;


    END PROCESS;


    -- bo chia tan 800KHz dung de soi tren signalTAB --50*10^6/800*10^3
    process(clk)
    VARIABLE cnt_div : INTEGER range 0 to divider1:= 0;
    variable f : std_logic;
    begin
    if rising_edge(clk) then
    cnt_div := cnt_div + 1;
    if(cnt_div = divider1) then
    cnt_div := 0;
    f := not f;
    end if;
    end if;
    clk1 <= f;
    end process;



    --state machine and writing to sda during scl low (data_clk rising edge)

    PROCESS(data_clk)

    BEGIN
    IF(data_clk'EVENT AND data_clk = '1') THEN
    CASE state IS
    -- Init TEMP275
    WHEN ready => -- trang thai nghi, chuan bi cho truyen du lieu
    sda_out <= '1';
    ena <= '1'; -- cho phep viet lenh
    addr_rw <= "10010000";
    data_tx <= "00000001";
    state <= start;

    WHEN start => -- bit start
    scl_ena <= '1';
    sda_out <= addr_rw(bit_cnt);
    state <= command;

    WHEN command => -- dia chi TEMP275
    IF(bit_cnt = 0) THEN
    sda_out <= 'Z'; -- cho bit ACK tu slave
    bit_cnt <= 7;
    state <= slv_ack1;
    ELSE
    bit_cnt <= bit_cnt - 1;
    sda_out <= addr_rw(bit_cnt-1);
    state <= command;

    END IF;
    WHEN slv_ack1 => -- nhan bit ack tu TEMP275
    rw <= '0';

    sda_out <= data_tx(bit_cnt);
    state <= wr1;

    when wr1 => -- SELECT RES CONFIG
    if(bit_cnt = 0) then
    sda_out <= 'Z';
    bit_cnt <= 7;
    data_tx <= "00000000";
    state <= slv_ack2;
    else
    bit_cnt <= bit_cnt - 1;
    sda_out <= data_tx(bit_cnt - 1);
    state <= wr1;
    end if;

    when slv_ack2 =>
    rw <= '0';

    sda_out <= data_tx(bit_cnt);
    state <= wr2;

    when wr2 =>
    if(bit_cnt = 0) then
    sda_out <= 'Z';
    bit_cnt <= 7;
    state <= slv_ack3;
    else
    bit_cnt <= bit_cnt - 1;
    sda_out <= data_tx(bit_cnt - 1);
    state <= wr2;
    end if;

    when slv_ack3 =>
    sda_out <= '1';
    ena <= '0';
    scl_ena <= '0';
    state <= stop;

    when stop =>

    state <= ready1;


    -- Qua trinh doc du lieu tu TEMP275
    when ready1 =>

    ena <= '1';
    addr_rw <= "10010000";
    data_tx <= "00000000";
    state <= start1;

    when start1 =>
    scl_ena <= '1';
    sda_out <= addr_rw(bit_cnt);
    state <= command1;

    when command1 =>
    IF(bit_cnt = 0) THEN
    sda_out <= 'Z'; -- cho bit ACK tu slave
    bit_cnt <= 7;
    state <= slv_ack4;
    ELSE
    bit_cnt <= bit_cnt - 1;
    sda_out <= addr_rw(bit_cnt-1);
    state <= command1;
    END IF;

    when slv_ack4 =>
    ena <= '0' ;
    sda_out <= '1';
    scl_ena <= '0';
    state <= ready2;
    when ready2 =>
    ena <= '1';
    addr_rw <= "10010001";
    state <= start2;
    when start2 =>
    scl_ena <= '1';
    sda_out <= addr_rw(bit_cnt);
    state <= command2;
    when command2 =>
    if(bit_cnt = 0) then
    sda_out <= 'Z';
    bit_cnt <= 7;
    state <= slv_ack5;
    else
    bit_cnt <= bit_cnt - 1;
    sda_out <= addr_rw(bit_cnt - 1);
    state <= command2;
    end if;
    when slv_ack5 =>
    rw <= '1';
    sda_out <= '1';
    state <= rd;
    when rd =>
    if (bit_cnt = 0) then
    sda_out <= '0';
    bit_cnt <= 7;
    data_rd <= data_rx;
    state <= mstr_ack;
    else
    bit_cnt <= bit_cnt - 1;
    state <= rd;
    end if;

    when mstr_ack =>
    ena <= '0';
    scl_ena <= '0';

    state <= stop1;

    when stop1 => -- bit STOP

    sda_out <= '1';
    state <= ready2;

    END CASE;


    END IF;
    if (data_clk'event and data_clk ='0') then
    case state is
    when rd =>
    data_rx(bit_cnt) <= sda;
    when others => Null;
    end case;
    end if;

    END PROCESS;


    --set sda output
    WITH state SELECT
    sda_ena_n <= data_clk WHEN start, --generate start condition
    data_clk when start1,
    data_clk when start2,
    not data_clk when stop1,

    not data_clk WHEN stop, --generate stop condition

    'Z' when rd,
    sda_out WHEN OTHERS; --set to internal sda signal

    --set scl and sda outputs
    SCL <= scl_clk when scl_ena = '1' else '1';

    sda <= sda_ena_n;


    end arch;
    Attached Files

  • #2
    Nguyên văn bởi zhounguyen Xem bài viết
    Chào các bạn !
    Mình đang phải đọc nhiệt độ từ con cảm biến nhiệt số TEMP275. Hiện là code VHDL đã viết xong, mo phỏng bằng Modelsim thì thấy là được. Nhưng cho vào mạch thật , sử dụng Kit Alter DE2-115 để test và mo phỏng bằng SIGNALTAB thì chưa đọc được nhiệt độ.
    Rất mong nhận được sự giúp đỡ của các bạn trên diễn đàn này !!!
    Trong SIGNALTAP, statemachine của bạn chạy tới đâu? Bạn co' thê add statemachine trong pop-up menu sau khi right-click!

    Bạn coi lại:
    - Address đúng chưa,
    - Read/Write bit đúng chưa
    - Slave co' "ACK" không

    Comment


    • #3
      Adress+bit read/write , mọi thứ đều đúng rồi bạn ah. Có lẽ đang bị tranh chấp dữ liệu ở dây SDA khi viết và khi đọc.

      Comment


      • #4
        Nguyên văn bởi zhounguyen Xem bài viết
        Adress+bit read/write , mọi thứ đều đúng rồi bạn ah. Có lẽ đang bị tranh chấp dữ liệu ở dây SDA khi viết và khi đọc.
        Nước này thì bạn đi kiếm cai oscilloscope để coi tín hiệu tại chân của tempsensor là gì?

        Comment


        • #5
          Mình đã kiểm tra rồi, vấn đề là ở code VHDL của mình, tại vì mạch thật đã có người test thành công bằng code AHDL.
          Mong các bạn tư vấn thêm !

          Comment


          • #6
            em cũng đang tìm hiểu về FPGA với cảm biến nhiệt Ds18b20 ...không biết anh có thế cho em out source không ... có thể thể tìm hiểu và phát triển ... nếu được có thể gủi qua mail hoangthinh195@gmail.com.Xin cảm ơn a trước

            Comment

            Về tác giả

            Collapse

            zhounguyen Tìm hiểu thêm về zhounguyen

            Bài viết mới nhất

            Collapse

            Đang tải...
            X