TP projet FPGA Moteur pas à pas

37  Download (0)

Full text

(1)

1

Ecole d’ingénieurs Sup Galilée

Spécialité Instrumentation

TP projet FPGA Moteur pas à pas

Travaux pratiques

Fabrice Wiotte Laboratoire LPL

© INSTITUT GALILEE, 99 avenue Jean-Baptiste-Clément 93430 VILLETANEUSE 2020/2021

(2)

2

Sommaire

Sommaire ... 2

Présentation TP ... 3

Objectif ... 3

Introduction ... 3

Schéma de principe ... 3

Les différentes étapes du TP projet……… ……….…..4

Partie 1 CAO ... 4

Carte à developper ... 4

Encodeur ... 5

Driver moteur et affichage fréquence de rotation ... 6

Partie 2 Xilinx ISE ... 7

Logiciel utilisé ... 7

Vue schématique (RTL) du projet ... 8

Les principaux modules à développer ... 8

Le codeur incrémental : principe ………..……11

Annexes... ...9-37 Les tests bench (simulations) des principaux modules……….……9-10 Les codes VHDL à compléter et à éditer sous ISE………12-24 ISE Project : choix pour développement... ... ...12-28 Le schéma principal TOP modul sous ISE du projet………..…25 Le fichier principal VHDL TOP modul sous ISE du projet………..………26-32 Le fichier de contraintes TP.ucf (.ucf user contraints file)...33-35 La carte d’évaluation Digilent Nexys 4 et A7-100T……….……..36-37

(3)

3

Présentation TP

Objectif

Contrôler un moteur numérique du type pas à pas, sens de rotation, vitesse de rotation, contrôle du pas.

Il faudra afficher la fréquence de fonctionnement du moteur, le pas ainsi que la vitesse en tr/min.

Le moteur fonctionne en boucle ouverte non asservi.

Moteur utilisé : 28BYJ-48 5V, driver moteur ULN2003 et encodeur PEC11R 24 pas/tours.

Le moteur à une réduction de 1/64 soit 360 degrés/64 = 5.625 degré/pas.

En mode demi-pas qui correspond à 8 états et 4 phases la réduction finale est de 4096 (64x64).

Le moteur aura un pas unitaire angulaire de 5.625/64 = 0,0879 degrés !.

Vitesse max du moteur = 255Hz

Introduction

Les moteurs pas à pas permettent de réaliser un positionnement précis à partir d’une commande simple et peu coûteuse. Leur champ d’application est très vaste (montre à aiguille à quartz, lecteur de disquette...) et touche beaucoup de domaines pour les entraînements à faible puissance.

Schéma de principe

Contrairement à l’ensemble des autres moteurs, le comportement du moteur pas à pas est de type numérique : c’est à dire qu’il fonctionne par impulsions tout ou rien.

La plupart des actionneurs, qu’ils soient électriques ou hydrauliques fournissent un couple ou une vitesse qui est fonction du niveau d’entrée de leur système de commande.

Avec le moteur pas à pas, il suffit d’envoyer une impulsion pour le faire tourner d’un pas. Si ces impulsions sont envoyées à fréquence fixe le moteur tourne à vitesse constante.

Chaque impulsion envoyée par le système de commande au module de puissance se traduit par la rotation d'un pas du moteur. La résolution angulaire¸ d'un moteur pas à pas va de 4 à 400 pas.

Figure 1 Schéma de principe du moteur pas à pas CW

CCW

Figure 2 ci-dessus chronogramme de fonctionnement en mode demi pas

(4)

4

Les différentes étapes du TP projet

Partie 1. Développement des cartes électroniques associé à la carte FPGA NEXYS 4 ou A7-100T Partie 2. Développement du code VHDL pour programmer la carte FPGA sous ISE web pack 14.7

Partie 1

Il faudra développer deux cartes électroniques avec le logiciel de CAO électronique ALTIUM qui se connecteront à la carte FPGA. Carte encodeur numérique et Carte driver stepper motor.

Les librairies pour les composants seront fournies.

Nous utiliserons une machine à gravure anglaise, la LPKF protoMatE44 pour développer les deux circuits, (démonstration si possible au laboratoire de physique des lasers).

La première carte permet le contrôle de la fréquence du moteur avec un encodeur numérique.

La seconde carte permet le contrôle en puissance des phases d’allumage des bobinages du moteur et l’affichage de la fréquence de rotation.

L’affichage de la vitesse en tr/min et le pas seront à implémenter sur la carte de développement FPGA Nexys 4 ou A7-100T déjà étudié en première année à l’aide des afficheurs disponibles.

Figure 1 Carte FPGA utilisée et carte filles à développer

(5)

5

Carte à développer sous ALTIUM DESIGNER 20

1. Carte fille 1: Encodeur numérique PEC11R

Chronogramme pour CW → or CCW 

Sous Altium designer 20 Vue PCB et 3D

(6)

6

Carte à développer sous ALTIUM DESIGNER 20

2. Carte fille: contrôle moteur & affichage fréquence

Sous Altium designer 20 Vue PCB et 3D

(7)

7

Xilinx ISE 14.7

Le projet pour la partie numérique doit être développé sous ISE 14.7, télécharger la version 14.7 https://www.xilinx.com/downloadNav/vivado-design-tools/archive-ise.html

Attention éviter de prendre la version 14.7 Windows 10 qui est une machine virtuelle.

Prendre la version 14.7 et patcher ISE 14.7 pour Windows 10 avec le lien ci-dessous.

https://github.com/cbureriu/xilinx-14.7-patch-for-Win10-32-64

Vous pouvez également utiliser les outils les plus récent de Xilinx pour la programmation FPGA.

Vivado Suite https://www.xilinx.com/support/download.html

Cependant vous n’aurais pas accès aux outils graphiques tels que la saisi de schéma dans cette version.

