реклама на сайте
подробности

 
 
> Подключение AD7478A к ПЛИС по SPI, Совет, помощь,подсказка.
Hit
сообщение Mar 28 2013, 04:54
Сообщение #1





Группа: Участник
Сообщений: 13
Регистрация: 7-03-13
Пользователь №: 75 933



Здравствуйте! Необходимо подключить АЦП AD7478А к ПЛИС. На вход ацп подается последовательность импульсов с частотой 4кГц, длительностью 1 мкс. Момент прихода импульса не известен. Т.е. необходимо поставить пороговое устройство(ПУ). Поясните, пожалуйста, как в этом случае необходимо считывать данные? На форуме нашел этот код. Правда он косячный. Необходимо сформировать cs-сигнал в момент прихода разрешающего сигнала с ПУ, и в этот же момент запустить тактовые импульсы, так? Просто нужно сформировать 12 импульсов,ацп выдаст по ним данные, которые придут в регистр?
Код
d:\zwork\tlc548(9)\top_lev.vhd
1 libraryIEEE;
2 useIEEE.STD_LOGIC_1164.ALL;
3 useIEEE.STD_LOGIC_ARITH.ALL;
4 useIEEE.STD_LOGIC_UNSIGNED.ALL;
5
6 entitytop_lev is
7 port(
8 clk : in std_logic; -- External clock
9 Data_adc: in std_logic; -- Data from ADC
10 cs : in std_logic; -- External ChipSelect
11 cs_adc : out std_logic; -- ChipSelect for ADC ==-Active Low-==
12 clk_adc : out std_logic; -- Clock for ADC
13 Data_out: out std_logic_vector(7 downto 0) -- Output Vector 8 bits
14 );
15 endtop_lev;
16
17 architectureBehavioral oftop_lev is
18
19 signalD_reg : std_logic_vector(7 downto 0);
20 signalcnt : std_logic_vector(2 downto 0);
21
22 begin
23
24 clk_adc <=clk;
25 cs_adc <=cs;
26
27 process(clk)
28 begin
29 if rising_edge(clk) then
30 ifcs ='0' then
31 D_reg <=D_reg(6 downto 0) &Data_adc;
32 --else
33 --D_reg <= (others => '0');
34 end if;
35 end if;
36 end process;
37
38 process(clk,cs)
39 begin
40 ifcs ='1' then
41 cnt <= (others =>'0');
42 elsif rising_edge(clk) then
43 cnt <=cnt +'1';
44 end if;
45 end process;
46
47 Data_out <=D_reg whencnt = "00000000";
48
49 endBehavioral;
50

Прикрепил временную диаграмму АЦП.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Hit
сообщение Mar 28 2013, 08:59
Сообщение #2





Группа: Участник
Сообщений: 13
Регистрация: 7-03-13
Пользователь №: 75 933



Парад глупых вопросов.
Когда высокий уровень на CS обязательно нSCLK переключать на высокий уровень ?
Когда происходит АЦ преобразование ?
Почему 4 zero? Почему не 3 ?
Data_out <=D_reg when cnt = "00000000"; - почему на выход передаются значения в момент, когда cnt = "00000000"?
Третье состояние после последнего бита, и даже если будут входные импульсы, оно все равно сохранится ?

При поступлении сигнала от ПУ, формируется CS, поступают тактовые импульсы. С каждым тактовым импульсом АЦП выдает одно значение. Оно поступает в сдвиговый регистр. В итоге после 12 импульсов в регистре 8 битное значение. Потом тактовые импульсы продолжают поступать, на на выходе АЦП 3 состояние. Потом ждем следующий сигнал от ПУ. И опять формируем CS длительностью 10 нс. И Все ?
Нужна помощь с кодом.
Схемотехническим проектированием занимался, а вот на VHDL писал только простенькие программы. Помогите с реализацией SPI. Простенькую структуру, а то в интернете нашел вот это, но тут трудновато для моего уровня:
Код
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;

ENTITY spi_master IS
  GENERIC(
    slaves  : INTEGER := 8;  --number of spi slaves
    d_width : INTEGER := 8); --data bus width
  PORT(
    clock   : IN     STD_LOGIC;                             --system clock
    reset_n : IN     STD_LOGIC;                             --asynchronous reset
    enable  : IN     STD_LOGIC;                             --initiate transaction
    cpol    : IN     STD_LOGIC;                             --spi clock polarity
    cpha    : IN     STD_LOGIC;                             --spi clock phase
    cont    : IN     STD_LOGIC;                             --continuous mode command
    clk_div : IN     INTEGER;                               --system clock cycles per 1/2 period of sclk
    addr    : IN     INTEGER;                               --address of slave
    tx_data : IN     STD_LOGIC_VECTOR(d_width-1 DOWNTO 0);  --data to transmit
    miso    : IN     STD_LOGIC;                             --master in, slave out
    sclk    : BUFFER STD_LOGIC;                             --spi clock
    ss_n    : BUFFER STD_LOGIC_VECTOR(slaves-1 DOWNTO 0);   --slave select
    mosi    : OUT    STD_LOGIC;                             --master out, slave in
    busy    : OUT    STD_LOGIC;                             --busy / data ready signal
    rx_data : OUT    STD_LOGIC_VECTOR(d_width-1 DOWNTO 0)); --data received
END spi_master;

