Eduardo Posted April 14, 2013 Report Share Posted April 14, 2013 Hi, i have been working with the p1 500k board since last month with the help of Hamster's tutorial and some posts of the forum, where i have learned a lot that's why I thank all who contribute to the papilio project and hope I can also contribute myself in the future. But now I'm having trouble making the ADC of the logic starter megawing work, I tried directly with the code that Hamster gives in his tutorial and when I was trying to read 3.3V in the channel 0 of the ADC, what the LEDs show is "0b10101100" what confuses me because I thought i should see "0b11111111" as 3.3V is the maximum value that the 12 bit ADC can read. So since i couldn't really understand if the code of the tutorial uses the 8 most significant bits of the 12 bit ADC output value to light up the LEDs, i thought that i should use the recommended code ( -- Normally you would grab "datain_shiftreg(10 downto 0) & adc_dout" for 12 bits) to output the 12 bits and then display that value on the Seven seg display in hex. Also I did it and now the displays show "0B72" with 3.3 V and "0037" with 0.0V, what just looks like the same problem before. So my question is, how do I send the correct 12/8 bits output value of the ADC to the displays/Leds in the logic starter mega wing, what am i missing? Is it a problem with the hardware? Because i was trying it with an external 3.3V voltage source and a potentiometer, but then i used the 3.3V and 2.5V voltage lines of the logic starter megawing and just ended with the same results. I also saw in the datasheet of the ADC128S102 that i could use a 22ohm resistor and a 1nF capacitor, but I don't really think that will solve the problem. The code that I'm using with the Leds is the following:library IEEE;use IEEE.STD_LOGIC_1164.ALL;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned valuesuse IEEE.NUMERIC_STD.ALL;-- Uncomment the following library declaration if instantiating-- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity adc is port ( clk : IN std_logic; -- user interface switches : IN std_logic_vector(2 downto 0); leds : OUT std_logic_vector(7 downto 0); -- Signals to the ADC ADC_CS_N : OUT std_logic; ADC_SCLK : OUT std_logic; ADC_DIN : OUT std_logic; ADC_DOUT : IN std_logic );end adc;architecture Behavioral of adc is -- Counter - the lowest 6 bits are used to control signals to the ADC. -- The rest are used to activate the ADC when 0 signal counter : std_logic_vector(22 downto 0) := (others =>'0'); -- shift registers to delay output signals signal clk_shiftreg : std_logic_vector( 1 downto 0) := (others =>'0'); signal dataout_shiftreg : std_logic_vector( 2 downto 0) := (others =>'0'); -- shift register to collect incoming bits signal datain_shiftreg : std_logic_vector(11 downto 0) := (others =>'0'); -- register to hold the current channel signal channel_hold : std_logic_vector( 2 downto 0) := (others =>'0'); signal adc_active : std_logic;begin -- set outgoing signals ADC_DIN <= dataout_shiftreg(2); ADC_SCLK <= clk_shiftreg(1); with counter(22 downto 6) select adc_active <= '1' when "00000000000000000", '0' when others; process (clk) begin if rising_edge(clk) then-- A small shift register delays the clk by one cycle (31.25ns) to ensure timings are -met. clk_shiftreg(1) <= clk_shiftreg(0); -- Including adc_cs_n in a clocked process to ensure that it is adc_cs is implemented -in a flipflop ADC_CS_N <= not(adc_active); if adc_active = '1' then clk_shiftreg(0) <= counter(1); else clk_shiftreg(0) <= '1'; end if; -- This controls where we send out the address to the ADC (bits 2,3 and 4 of the -stream)-- we use a short shift register to ensure that the ADC_DOUT transistions are delayed-- 31 ns or so from the clk transitions dataout_shiftreg(2 downto 1) <= dataout_shiftreg(1 downto 0); if adc_active = '1' then case counter(5 downto 2) is when "0010" => dataout_shiftreg(0) <= channel_hold(2); when "0011" => dataout_shiftreg(0) <= channel_hold(1); when "0100" => dataout_shiftreg(0) <= channel_hold(0); when others => dataout_shiftreg(0) <= '0'; end case; -- As counter(2) is used used to generate sclk, this test ensures that we -- capture bits right in the middle of the clock pulse if counter(5 downto 0) = "000000" then channel_hold <= switches; end if; if counter(1 downto 0) = "11" then datain_shiftreg <= datain_shiftreg(10 downto 0) & ADC_DOUT; end if; -- When we have captured the last bit it is the time to update the output. if counter(5 downto 0) = "111111" then -- Normally you would grab "datain_shiftreg(10 downto 0) & adc_dout" for 12 bits LEDs <= datain_shiftreg(10 downto 3) ; end if; else dataout_shiftreg(0) <= '0'; end if; counter <= STD_LOGIC_VECTOR(UNSIGNED(counter)+1); end if; end process; end Behavioral;And the code I'm using fo the the seven seg display is:library IEEE;use IEEE.STD_LOGIC_1164.ALL;-- Uncomment the following library declaration if using-- arithmetic functions with Signed or Unsigned valuesuse IEEE.NUMERIC_STD.ALL;-- Uncomment the following library declaration if instantiating-- any Xilinx primitives in this code.--library UNISIM;--use UNISIM.VComponents.all;entity adc is port ( clk : IN std_logic; -- user interface switches : IN std_logic_vector(2 downto 0); anodes : OUT std_logic_vector(3 downto 0); segments : OUT std_logic_vector(6 downto 0); dp : OUT std_logic; -- Signals to the ADC ADC_CS_N : OUT std_logic; ADC_SCLK : OUT std_logic; ADC_DIN : OUT std_logic; ADC_DOUT : IN std_logic );end adc;architecture Behavioral of adc is -- Counter - the lowest 6 bits are used to control signals to the ADC. -- The rest are used to activate the ADC when 0 signal counter : std_logic_vector(22 downto 0) := (others =>'0'); -- shift registers to delay output signals signal clk_shiftreg : std_logic_vector( 1 downto 0) := (others =>'0'); signal dataout_shiftreg : std_logic_vector( 2 downto 0) := (others =>'0'); -- shift register to collect incoming bits signal datain_shiftreg : std_logic_vector(11 downto 0) := (others =>'0'); -- register to hold the current channel signal channel_hold : std_logic_vector( 2 downto 0) := (others =>'0'); signal adc_active : std_logic; signal sensor_value : std_logic_vector( 11 downto 0) := (others =>'0'); COMPONENT display4digits PORT( clk : IN std_logic; digit0 : IN std_logic_vector(3 downto 0); digit1 : IN std_logic_vector(3 downto 0); digit2 : IN std_logic_vector(3 downto 0); digit3 : IN std_logic_vector(3 downto 0); anodes : OUT std_logic_vector(3 downto 0); sevenseg : OUT std_logic_vector(6 downto 0); dp : OUT std_logic ); END COMPONENT;begin -- set outgoing signals ADC_DIN <= dataout_shiftreg(2); ADC_SCLK <= clk_shiftreg(1); with counter(22 downto 6) select adc_active <= '1' when "00000000000000000", '0' when others; Inst_display4digits: display4digits PORT MAP( clk => clk, digit0 => sensor_value(3 downto 0), digit1 => sensor_value(7 downto 4), digit2 => sensor_value(11 downto 8), digit3 => "0000", anodes => anodes, sevenseg => segments, dp => dp ); process (clk) begin if rising_edge(clk) then -- A small shift register delays the clk by one cycle (31.25ns) to ensure timings are -met. clk_shiftreg(1) <= clk_shiftreg(0); -- Including adc_cs_n in a clocked process to ensure that it is adc_cs is implemented -in a flipflop ADC_CS_N <= not(adc_active); if adc_active = '1' then clk_shiftreg(0) <= counter(1); else clk_shiftreg(0) <= '1'; end if; -- This controls where we send out the address to the ADC (bits 2,3 and 4 of the -stream) -- we use a short shift register to ensure that the ADC_DOUT transistions are delayed -- 31 ns or so from the clk transitions dataout_shiftreg(2 downto 1) <= dataout_shiftreg(1 downto 0); if adc_active = '1' then case counter(5 downto 2) is when "0010" => dataout_shiftreg(0) <= channel_hold(2); when "0011" => dataout_shiftreg(0) <= channel_hold(1); when "0100" => dataout_shiftreg(0) <= channel_hold(0); when others => dataout_shiftreg(0) <= '0'; end case; -- As counter(2) is used used to generate sclk, this test ensures that we -- capture bits right in the middle of the clock pulse if counter(5 downto 0) = "000000" then channel_hold <= switches; end if; if counter(1 downto 0) = "11" then datain_shiftreg <= datain_shiftreg(10 downto 0) & ADC_DOUT; end if; -- When we have captured the last bit it is the time to update the output. if counter(5 downto 0) = "111111" then -- Normally you would grab "datain_shiftreg(10 downto 0) & adc_dout" for 12 bits sensor_value <= datain_shiftreg(10 downto 0) & ADC_DOUT; end if; else dataout_shiftreg(0) <= '0'; end if; counter <= STD_LOGIC_VECTOR(UNSIGNED(counter)+1); end if; end process; end Behavioral;I also tried "sensor_value <= datain_shiftreg(11 downto 0);" instead of "sensor_value <= datain_shiftreg(10 downto 0) & ADC_DOUT;" what I thought was the correct code to use but it just gave me "05A6" with 3.3 V and "000B" with 0.0V. Sorry if this question has been asked before but I just couldn't find anything in the forum. Thanks in advance, Eduardo Link to comment Share on other sites More sharing options...
Eduardo Posted April 18, 2013 Author Report Share Posted April 18, 2013 I'm still not able to understand how this code is supposed to work, i would really appreciate some help around here. By the way, when i´m supposed to be reading an adc value, the leds don´t remain stable, they keep changing every time. I also tried the "ZPUino Test Code for the LogicStart MegaWing" in order to see if the ADC128S102 is working as it should, but the bit file didn´t work, i couldn´t see anything clear in my monitor, does anyone knows if that bit file is working? Link to comment Share on other sites More sharing options...
Eduardo Posted April 18, 2013 Author Report Share Posted April 18, 2013 If I use the following line: "LEDs <= datain_shiftreg(7 downto 0) ;" am i supposed to be printing the first 8 bits of the adc? Link to comment Share on other sites More sharing options...
hamster Posted April 18, 2013 Report Share Posted April 18, 2013 Hi Eduardo, Can you run a "clean up project files" and email me a zip of your project at hamster@snap.net.nz ? I'll have a look over it for you over the weekend. Mike Link to comment Share on other sites More sharing options...
Eduardo Posted April 18, 2013 Author Report Share Posted April 18, 2013 Hi Mike, Yeah, I just did it, thank you! Eduardo Link to comment Share on other sites More sharing options...
hamster Posted April 19, 2013 Report Share Posted April 19, 2013 Hi Eduardo, After checking your code I think we have both missed that the ADC's VA (Analog/reference voltage) is connected to 5.0V... and 5.0V does read about x0FE0. I've sent you the test bench I used to verify that the ADC was correctly capturing the data. If you initialise "counter" in your ADC to something like "11111111111100000000000" you will only have to simulate 64us or so before the ADC conversion will begin. Link to comment Share on other sites More sharing options...
Eduardo Posted April 21, 2013 Author Report Share Posted April 21, 2013 Thanks a lot Mike, you saved my day. I should have checked out how the ADC is connected in the Logic Start Mega Wing, but I really thought the reference voltage was 3.3V because of what you say in your book about connecting the ADC to 5V. But anyway the upadate you did to my display4digit module really improve how the 7segment displays show the value the ADC reads, now I am able to read a stable value (without burning my eyes haha). Link to comment Share on other sites More sharing options...
Tkay Posted November 5, 2015 Report Share Posted November 5, 2015 Hie I am curious to know why do you access the control register from 10 and not 11 looking at the way you did it. "datain_shiftreg(10 downto 0) & ADC_DOUT" Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.