Supports des TP : https://moodlelms.univ-paris13.fr/my/ ... FPGA2- INSTR2 mais aussi les supports De TP ELN de première année.

Figure 2 Carte FPGA avec les cartes filles

(8)

8

Les principaux modules en code VHDL à réaliser

Gestion horloge et synchronisation de la carte FPGA et des cartes annexes:

Module Clock_manager.vhd

Gestion de l’encodeur numérique pour le réglage de la fréquence de rotation du moteur:

Module codeur incremental.vhd

Gestion de la machine d’état des phases de contrôle du moteur pas à pas:

State_machine_stepper_motor.vhd

Table de décodage-multiplexage pour l’affichage des pas et de la Vitesse du moteur en tr/mn:

Decode_2_to_8.vhd et MUX.vhd Afficheur 7 segments:

BCD_7segments.vhd

Compteur binary to decimal pour afficher les pas:

Compteur_B_to_D.vhd

Module calcul de la Vitesse du moteur Calcul_vitesse_stepper_motor.vhd

Figure 3 vue RTL sous Xilinx ISE 14.7 du projet

(9)

9

Tests bench

Module CLOCK manager 1

Module CLOCK manager 2

Module encodeur numérique

(10)

10

Tests bench

Module encodeur numérique

Module machine d’état moteur pas à pas

Module machine d’état moteur pas à pas

(11)

11

Basé sur Le code de Gray, également appelé binaire réfléchi, permet de ne faire changer qu'un seul bit à la fois quand un nombre est incrémenté ou décrémenté d'une unité.

Ici codage sur 4 bits

(12)

12

--Code codeur numérique à

completer

- -- Déclaration des bibliothèques utilisées

library IEEE;

use IEEE.STD_LOGIC_1164.all; -- inclus signaux améliorés du type std_ulogic-- use IEEE.STD_LOGIC_ARITH.all; -- fournit le calcul numérique--

use IEEE.STD_LOGIC_UNSIGNED.all; -- calcul numérique non signé sur le type std_logic_vector-- entity codeur_numerique is

Port (

CLK : in STD_LOGIC; --1000Hz-- Reset : in STD_LOGIC;

rotary_A : in STD_LOGIC;

rotary_B : in STD_LOGIC;

compte_out_codeur : out STD_LOGIC_VECTOR(7 downto 0));

end codeur_numerique;

architecture Behavioral of codeur_numerique is

type etat_codeur is(S1,S2,S3,S4,S5,S6,S7); -- declaration de la machine d'état et du nombre d'état--

signal etat : etat_codeur;

signal compteur: INTEGER range 0 to 255; -- déclaration d'un compteur 8 bits qui servira à modifier la fréquence de focntionnement du moteur--

-- process machine d'état encodeur numérique-- begin

process(CLK,reset,rotary_A,rotary_B) -- liste de sensibilité toujours des entrées ou des signaux déclarés--

begin

if reset ='1' then

compte_out_codeur <="00000000"; -- on s'assure que le compteur de sortie soit à zéro à l'initialisation --

compteur <= 0; -- compteur interne à zéro à l'initialisation-- etat <= S1; -- on va à l'état S1 --

elsif CLK'event and CLK ='1' then -- sur front montant d’horloge-- case etat is -- machine d'état on décrit tous les cas possibles-- … --code à compléter

End case;

compte_out_codeur <= CONV_STD_LOGIC_VECTOR(compteur,8); -- on convertit des entiers en std_logic_vectors, bus logic.

end if;

end process;

end Behavioral; --en vert du commentaire—

(13)

13

--Code state machine moteur à

completer

— -- Déclaration des bibliothèques utilisées

library IEEE;

use IEEE.STD_LOGIC_1164.all; -- inclus signaux améliorés du type std_ulogic-- use IEEE.STD_LOGIC_ARITH.all;

use IEEE.STD_LOGIC_UNSIGNED.all;

use ieee.numeric_std.all; -- fournit le calcul numérique tableaux signés non signés de type std_logic pour les signaux--

entity state_machine_stepper_motor is Port (

clk : in STD_LOGIC; --1000Hz-- bouton_UP : in STD_LOGIC;

bouton_DOWN : in STD_LOGIC;

change_frequency_motor : in STD_LOGIC_VECTOR (7 downto 0);

Commandes_demi_pas : out STD_LOGIC_VECTOR (3 downto 0);

vers_change_frequency_motor : out STD_LOGIC_VECTOR (7 downto 0);

reset : in STD_LOGIC;

visu_UP : out STD_LOGIC;

visu_DOWN : out STD_LOGIC);

end state_machine_stepper_motor;

architecture Behavioral of state_machine_stepper_motor is

TYPE etat IS (attente, position1, position2, position3, position4, position5, position6, position7, position8);

SIGNAL state_machine: etat;

SIGNAL count4 : INTEGER range 0 to 1000 := 0; --16 bits compteur-- SIGNAL clock_int4: STD_LOGIC :='0';

signal M : INTEGER range 0 to 1000;

begin

--Divise par M en fonction de change_frequency_motor-- PROCESS(clk,M,reset,change_frequency_motor)

BEGIN

if reset='1' then

clock_int4 <='0';

count4 <=0;

elsif rising_edge(clk) then

M <= 1000/conv_integer(change_frequency_motor);

IF count4 <= M-1 THEN count4 <= count4 + 1;

ELSE

count4 <=0;

END IF;

--à la moitié du comptage on change la valeur de clock_1Hz_int (rapport cyclique = 1/2)-- IF count4 <= M/2 THEN

clock_int4 <= '0';

ELSE

clock_int4 <= '1';

END IF;

end if;

end process;

(14)

14

--Code state machine moteur à

completer suite

--state machine moteur pas a pas--

process(clock_int4,Reset,bouton_UP,bouton_DOWN) begin

if reset='1' then

state_machine <= attente;

Commandes_demi_pas <="0000";

