En este momento estoy tratando de usar MCP3008 como un ADC, pero por alguna razón no convierte la salida correctamente. (Un proyecto para principiantes).
Le proporciono un 3.3 V = vref = Vdd = ch0
Pero mi salida parece que nunca se convierte en = > 1111111111, sino algo así como 1111010111 ...
Lo programo en un FPGA, usando VHDL.
FPGa CLK: 50 mhz.
Aquí está el código:
ibrary IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_logic_unsigned.all;
use ieee.numeric_std.all;
entity main is
Port ( MISO : in STD_LOGIC;
MOSI : out STD_LOGIC;
CS : out STD_LOGIC;
SCLK : out STD_LOGIC;
CLK : in STD_LOGIC;
);
end main;
architecture Behavioral of main is
constant N : integer := 4;
signal prescaler_counter : integer range 0 to 50000000 := 0;
signal newClock : std_logic := '0';
signal TX :std_logic_vector(N downto 0) := "11000";
signal RX : std_logic_vector(9 downto 0) := "0000000000";
type state_type is (start,state2,state3,state4,state5); --type of state machine.
signal state : state_type := start;
signal shift_counter: integer range 0 to 750:= N;
begin
prescaler01: process(clk, newClock)
begin
if rising_edge(clk) then
if prescaler_counter < 1000000 then
prescaler_counter <= prescaler_counter + 1;
else
newClock <= not newClock;
prescaler_counter <= 0;
end if;
end if;
end process;
SCLK <= newClock;
SPI_state: process(newClock)
begin
if falling_edge(newClock) then
case state is
when start =>
CS <= '1';
MOSI <= '0';
busy <= '1';
RX <= "0000000000";
state <= state2;
when state2 => -- Send init bits.
CS <= '0';
shift_counter <= shift_counter - 1;
TX <= TX(N-1 downto 0) & TX(N);
MOSI <= TX(N);
if shift_counter = 0 then
MOSI <= '0';
shift_counter<= 12;
state <= state3;
end if;
when state3 =>
--MOSI <= '0';
CS <= '0'; -- Last bit init bit;
state <= state5;
when state4=>
CS <= '0'; --T_sample from falling - falling
state <= state5;
when state5=>
CS <= '0'; -- Read
if shift_counter = 0 then
MOSI <= '0';
shift_counter<= N;
busy <= '0';
state <= start;
elsif shift_counter < 11 then
RX <= RX(8 downto 0) & MISO;
shift_counter <= shift_counter - 1;
else
shift_counter <= shift_counter - 1;
end if;
when others =>
state <= start;
end case;
end if;
end process;
Creo que mi tiempo puede estar un poco fuera ... Aunque lo ajusté en simulaciones ... Entonces, no tiene sentido, por qué la salida no parece correcta ...
La ayuda es muy apreciada :).
Sé que esta pregunta tendrá muchos votos a la baja, debido al nivel de dificultad de la pregunta, pero tengo que comenzar en alguna parte.
-edit-
Probé la simulación que Lincoln publicó como una respuesta que muestra que el tiempo no está apagado. Agregué debug_tx que muestra en qué estado se encuentra el programa en este momento.
- debug_tx:="0001": establece CS alto, por lo que la entrada se restablece.
- debug_tx:="0010" - Enviar bit de inicio "11000" = > inicio bit + peform ADC, entrada CH0.
- debug_tx:="0100" - delay - Tiempo necesario para el ADC
- Debug_tx:="1000" - delay - omite la primera nulbit.
- debug_tx:="1101" - lea - 9 veces y realice los valores de cambio a dejado como tal.
Estoy bastante seguro de que algo está mal con la forma en que estoy cambiando las cosas ... O tal vez algo más ...
RX <= RX(8 downto 0) & MISO;
Rx_Led muestra el valor binario de la salida que lee ... Parece que los dos últimos turnos se han estancado en periodos de 2 clics cada uno ... Lo que parece extraño ...
Nota al margen, solo estoy aplicando el sistema 3.3V, pero he hecho una escala previa del reloj a 5-10 hz, por lo que debería ser un problema con la diferencia de tiempo de la aplicación de 5 V o 3 V.