[Numérique] Delay dans mon implementation de la transmission SPI
Répondre à la discussion
Affichage des résultats 1 à 9 sur 9

Delay dans mon implementation de la transmission SPI



  1. #1
    invite562bcc10

    Delay dans mon implementation de la transmission SPI


    ------

    Bonjour,

    J'essaye de faire la transmission SPI qui respecte cette photo:
    SPI transmission.png

    J'ai fais le composant en utilisant le syntaxe de FSM du cour: je obtiens ca:
    tb_emission_spi.png

    le code est :
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    
    entity SPI_TX is
        Port ( data_in : in  STD_LOGIC_VECTOR (7 downto 0);
               spi_start : in  STD_LOGIC;
               rst : in  STD_LOGIC;
               clk : in  STD_LOGIC;
               SPI_CS : out  STD_LOGIC;
               SPI_SCK : out  STD_LOGIC;
               SPI_MOSI : out  STD_LOGIC);
    end SPI_TX;
    
    architecture Behavioral of SPI_TX is
    
        type T_etat is (idle,bitsdata);
        signal next_etat, reg_etat : T_etat;
        signal next_bitcpt, reg_bitcpt : unsigned (2 downto 0); --compte le bit qu'on veut passer en serie
        signal txdatas_next, txdatas_reg : STD_LOGIC_VECTOR (7 downto 0);-- pour enlever bit par bit et les passer en serie
        signal cpt_spi : STD_LOGIC ; -- signal pour faire le SPI_CLK
        signal CS_reg,CS_next : STD_LOGIC ;
        signal MOSI_reg,MOSI_next : STD_LOGIC ;
    
    begin
    
        etat_suivant: process(data_in,spi_start,reg_etat,reg_bitcpt,txdatas_reg,CS_reg,MOSI_reg,cpt_spi)
            begin
                next_etat <= reg_etat;
                --SPI_MOSI <= '0';
                --SPI_CS <= '1';
                next_bitcpt <= reg_bitcpt;
                txdatas_next <= txdatas_reg;
                CS_next <= CS_reg;
                MOSI_next <= MOSI_reg;
    
                case reg_etat is
                    when idle =>
                        MOSI_next <= '0';
                       CS_next <= '1';
                        next_bitcpt <= (others =>'0');
    
                        if spi_start ='1' then
                            txdatas_next <= data_in;
                            next_etat <= bitsdata;
                        end if;
    
                    when bitsdata =>
                        CS_next <= '0';
                        if cpt_spi = '1' then -- if put rising_edge(cpt_spi) it doesn't work 
                            MOSI_next <= txdatas_reg(0) ;
                            txdatas_next <= '0' &txdatas_reg(7 downto 1);
                            if reg_bitcpt = "111" then  -- if the 8 data bits have been sent
                                next_etat <= idle ;
                            else
                                next_bitcpt <= reg_bitcpt + 1 ;
                            end if;
                        end if;
                end case;
        end process etat_suivant;
        SPI_SCK<=cpt_spi;
        SPI_CS<=CS_reg;
        SPI_MOSI<=MOSI_reg;
        -- Creating SPI_clk (ici c'est le clk /2)
        compteur: process(clk)
            begin
            if rst = '1' then
                cpt_spi <=  '0';
            else
                if rising_edge(clk) then
                    if CS_reg = '0' then
                        if cpt_spi='1' then
                            cpt_spi <='0';
                        else 
                            cpt_spi <=  '1';
                        end if; 
                    else  --CS_reg=1
                        cpt_spi <='0';
    
                    end if ;
                end if; 
            end if;
        end process compteur;
    
    
    
        registre_etat: process(clk)
         begin
            if rising_edge(clk) then
                if rst = '1' then
                    reg_etat <= idle;
                    reg_bitcpt <= (others =>'0');
                    txdatas_reg <=(others =>'0') ;
                    CS_reg<='1';
                    MOSI_reg<='0';
    
                else
                    reg_etat <= next_etat;
                    reg_bitcpt <= next_bitcpt;
                    txdatas_reg <=txdatas_next;
                    CS_reg<=CS_next ;
                    MOSI_reg<=MOSI_next ;
                end if;
            end if;
        end process registre_etat;
    
    end Behavioral;
    Ayant été bloqué j'ai fais avec la methode plus facile et plus claire (en faisant une seul process) j'obtiens ca :

    tb_emission_spi_one_process.png

    Le code est:
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    
    entity SPI_TX is
        Port ( data_in : in  STD_LOGIC_VECTOR (7 downto 0);
               spi_start : in  STD_LOGIC;
               rst : in  STD_LOGIC;
               clk : in  STD_LOGIC;
               SPI_CS : out  STD_LOGIC;
               SPI_SCK : out  STD_LOGIC;
               SPI_MOSI : out  STD_LOGIC);
    end SPI_TX;
    
    architecture Behavioral of SPI_TX is
    
    	type T_etat is (idle,bitsdata);
    	signal reg_etat : T_etat;
    	signal reg_bitcpt : unsigned (3 downto 0); --compte le bit qu'on veut passer en serie
    	signal txdatas_reg : STD_LOGIC_VECTOR (7 downto 0);-- pour enlever bit par bit et les passer en serie
    	signal cpt_spi: STD_LOGIC ; -- signal pour faire le SPI_CLK
    	signal CS_reg,CS_next : STD_LOGIC ;
    	signal MOSI_reg,MOSI_next : STD_LOGIC ;
    
    begin
    ----------------------------------------------------------------------------------
      etat_suivant: process(CLK,rst)
      begin
        if rising_edge(CLK) then
    		if rst = '1' then
    			reg_etat <= idle;
    			reg_bitcpt <= (others =>'0');
    			txdatas_reg <=(others =>'0') ;
    			CS_reg<='1';
    			MOSI_reg<='0';
          else
    			case reg_etat is
    				when idle =>
    					MOSI_reg <= '0';
    				   CS_reg <= '1';
    					reg_bitcpt <= (others =>'0');
    
    					if spi_start ='1' then
    						txdatas_reg <= data_in;
    						reg_etat <= bitsdata;
    					end if;
    							
    				when bitsdata =>
    					CS_reg <= '0';
    					if cpt_spi = '0' then 
    						--if CS_reg = '0' then
    							MOSI_reg <= txdatas_reg(0) ;
    							txdatas_reg <= '0' &txdatas_reg(7 downto 1);
    							if reg_bitcpt = "1000" then  -- if the 8 data bits have been sent
    								reg_etat <= idle ;
    							else
    								reg_bitcpt <= reg_bitcpt + 1 ;
    							end if;
    						--end if;
    					end if;
    				when others => -- il faut TOUJOURS un "when others"  car ton "CASE" n'énumère pas forcement tous les  as possibles
    					assert (false) report "Unsupported state"severity failure ;-- au cas ou il y aurait un bug qq part cela remonte en simulation
    				end case;
    		 end if;
    	end if;
    
    	end process etat_suivant;
    	
    	SPI_SCK<=cpt_spi;
    	SPI_CS<=CS_reg;
    	SPI_MOSI<=MOSI_reg;
    	
    ------------------------------------------------------------------------------------
    	-- Creating SPI_clk (ici c'est le clk /2)
    	compteur: process(clk)
    		begin
    		if rst = '1' then
    			cpt_spi <=  '0';
    		else
    			if rising_edge(clk) then
    				if CS_reg = '0' then
    					if cpt_spi='1' then
    						cpt_spi <='0';
    					else 
    						cpt_spi <=  '1';
    					end if; 
    				else  --CS_reg=1
    					cpt_spi <='0';
    
    				end if ;
    			end if; 
    		end if;
    	end process compteur;
    end Behavioral;
    Mes questions comment peut on faire pour corriger les 2 codes pour avoir un resultat similaire au premier photo.

    Merci

    -----

  2. #2
    jiherve

    Re : Delay dans mon implementation de la transmission SPI

    Bonjour,
    çà cela doit aller!
    Code:
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    
    entity SPI_TX is
        Port ( DATA_IN : in  STD_LOGIC_VECTOR (7 downto 0);
               SPI_START : in  STD_LOGIC;
               RST : in  STD_LOGIC;
               CLK : in  STD_LOGIC;
               SPI_CS : out  STD_LOGIC;
               SPI_SCK : out  STD_LOGIC;
               SPI_MOSI : out  STD_LOGIC);
    end SPI_TX;
    
    architecture Behavioral of SPI_TX is
    
      type T_etat is (idle,bitsdata);
      signal reg_etat : T_etat;
      signal reg_bitcpt : unsigned (3 downto 0); --compte le bit qu'on veut passer en serie
      signal txdatas_reg : STD_LOGIC_VECTOR (7 downto 0);-- pour enlever bit par bit et les passer en serie
      signal cpt_spi: STD_LOGIC ; -- signal pour faire le SPI_CLK
      signal CS_reg : STD_LOGIC ;
    
    begin
    ----------------------------------------------------------------------------------
      etat_suivant: process(CLK,RST)
      begin
        if RST = '1' then
           reg_etat     <= idle;
           reg_bitcpt   <= (others =>'0');
           txdatas_reg  <=(others =>'0') ;
           CS_reg       <='1';
        elsif rising_edge(CLK) then
          case reg_etat is
            when idle =>
              if spi_start = '1' then
                txdatas_reg <= data_in;
                reg_etat    <= bitsdata;
                CS_reg      <= '0';
              else
                txdatas_reg <= (others => 0);
                CS_reg <= '1';
                reg_bitcpt <= (others => 0);
              end if;
                  
            when bitsdata =>
              if cpt_spi = '1' then 
                txdatas_reg <= '0' & txdatas_reg(7 downto 1);
                if reg_bitcpt = "0111" then  -- if the 8 data bits have been sent
                  reg_etat <= idle ;
                  CS_reg <= '1';
                else
                  reg_bitcpt <= reg_bitcpt + 1 ;
                end if;
              end if;
    
            when others => -- il faut TOUJOURS un "when others"  car ton "CASE" n'énumère pas forcement tous les  as possibles
              assert (false) report "Unsupported state"severity failure ;-- au cas ou il y aurait un bug qq part cela remonte en simulation
            end case;
         end if;
      end if;
    
      end process etat_suivant;
      
      SPI_SCK   <= cpt_spi;
      SPI_CS    <= CS_reg;
      SPI_MOSI  <= txdatas_reg(0);
      
    ------------------------------------------------------------------------------------
      -- Creating SPI_clk (ici c'est le clk /2)
      compteur: process(CLK,RST)
        begin
        if RST = '1' then
          cpt_spi <=  '0';
        elsif rising_edge(clk) then
            if CS_reg = '0' then
              cpt_spi <= not cpt_spi;
            else  --CS_reg=1
              cpt_spi <='0';
            end if ;
          end if; 
        end if;
      end process compteur;
    end Behavioral;
    Le reset sera toujours mieux en asynchrone.
    JR
    l'électronique c'est pas du vaudou!

  3. #3
    invite562bcc10

    Re : Delay dans mon implementation de la transmission SPI

    Bonsoir,
    Après la correction de quelque petits erreurs de syntaxe ca marche bien.
    Merci beaucoup !!

  4. #4
    jiherve

    Re : Delay dans mon implementation de la transmission SPI

    re
    si erreur de syntaxe il y a amha elles ne sont pas de mon fait j'ai juste fait ctrlx ctrlv sauf pour la clock!
    ceci dit que cela fonctionne ne m’étonne pas vraiment!
    JR
    Dernière modification par jiherve ; 15/10/2017 à 21h48.
    l'électronique c'est pas du vaudou!

  5. A voir en vidéo sur Futura
  6. #5
    invite562bcc10

    Re : Delay dans mon implementation de la transmission SPI

    C'est possible que c'est quand c'est produit quand j'ai copier coller, l'importance c'est que cela fonctionne
    Je vous remercie !

  7. #6
    jiherve

    Re : Delay dans mon implementation de la transmission SPI

    Re
    je n'ai pas vraiment de mérite car j'ai pissé du VHDL pendant au moins 15 ans, il m'arrive cependant toujours de faire des bêtises.
    JR
    l'électronique c'est pas du vaudou!

  8. #7
    invite562bcc10

    Re : Delay dans mon implementation de la transmission SPI

    Le mérite du fait que vous preniez le temps d'aider les autres !
    Bonne soirée

  9. #8
    albanxiii
    Modérateur

    Re : Delay dans mon implementation de la transmission SPI

    Personnellement je ne suis pas pour donner les solutions toutes cuites. Et j'ai écrit ma première ligne de VHDL en 1999.
    Not only is it not right, it's not even wrong!

  10. #9
    jiherve

    Re : Delay dans mon implementation de la transmission SPI

    Bonjour,
    Il serait trop long et compliqué de faire du pas à pas , je compte sur l'intelligence du demandeur pour comprendre le code fourni.
    Pour le VHDL j'ai basculé complétement le jour ou le compilo (QuartusII Altera ,car Maxplus2 en VHDL était inutilisable ) faisait mieux ou pas plus mal que moi en AHDL surtout coté fréquence de fonctionnement .
    JR
    l'électronique c'est pas du vaudou!

Discussions similaires

  1. [Programmation] delay ne marche pas dans un programme microcontrôleur pic16f1508
    Par invite907fd2ff dans le forum Électronique
    Réponses: 13
    Dernier message: 19/05/2016, 17h40
  2. [Programmation] diminue le delay dans un programme arduino
    Par invite6a1b20ed dans le forum Électronique
    Réponses: 2
    Dernier message: 24/03/2016, 18h06
  3. transmission dans l'air par faisceau laser
    Par invite40166245 dans le forum Électronique
    Réponses: 9
    Dernier message: 05/03/2012, 17h58
  4. Question sur l'implémentation de microblaze dans Spartan3
    Par invite0d5fe536 dans le forum Électronique
    Réponses: 0
    Dernier message: 17/04/2008, 03h08
  5. transmission de données dans l'espace
    Par invitec4eb90fd dans le forum Astronautique
    Réponses: 15
    Dernier message: 08/09/2007, 09h18
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...