elsif rising_edge(clock_int4) then -- sur front montant de clock_int4-- case state_machine is

… --code à compléter End case;

end if;

end process;

vers_change_frequency_motor <= std_logic_vector(change_frequency_motor);

visu_UP <= bouton_UP;

visu_DOWN <= bouton_DOWN;

end Behavioral;

(15)

15

--Code clock manager à

completer—

-- Déclaration des bibliothèques utilisées library IEEE;

use IEEE.STD_LOGIC_1164.ALL; -- inclus signaux améliorés du type std_ulogic--

use IEEE.STD_LOGIC_UNSIGNED.all; -- calcul numérique non signé sur le type std_logic_vector-- entity clock_manager_project is

Port ( clk : in STD_LOGIC; --100MHz clk_div1 : out STD_LOGIC; --1000Hz

clk_div2 : out STD_LOGIC; --1000Hz ce : in STD_LOGIC;

reset : in STD_LOGIC);

end clock_manager_project;

architecture Behavioral of clock_manager_project is

--pour compter jusqu'a (100000 -1) il faut 17 bits (2^17= 131072 ) signal count1: INTEGER range 0 to 100000 := 0;

SIGNAL clock_int1: STD_LOGIC :='0';

signal count2: INTEGER range 0 to 100000 := 0;

SIGNAL clock_int2: STD_LOGIC :='0';

CONSTANT M1: INTEGER := 100000; -- resultat de la division pour 1000Hz CONSTANT M2: INTEGER := 100000; -- resultat de la division pour 1000Hz Begin

--Divise par 10000 FOUT = 1000Hz synchro affichage et synchro state machine—

PROCESS(clk,ce,reset) BEGIN

… --code à completer—

END PROCESS;

--à la moitié du comptage on change la valeur de clock_1Hz_int (rapport cyclique = 1/2) clock_int1 <= '1' WHEN count1 <= M1/2 ELSE '0';

clk_div1 <= clock_int1;

clock_int2 <= '1' WHEN count1 <= M2/2 ELSE '0';

clk_div2<= clock_int2;

end Behavioral;

(16)

16

--Code Mux à

completer—

-- Déclaration des bibliothèques utilisées library IEEE;

use IEEE.STD_LOGIC_1164.ALL; -- inclus signaux améliorés du type std_ulogic-- entity MUX is

Port (

A : in STD_LOGIC_VECTOR (3 downto 0);

B : in STD_LOGIC_VECTOR (3 downto 0);

C : in STD_LOGIC_VECTOR (3 downto 0);

D : in STD_LOGIC_VECTOR (3 downto 0);

E : in STD_LOGIC_VECTOR (3 downto 0);

F : in STD_LOGIC_VECTOR (3 downto 0);

G : in STD_LOGIC_VECTOR (3 downto 0);

H : in STD_LOGIC_VECTOR (3 downto 0);

SEL : in STD_LOGIC_VECTOR (2 downto 0);

sortie_mux : out STD_LOGIC_VECTOR (3 downto 0));

end MUX;

architecture Behavioral of MUX is begin

process(sel,A,B,C,D,E,F,G,H) begin

case sel is

--when "000" => Sortie_Mux <= A;

when "001" => Sortie_Mux <= B;

---- code à compléter

when others => Sortie_Mux <= A;

end case;

end process;

end Behavioral;

(17)

17

--Code decode 2 to 8 à

completer—

-- Déclaration des bibliothèques utilisées library IEEE;

use IEEE.STD_LOGIC_1164.ALL; -- inclus signaux améliorés du type std_ulogic-- entity DECODE_2_to_8 is

Port (

SEL : in STD_LOGIC_VECTOR (2 downto 0);

select_freq_or_vitesse : in STD_LOGIC;

DP1 : out STD_LOGIC;

afficheur_0 : out STD_LOGIC;

afficheur_1 : out STD_LOGIC;

afficheur_2 : out STD_LOGIC;

afficheur_3 : out STD_LOGIC;

afficheur_4 : out STD_LOGIC;

afficheur_5 : out STD_LOGIC;

afficheur_6 : out STD_LOGIC;

afficheur_7 : out STD_LOGIC);

end DECODE_2_to_8;

architecture Behavioral of DECODE_2_to_8 is begin

process(Sel,select_freq_or_vitesse) begin

afficheur_0 <='1';afficheur_1 <='1';afficheur_2 <='1';afficheur_3 <='1';afficheur_4 <='1';

afficheur_5 <='1'; afficheur_6 <='1'; afficheur_7 <='1'; DP1 <='1';

if select_freq_or_vitesse = '1' then case sel is

--when "000" =>afficheur_0 <='0'; DP1 <='1';

----code à completer

when others => afficheur_0 <='0'; DP1 <='1';

end case;

else

case sel is

--when "000" =>afficheur_0 <='0'; DP1 <='1';

----code à completer

when others => afficheur_0 <='0'; DP1 <='1';

end case;

end if;

end process;

end Behavioral;

(18)

18

--Code BCD 7 segements complet

-- Déclaration des bibliothèques utilisées library IEEE;

use IEEE.STD_LOGIC_1164.ALL; -- inclus signaux améliorés du type std_ulogic-- entity BCD_7Segments is

Port (

d : in STD_LOGIC_VECTOR (3 downto 0);

s : out STD_LOGIC_VECTOR (6 downto 0));

end BCD_7Segments;

architecture Behavioral of BCD_7Segments is -- segment encoding

-- 0 -- --- -- 5 | | 1 -- --- <- 6 -- 4 | | 2 -- --- -- 3 begin

with d select

s<= "1111001" when "0001", --1

"0100100" when "0010", --2 "0110000" when "0011", --3 "0011001" when "0100", --4 "0010010" when "0101", --5 "0000010" when "0110", --6 "1111000" when "0111", --7 "0000000" when "1000", --8

"0010000" when "1001", --9 "0001000" when "1010", --A