ARCHITECTURE logic OF spi_master IS
  TYPE machine IS(ready, execute);                           --state machine data type
  SIGNAL state       : machine;                              --current state
  SIGNAL slave       : INTEGER;                              --slave selected for current transaction
  SIGNAL clk_ratio   : INTEGER;                              --current clk_div
  SIGNAL count       : INTEGER;                              --counter to trigger sclk from system clock
  SIGNAL clk_toggles : INTEGER RANGE 0 TO d_width*2 + 1;     --count spi clock toggles
  SIGNAL assert_data : STD_LOGIC;                            --'1' is tx sclk toggle, '0' is rx sclk toggle
  SIGNAL continue    : STD_LOGIC;                            --flag to continue transaction
  SIGNAL rx_buffer   : STD_LOGIC_VECTOR(d_width-1 DOWNTO 0); --receive data buffer
  SIGNAL tx_buffer   : STD_LOGIC_VECTOR(d_width-1 DOWNTO 0); --transmit data buffer
  SIGNAL last_bit_rx : INTEGER RANGE 0 TO d_width*2;         --last rx data bit location
BEGIN
  PROCESS(clock, reset_n)
  BEGIN

    IF(reset_n = '0') THEN        --reset system
      busy <= '1';                --set busy signal
      ss_n <= (OTHERS => '1');    --deassert all slave select lines
      mosi <= 'Z';                --set master out to high impedance
      rx_data <= (OTHERS => '0'); --clear receive data port
      state <= ready;             --go to ready state when reset is exited

    ELSIF(clock'EVENT AND clock = '1') THEN
      CASE state IS               --state machine

        WHEN ready =>
          busy <= '0';             --clock out not busy signal
          ss_n <= (OTHERS => '1'); --set all slave select outputs high
          mosi <= 'Z';             --set mosi output high impedance
          continue <= '0';         --clear continue flag

          --user input to initiate transaction
          IF(enable = '1') THEN      
            busy <= '1';             --set busy signal
            IF(addr < slaves) THEN   --check for valid slave address
              slave <= addr;         --clock in current slave selection if valid
            ELSE
              slave <= 0;            --set to first slave if not valid
            END IF;
            IF(clk_div = 0) THEN     --check for valid spi speed
              clk_ratio <= 1;        --set to maximum speed if zero
              count <= 1;            --initiate system-to-spi clock counter
            ELSE
              clk_ratio <= clk_div;  --set to input selection if valid
              count <= clk_div;      --initiate system-to-spi clock counter
            END IF;
            sclk <= cpol;            --set spi clock polarity
            assert_data <= NOT cpha; --set spi clock phase
            tx_buffer <= tx_data;    --clock in data for transmit into buffer
            clk_toggles <= 0;        --initiate clock toggle counter
            last_bit_rx <= d_width*2 + conv_integer(cpha) - 1; --set last rx data bit
            state <= execute;        --proceed to execute state
          ELSE
            state <= ready;          --remain in ready state
          END IF;

        WHEN execute =>
          busy <= '1';        --set busy signal
          ss_n(slave) <= '0'; --set proper slave select output
          
          --system clock to sclk ratio is met
          IF(count = clk_ratio) THEN        
            count <= 1;                     --reset system-to-spi clock counter
            assert_data <= NOT assert_data; --switch transmit/receive indicator
            clk_toggles <= clk_toggles + 1; --increment spi clock toggles counter
            
            --spi clock toggle needed
            IF(clk_toggles <= d_width*2 AND ss_n(slave) = '0') THEN
              sclk <= NOT sclk; --toggle spi clock
            END IF;
            
            --receive spi clock toggle
            IF(assert_data = '0' AND clk_toggles < last_bit_rx + 1 AND ss_n(slave) = '0') THEN
              rx_buffer <= rx_buffer(d_width-2 DOWNTO 0) & miso; --shift in received bit
            END IF;
            
            --transmit spi clock toggle
            IF(assert_data = '1' AND clk_toggles < last_bit_rx) THEN
              mosi <= tx_buffer(d_width-1);                     --clock out data bit
              tx_buffer <= tx_buffer(d_width-2 DOWNTO 0) & '0'; --shift data transmit buffer
            END IF;
            
            --last data receive, but continue
            IF(clk_toggles = last_bit_rx AND cont = '1') THEN
              tx_buffer <= tx_data;                       --reload transmit buffer
              clk_toggles <= last_bit_rx - d_width*2 + 1; --reset spi clock toggle counter
              continue <= '1';                            --set continue flag
            END IF;
            
            --normal end of transaction, but continue
            IF(continue = '1') THEN  
              continue <= '0';      --clear continue flag
              busy <= '0';          --clock out signal that first receive data is ready
              rx_data <= rx_buffer; --clock out received data to output port    
            END IF;
            
            --end of transaction
            IF((clk_toggles = d_width*2 + 1) AND cont = '0') THEN  
              busy <= '0';             --clock out not busy signal
              ss_n <= (OTHERS => '1'); --set all slave selects high
              mosi <= 'Z';             --set mosi output high impedance
              rx_data <= rx_buffer;    --clock out received data to output port
              state <= ready;          --return to ready state
            ELSE                       --not end of transaction
              state <= execute;        --remain in execute state
            END IF;
          
          ELSE              --system clock to sclk ratio not met
            count <= count + 1; --increment counter
            state <= execute;   --remain in execute state
          END IF;

      END CASE;
    END IF;
  END PROCESS;
END logic;
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 17:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01409 секунд с 7
ELECTRONIX ©2004-2016