"0000011" when "1011", --b

"1000110" when "1100", --C "0100001" when "1101", --d

"0000110" when "1110", --E

"0001110" when "1111", --F

"1000000" when others; --0 end Behavioral;

(19)

19

--Code compteur 3 bits à complet

-- Déclaration des bibliothèques utilisées library IEEE;

use ieee.std_logic_1164.all; -- inclus signaux améliorés du type std_ulogic-- use ieee.std_logic_arith.all; -- fournit le calcul numérique--

use ieee.std_logic_unsigned.all; -- calcul numérique non signé sur le type std_logic_vector-- entity compteur_3bits is

Port ( clk : in STD_LOGIC;

reset : in STD_LOGIC;

enable : in STD_LOGIC;

sortie_compteur : out STD_LOGIC_VECTOR (2 downto 0)); -3 bits on affiche sur 8 digits-- end compteur_3bits;

architecture Behavioral of compteur_3bits is

signal compte : std_logic_vector(2 downto 0); -- on declare un signal de comptage-- begin

--compteur 3 bits on compte au max jusqu’à 2^3 max-- process(CLK,reset)

BEGIN

…--code à completer END PROCESS;

Sortie_compteur <= compte;

end Behavioral;

(20)

20

--Code compteur BCD à compléter

-- Déclaration des bibliothèques utilisées library IEEE;

use ieee.std_logic_1164.all; -- inclus signaux améliorés du type std_ulogic-- use ieee.std_logic_arith.all; -- fournit le calcul numérique--

use ieee.std_logic_unsigned.all; -- calcul numérique non signé sur le type std_logic_vector--

--le compteur BCD permet d’afficher la valeur du pas sur 4 digits-- entity CompteurBCD is

Port (

CLK : in STD_LOGIC; --1000Hz

change_frequency_motor : in STD_LOGIC_VECTOR (7 downto 0);

bouton_UP : in STD_LOGIC;

bouton_DOWN : in STD_LOGIC;

Enable : in STD_LOGIC;

Reset : in STD_LOGIC;

Full : out STD_LOGIC;

Empty : out STD_LOGIC;

BCD_U : out STD_LOGIC_VECTOR (3 downto 0);

BCD_D : out STD_LOGIC_VECTOR (3 downto 0);

BCD_H : out STD_LOGIC_VECTOR (3 downto 0);

BCD_T: out STD_LOGIC_VECTOR (3 downto 0) );

end CompteurBCD;

SIGNAL count3 : INTEGER range 0 to 1000 := 0; --16 bits compteur SIGNAL clock_int3: STD_LOGIC;

signal M : INTEGER range 0 to 1000;

signal COUNTER_U: INTEGER range 0 to 9;

signal COUNTER_D: INTEGER range 0 to 9;

signal COUNTER_H: INTEGER range 0 to 9;

signal COUNTER_T: INTEGER range 0 to 9;

signal IS_4096: STD_LOGIC;

signal IS_0000: STD_LOGIC;

begin

--Divise par M en fonction de change_frequency_motor on modifie la Vitesse du compteur-- PROCESS(clk,reset,Enable,M,change_frequency_motor)

BEGIN

if reset ='1' then count3 <= 0;

elsif rising_edge(clk) then if enable ='1' then

M <= 1000/conv_integer(change_frequency_motor);

IF count3 <= M-1 THEN

(21)

21

--Code compteur BCD à completer

count3 <= count3 + 1;

ELSE

count3 <= 0;

END IF;

--à la moitié du comptage on change la valeur de clock_1Hz_int (rapport cyclique = 1/2)-- IF count3 <= M/2 THEN

clock_int3 <= '0';

ELSE

clock_int3 <= '1';

END IF;

end if;

end if;

END PROCESS;

--le compteur BCD permet d’afficher la valeur du pas 0 to 4096 sur 4 digits-- process(clock_int3,Enable,reset,bouton_UP,bouton_DOWN)

begin

if Reset='1' then --on initialize le compteur au démarrage-- COUNTER_U <= 0;

COUNTER_D <= 0;

COUNTER_H <= 0;

COUNTER_T <= 0;

elsif rising_edge(clock_int3) then if Enable = '1' then

if bouton_UP ='1' then

…--code à completer end if;

if bouton_DOWN ='1' then …--code à completer

end if;

end if;

end process;

BCD_U <= CONV_STD_LOGIC_VECTOR(COUNTER_U,4);

BCD_D <= CONV_STD_LOGIC_VECTOR(COUNTER_D,4);

BCD_H <= CONV_STD_LOGIC_VECTOR(COUNTER_H,4);

BCD_T <= CONV_STD_LOGIC_VECTOR(COUNTER_T,4);

-- on defini les limites du compteur ici 4096 pas--

IS_4096 <= '1' when (COUNTER_U = 6 and COUNTER_D = 9 and COUNTER_H = 0 and COUNTER_T = 4) else '0';

IS_0000 <= '1' when (COUNTER_U = 0 and COUNTER_D = 0 and COUNTER_H = 0 and COUNTER_T = 0) else '0';

Full <= IS_4096;

Empty <= IS_0000;

end Behavioral;

(22)

22

--Exemple de Code pour le calcul de la Vitesse du moteur en tr/min

--Ce code est une possibilitée de calcul de la Vitesse du moteur mais il y en a sans doute d’autres—

library IEEE;

use IEEE.STD_LOGIC_1164.all;

use IEEE.STD_LOGIC_ARITH.all;

use IEEE.STD_LOGIC_UNSIGNED.all;

use ieee.numeric_std.all;

--en fonction de la fréquence d’entrée du moteur entre 0-255Hz on calcul la Vitesse en tr/mn-- entity calcul_vitesse_stepper_motor is

Port ( frequency_in_motor : in STD_LOGIC_VECTOR (7 downto 0); --entre 0 et 255Hz-- select_freq_or_vitesse : in STD_LOGIC;

affichage_vitesse_digit0 : out STD_LOGIC_VECTOR (3 downto 0);

affichage_vitesse_digit1 : out STD_LOGIC_VECTOR (3 downto 0);

affichage_vitesse_digit2 : out STD_LOGIC_VECTOR (3 downto 0);

affichage_vitesse_digit3 : out STD_LOGIC_VECTOR (3 downto 0));

end calcul_vitesse_stepper_motor;

architecture Behavioral of calcul_vitesse_stepper_motor is signal Frequence: INTEGER range 0 to 255;

signal N: INTEGER; -- Tours/minutes ou *60 tr/heures signal Q : STD_LOGIC_VECTOR (11 downto 0);

signal Q2 : STD_LOGIC_VECTOR (7 downto 0);

signal decalage_a_gauche: INTEGER;

signal view_signal_decalage_a_gauche : STD_LOGIC_VECTOR (26 downto 0);

signal view_signal_N : STD_LOGIC_VECTOR (26 downto 0);

begin

Frequence <= conv_integer(frequency_in_motor);

decalage_a_gauche <= (Frequence * 100000); -- car on ne peut que declarer des entiers pas des nombres flottants, on décale à gauche le resultat pour conserver la valeur entière--

N <= (decalage_a_gauche / 4096) * 60; --tours/s -->tours/minutes @100Hz 1.464 tr/min Q <= std_logic_vector(to_unsigned(N/100, 12)); -- on converti en std_logic_vector le nombre-- Q2 <= frequency_in_motor;

process(Q,Q2,select_freq_or_vitesse) --liste de sensibilité, signaux d’entrées ou internes--- -- variable temporaire

variable temp : STD_LOGIC_VECTOR ( 11 downto 0 ); --utilisé pour la valeur da la vitesse-- variable temp2 : STD_LOGIC_VECTOR ( 7 downto 0 ); --utilisé pour la valeur de fréquence-- variable bcd : STD_LOGIC_VECTOR ( 15 downto 0 ); -- variable de sortie BCD vers l’affichage--

begin

(23)

23

--Code calcul de la Vitesse du moteur en tr/min suite

Le double dabble

-- 2 4 3 --- valeur à afficher -- 0010 0100 0011 -- valeur binaire

-- <---ORIGINAL

--000 0000 0000 11110011 b243 en base binaire

--Le double dabble est un algorithme utilisé pour convertir des nombres d'un système-- --binaire vers un système décimal. Pour des raisons pratiques, le résultat est--

--généralement stocké sous la forme de décimal codé en binaire (BCD)--

--En partant du registre initial, l'algorithme effectue n itérations (soit 8 dans l'exemple ci-dessous) --a chaque itération, le registre est décalé d'un bit vers la gauche. Avant d'effectuer cette

opération,

--la partie au format BCD est analysée, décimale par décimale. Si une décimale en BCD (4 bits) --est plus grande que 4 alors on lui ajoute 3. Cette incrément permet de s'assurer qu'une valeur de 5 après incrémentation et décalage, devient 16 et se propage correctement à la décimale suivante.

--- 0000 0000 0000 11110011 Initialisation --- 0000 0000 0001 11100110 Décalage --- 0000 0000 0011 11001100 Décalage --- 0000 0000 0111 10011000 Décalage

--- 0000 0000 1010 10011000 Ajouter 3 à la première décimale BCD, puisque sa valeur était 7

--- 0000 0001 0101 00110000 Décalage

--- 0000 0001 1000 00110000 Ajouter 3 à la première décimale BCD, puisque sa valeur était 5

--- 0000 0011 0000 01100000 Décalage --- 0000 0110 0000 11000000 Décalage

--- 0000 1001 0000 11000000 Ajouter 3 à la seconde décimale BCD, puisque sa valeur était 6

--- 0001 0010 0001 10000000 Décalage -- 0010 0100 0011 00000000 Décalage

--2----4---3-- résultat obtenu à afficher --mettre à zéro la variable bcd

bcd := (others => '0');

if select_freq_or_vitesse ='1' then -- select bit pour afficher soit la fréquence sur les afficheurs 4 digits annexes ou la Vitesse en tr/mn--

temp (11 downto 0) := Q ;-- lire le signal Q dans la variable

for i in 0 to 11 loop --- boucle d’itération—affichage sur 12 bits

if bcd(3 downto 0) > 4 then

bcd(3 downto 0) := bcd(3 downto 0) + 3;

end if;

(24)

24

--Code pour le calcul de la Vitesse du moteur en tr/min suite

Le double dabble if bcd(7 downto 4) > 4 then

bcd(7 downto 4) := bcd(7 downto 4) + 3;

end if;

if bcd(11 downto 8) > 4 then

bcd(11 downto 8) := bcd(11 downto 8) + 3;

end if;

bcd := bcd(14 downto 0) & temp(11);

temp := temp(10 downto 0) & '0'; -- decalage d’un bit à gauche-- end loop;

elsif select_freq_or_vitesse ='0' then -- si bit de selection passe à 0--

temp2(7 downto 0) := Q2 ;

--- boucle d’itération—affichage sur 8 bits

for i in 0 to 7 loop -- car on souhaite afficher sur 8 bits la fréquence-- if bcd(3 downto 0) > 4 then

bcd(3 downto 0) := bcd(3 downto 0) + 3;

end if;

if bcd(7 downto 4) > 4 then

bcd(7 downto 4) := bcd(7 downto 4) + 3;

end if;

if bcd(11 downto 8) > 4 then

bcd(11 downto 8) := bcd(11 downto 8) + 3;

end if;

bcd := bcd(14 downto 0) & temp2(7);

temp2 := temp2(6 downto 0) & '0'; -- decalage d’un bit à gauche-- end loop;

end if;

-- set outputs→ vers le multiplexeur et 7 segments--- affichage_vitesse_digit0 <= STD_LOGIC_VECTOR (bcd(3 downto 0));

affichage_vitesse_digit1 <= STD_LOGIC_VECTOR (bcd(7 downto 4));

affichage_vitesse_digit2 <= STD_LOGIC_VECTOR (bcd(11 downto 8));

affichage_vitesse_digit3 <= STD_LOGIC_VECTOR (bcd(15 downto 12));

end process;

end Behavioral;

(25)

25

Schéma principal TOP modul sous ISE

Deux types de développement pour le projet ISE et la forme du fichier principal : Sous forme de schéma ci-dessous

Figure 4 schéma principal pour le projet

(26)

26

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity Top_level_module_moteur_pas_a_pas is Port (

bouton_DOWN : in STD_LOGIC;

bouton_UP : in STD_LOGIC;

CLK : in STD_LOGIC;

reset : in STD_LOGIC;

enable : in STD_LOGIC;

rotary_A : in STD_LOGIC;

rotary_B : in STD_LOGIC;

select_freq_or_vitesse : in STD_LOGIC;

afficheur_0 : out STD_LOGIC;

afficheur_1 : out STD_LOGIC;

afficheur_2 : out STD_LOGIC;

afficheur_3 : out STD_LOGIC;

afficheur_4 : out STD_LOGIC;

afficheur_5 : out STD_LOGIC;

afficheur_6 : out STD_LOGIC;

afficheur_7 : out STD_LOGIC;

Commande_4_Phase : out STD_LOGIC_VECTOR (3 downto 0);

DP : out STD_LOGIC;

EMPTY : out STD_LOGIC;

FULL : out STD_LOGIC;

SEG : out STD_LOGIC_VECTOR (6 downto 0);

Visu_DOWN_freq : out STD_LOGIC;

Visu_UP_freq : out STD_LOGIC);

end Top_level_module_moteur_pas_a_pas;

architecture Behavioral of Top_level_module_moteur_pas_a_pas is -- signaux à declarer--

signal sortie_mux : std_logic_vector (3 downto 0);

signal A : std_logic_vector (3 downto 0);

signal B : std_logic_vector (3 downto 0);

signal C : std_logic_vector (3 downto 0);

signal D : std_logic_vector (3 downto 0);

signal E : std_logic_vector (3 downto 0);

signal F : std_logic_vector (3 downto 0);

signal G : std_logic_vector (3 downto 0);

signal H : std_logic_vector (3 downto 0);

signal SEL : std_logic_vector (2 downto 0);

signal change_frequency_motor : std_logic_vector (7 downto 0);

signal clk_synchro_affichage : std_logic := '0';

signal clk_synchro_state_machine : std_logic := '0';

(27)

27

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous suite

signal clk_div1 : std_logic := '0';

signal clk_div2 : std_logic := '0';

signal frequency_in_motor : std_logic_vector (7 downto 0);

-- on declare les composants ou les modules-- component BUFG

port (

I : in std_logic;

O : out std_logic);

end component;

component BCD_7Segments

port ( d : in std_logic_vector (3 downto 0);

s : out std_logic_vector (6 downto 0));

end component;

component MUX

port (

A : in std_logic_vector (3 downto 0);

B : in std_logic_vector (3 downto 0);

C : in std_logic_vector (3 downto 0);

D : in std_logic_vector (3 downto 0);

E : in std_logic_vector (3 downto 0);

F : in std_logic_vector (3 downto 0);

G : in td_logic_vector (3 downto 0);

H : in std_logic_vector (3 downto 0);

SEL : in std_logic_vector (2 downto 0);

sortie_mux : out std_logic_vector (3 downto 0));

end component;

component compteur_3bits

port ( clk : in std_logic;

reset : in std_logic;

enable : in std_logic;

sortie_compteur : out std_logic_vector (2 downto 0));

end component;

(28)

28

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous suite

component calcul_vitesse_stepper_motor port (

select_freq_or_vitesse : in std_logic;

frequency_in_motor : in std_logic_vector (7 downto 0);

affichage_vitesse_digit0 : out std_logic_vector (3 downto 0);

affichage_vitesse_digit1 : out std_logic_vector (3 downto 0);

affichage_vitesse_digit2 : out std_logic_vector (3 downto 0);

affichage_vitesse_digit3 : out std_logic_vector (3 downto 0));

end component;

component state_machine_stepper_motor port ( clk : in std_logic;

bouton_UP : in std_logic;

bouton_DOWN : in std_logic;

reset : in std_logic;

change_frequency_motor : in std_logic_vector (7 downto 0);

visu_UP : out std_logic;

visu_DOWN : out std_logic;

Commandes_demi_pas : out std_logic_vector (3 downto 0);

vers_change_frequency_motor : out std_logic_vector (7 downto 0));

end component;

component DECODE_2_to_8

port ( select_freq_or_vitesse : in std_logic;

SEL : in std_logic_vector (2 downto 0);

DP1 : out std_logic;

afficheur_0 : out std_logic;

afficheur_1 : out std_logic;

afficheur_2 : out std_logic;

afficheur_3 : out std_logic;

afficheur_4 : out std_logic;

afficheur_5 : out std_logic;

afficheur_6 : out std_logic;

afficheur_7 : out std_logic);

end component;

(29)

29

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous suite

component CompteurBCD

port ( CLK : in std_logic;

bouton_UP : in std_logic;

bouton_DOWN : in std_logic;

Enable : in std_logic;

Reset : in std_logic;

change_frequency_motor : in std_logic_vector (7 downto 0);

Full : out std_logic;

Empty : out std_logic;

BCD_U : out std_logic_vector (3 downto 0);

BCD_D : out std_logic_vector (3 downto 0);

BCD_H : out std_logic_vector (3 downto 0);

BCD_T : out std_logic_vector (3 downto 0));

end component;

component clock_manager_project port ( clk : in std_logic;

ce : in std_logic;

reset : in std_logic;

clk_div1 : out std_logic;

clk_div2 : out std_logic);

end component;

component codeur_numerique

port ( CLK : in std_logic;

reset : in std_logic;

rotary_A : in std_logic;

rotary_B : in std_logic;

compte_out_codeur : out std_logic_vector (7 downto 0));

end component;

--instanciation : on associe les modules ou composants entre eux—

begin

-- BUFG: Global Clock Simple Buffer -- 7 Series

-- Xilinx HDL Libraries Guide, version 14.1 BUFG_inst1 : BUFG

port map (

O => clk_synchro_affichage, -- 1-bit output: Clock output I => clk_div1 -- 1-bit input: Clock input

);

-- End of BUFG_inst instantiation

(30)

30

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous suite

-- BUFG: Global Clock Simple Buffer -- 7 Series

-- Xilinx HDL Libraries Guide, version 14.1 BUFG_inst2 : BUFG

port map (

O=>clk_synchro_state_machine, -- 1-bit output: Clock output I=>clk_div2 -- 1-bit input: Clock inp

);

-- End of BUFG_inst instantiation

module_3 : BCD_7Segments port map (

d(3 downto 0)=>sortie_mux(3 downto 0), s(6 downto 0)=>SEG(6 downto 0)

);

module_4 : MUX port map (

A(3 downto 0)=>A(3 downto 0), B(3 downto 0)=>B(3 downto 0), C(3 downto 0)=>C(3 downto 0), D(3 downto 0)=>D(3 downto 0), E(3 downto 0)=>E(3 downto 0), F(3 downto 0)=>F(3 downto 0), G(3 downto 0)=>G(3 downto 0), H(3 downto 0)=>H(3 downto 0), SEL(2 downto 0)=>SEL(2 downto 0),

sortie_mux(3 downto 0)=>sortie_mux(3 downto 0) );

module_5 : compteur_3bits

port map (

clk=>clk_synchro_affichage, enable=>enable,

reset=>reset,

sortie_compteur(2 downto 0)=>SEL(2 downto 0) );

(31)

31

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous suite

module_6 : calcul_vitesse_stepper_motor port map (

frequency_in_motor(7 downto 0)=>frequency_in_motor(7 downto 0), select_freq_or_vitesse=>select_freq_or_vitesse,

affichage_vitesse_digit0(3 downto 0)=>E(3 downto 0), affichage_vitesse_digit1(3 downto 0)=>F(3 downto 0), affichage_vitesse_digit2(3 downto 0)=>G(3 downto 0), affichage_vitesse_digit3(3 downto 0)=>H(3 downto 0) );

module_7 : state_machine_stepper_motor port map (

bouton_DOWN=>bouton_DOWN, bouton_UP=>bouton_UP,

change_frequency_motor(7 downto 0)=>change_frequency_motor(7 downto 0), clk=>clk_synchro_state_machine,

reset=>reset,

Commandes_demi_pas(3 downto 0)=>Commande_4_Phase(3 downto 0),

vers_change_frequency_motor(7 downto 0)=>frequency_in_motor(7 downto 0), visu_DOWN=>Visu_DOWN_freq,

visu_UP=>Visu_UP_freq

);

module_8 : DECODE_2_to_8 port map (

SEL(2 downto 0)=>SEL(2 downto 0),

select_freq_or_vitesse=>select_freq_or_vitesse, afficheur_0=>afficheur_0,

afficheur_1=>afficheur_1, afficheur_2=>afficheur_2, afficheur_3=>afficheur_3, afficheur_4=>afficheur_4, afficheur_5=>afficheur_5, afficheur_6=>afficheur_6, afficheur_7=>afficheur_7, DP1=>DP

);

(32)

32

Fichier principal VHDL TOP modul sous ISE

Sous forme d’instanciation VHDL ci-dessous suite

module_9 : CompteurBCD port map (

bouton_DOWN=>bouton_DOWN, bouton_UP=>bouton_UP,

change_frequency_motor(7 downto 0)=>change_frequency_motor(7 downto 0), CLK=>clk_synchro_state_machine,

Enable=>enable, Reset=>reset,

BCD_D(3 downto 0)=>B(3 downto 0), BCD_H(3 downto 0)=>C(3 downto 0), BCD_T(3 downto 0)=>D(3 downto 0), BCD_U(3 downto 0)=>A(3 downto 0), Empty=>EMPTY,

Full=>FULL );

module_10 : clock_manager_project port map (

ce=>enable, clk=>clk, reset=>reset, clk_div1=>clk_div1, clk_div2=>clk_div2 );

module_11 : codeur_numerique port map (

CLK=>clk_synchro_state_machine, reset=>reset,

rotary_A=>rotary_A, rotary_B=>rotary_B,

compte_out_codeur(7 downto 0)=>change_frequency_motor(7 downto 0) );

end Behavioral;

(33)

33

Le fichier de contrainte (entrées-sorties à “cabler”) À completer et à verifier suivant la carte FPGA utilisée

## This file is a general .ucf for the Nexys4 rev B board

## To use it in a project:

## - uncomment the lines corresponding to used pins

## - rename the used signals according to the project

## Clock signal

#Bank = 35, Pin name = IO_L12P_T1_MRCC_35, Sch name = CLK100MHZ NET "clk" LOC = E3;

NET "clk" IOSTANDARD = LVCMOS33;

## Switches Sch name = SW0 NET "enable" LOC = U9;

NET "enable" IOSTANDARD = LVCMOS33;

NET "select_freq_or_vitesse" LOC = P4;

NET "select_freq_or_vitesse" IOSTANDARD = LVCMOS33;

## 7 segment display

#Bank = 34, Pin name = IO_L2N_T0_34, Sch name = CA

NET "SEG[0]" LOC = L3;

NET "SEG[0]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L3N_T0_DQS_34, Sch name = CB

NET "SEG[1]" LOC = N1;

NET "SEG[1]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L6N_T0_VREF_34, Sch name = CC

NET "SEG[2]" LOC = L5;

NET "SEG[2]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L5N_T0_34, Sch name = CD

NET "SEG[3]" LOC = L4;

NET "SEG[3]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L2P_T0_34, Sch name = CE

NET "SEG[4]" LOC = K3;

NET "SEG[4]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L4N_T0_34, Sch name = CF

NET "SEG[5]" LOC = M2;

NET "SEG[5]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L6P_T0_34, Sch name = CG

NET "SEG[6]" LOC = L6;

NET "SEG[6]" IOSTANDARD = LVCMOS33;

(34)

34

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”) À completer et à verifier suivant la carte FPGA utilisée

#Bank = 34, Pin name = IO_L16P_T2_34, Sch name = DP

NET "DP" LOC = M4;

NET "DP" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L18N_T2_34, Sch name = AN0

NET "afficheur_0" LOC = N6;

NET "afficheur_0" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L18P_T2_34, Sch name = AN1

NET "afficheur_1" LOC = M6;

NET "afficheur_1" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L4P_T0_34, Sch name = AN2

NET "afficheur_2" LOC = M3;

NET "afficheur_2" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L13_T2_MRCC_34, Sch name = AN3

NET "afficheur_3" LOC = N5;

NET "afficheur_3" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L3P_T0_DQS_34, Sch name = AN4

NET "afficheur_4" LOC = N2;

NET "afficheur_4" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L16N_T2_34, Sch name = AN5

NET "afficheur_5" LOC = N4;

NET "afficheur_5" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L1P_T0_34, Sch name = AN6

NET "afficheur_6" LOC = L1;

NET "afficheur_6" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L1N_T034, Sch name = AN7

NET "afficheur_7" LOC = M1;

NET "afficheur_7" IOSTANDARD = LVCMOS33;

NET "bouton_UP" LOC = F15;

NET "bouton_UP" IOSTANDARD = LVCMOS33;

NET "bouton_DOWN" LOC = V10;

NET "bouton_DOWN" IOSTANDARD = LVCMOS33;

## Pmod Header JD NET "rotary_A" LOC = G3;

NET "rotary_A" IOSTANDARD = LVCMOS33;

NET "rotary_B" LOC = G1;

NET "rotary_B" IOSTANDARD = LVCMOS33;

NET "Visu_UP_freq" LOC = H6;

NET "Visu_UP_freq" IOSTANDARD = LVCMOS33;

NET "Visu_DOWN_freq" LOC = F13;

NET "Visu_DOWN_freq" IOSTANDARD = LVCMOS33;

(35)

35

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”) À completer et à verifier suivant la carte FPGA utilisée

NET "reset" LOC = R10;

NET "reset" IOSTANDARD = LVCMOS33;

NET "FULL" LOC = R8;

NET "FULL" IOSTANDARD = LVCMOS33;

NET "EMPTY" LOC = V9;

NET "EMPTY" IOSTANDARD = LVCMOS33;

## Pmod Header JA

#Bank = 15, Pin name = IO_L1N_T0_AD0N_15, Sch name = JA1 NET "Commande_4_Phase[0]" LOC = B13;

NET "Commande_4_Phase[0]" IOSTANDARD = LVCMOS33;

#Bank = 15, Pin name = IO_L5N_T0_AD9N_15, Sch name = JA2 NET "Commande_4_Phase[1]" LOC = F14;

NET "Commande_4_Phase[1]" IOSTANDARD = LVCMOS33;

#Bank = 15, Pin name = IO_L16N_T2_A27_15, Sch name = JA3 NET "Commande_4_Phase[2]" LOC = D17;

NET "Commande_4_Phase[2]" IOSTANDARD = LVCMOS33;

#Bank = 15, Pin name = IO_L16P_T2_A28_15, Sch name = JA4 NET "Commande_4_Phase[3]" LOC = E17;

NET "Commande_4_Phase[3]" IOSTANDARD = LVCMOS33;

NET "Commande_4_Phase[3]" DRIVE = 16;

NET "Commande_4_Phase[2]" DRIVE = 16;

NET "Commande_4_Phase[1]" DRIVE = 16;

NET "Commande_4_Phase[0]" DRIVE = 16;

NET "Commande_4_Phase[3]" SLEW = FAST;

NET "Commande_4_Phase[2]" SLEW = FAST;

NET "Commande_4_Phase[1]" SLEW = FAST;

NET "Commande_4_Phase[0]" SLEW = FAST;

(36)

36

ANNEXES

Carte de développement Digilent Nexys 4

ci-dessous contenu de la boîte A. Nexys 4 board

B. Custom Digilent cardboard box with protective foam C. One USB A to micro-B cable

Branchement de la carte

Pour démarrer la Carte d'Evaluation Nexys 4 ou A7-100T, suivez la procédure décrite ci-dessous : 1. Branchez la Carte sur votre PC à l'aide du câble USB prévu à cet effet

2. Le driver s’installe automatiquement

3. Charger le programme *.*.bit dans la cible à l’aide de l’utilitaire IMPACT sous ISE.

(37)

37

ANNEXES

Carte de développement Digilent Nexys A7

ci-dessous contenu de la boîte D. Nexys a7-100t board

E. Custom Digilent cardboard box with protective foam F. One USB A to micro-B cable

Branchement de la carte

Pour démarrer la Carte d'Evaluation Nexys 4 ou A7-100T, suivez la procédure décrite ci-dessous : 4. Branchez la Carte sur votre PC à l'aide du câble USB prévu à cet effet

5. Le driver s’installe automatiquement

6. Charger le programme *.*.bit dans la cible à l’aide de l’utilitaire IMPACT sous ISE.

Figure

Updating...

References

Related subjects :