64
1 Ecole d’ingénieurs Sup Galilée Spécialité Instrumentation TP projet FPGA Introduction au Moteur pas à pas Programmation sous Python Travaux pratiques Fabrice Wiotte Laboratoire LPL © INSTITUT GALILEE, 99 avenue Jean-Baptiste-Clément 93430 VILLETANEUSE 2020/2021

TP projet FPGA Introduction au Moteur pas à pas

  • Upload
    others

  • View
    8

  • Download
    1

Embed Size (px)

Citation preview

Page 1: TP projet FPGA Introduction au Moteur pas à pas

1

Ecole d’ingénieurs Sup Galilée

Spécialité Instrumentation

TP projet FPGA

Introduction au Moteur pas à pas

Programmation sous Python

Travaux pratiques

Fabrice Wiotte Laboratoire LPL

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

2020/2021

Page 2: TP projet FPGA Introduction au Moteur pas à pas

2

Sommaire

Sommaire .............................................................................................. 2 Présentation TP…………………………………………………………………………………………………………………………………………..….3-5

Objectif ............................................................................................. 3

Introduction ......................................................................................... 4

Schéma de principe…………………………………………………………………………………………………………………………………….4-5

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

****Partie 1 CAO**** 6-8

Carte à developer 7-8 Encodeur 7

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

****Partie 2 Xilinx ISE****…………………………………………………………………………………………………………………….9-10

Logiciel utilisé .................................................................................... 9

Vue schématique (RTL) du projet 10

Les principaux modules à développer………………………………………………………………………………………………..…11

Le codeur incrémental : principe ………………………………………………………………………………………………..14-15

Annexes................................................................................. ......12-64

Les tests bench (simulations) des principaux modules………………………………………………………………12-13

Les codes VHDL à éditer et à completer sous ISE…………………………………………………………………16-46

ISE Project : choix pour développement...................... ..................... ..........32

Le schéma principal TOP modul sous ISE du projet…………………………………………………………………..…32

Le fichier principal VHDL TOP modul sous ISE du projet…………………………………………..………33-39

Les fichiers de contraintes TP.ucf (.ucf user contraints file).............................40-46

****Partie 3 UART et Xilinx ISE****

Ajout du module UART pour communication PC ……………………………………………………………… ………...….47

Liaison série UART principe 48

Code VHDL à éditer et à compléter 49-52

Communication avec la carte FPGA : PuTTY 55

Communication avec la carte FPGA : Python 57

Le fichier de contrainte pour l’ajout de l’UART 57-61

La carte d’évaluation Digilent Nexys 4 et A7-100T………………………………………………………….……..63-64

Page 3: TP projet FPGA Introduction au Moteur pas à pas

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 en mode local par potentiomètre numérique et à distance avec une liaison USB-série avec le

pont UART à disposition sur la carte FPGA.

Dans un premier temps on développera la partie contrôle local avec un encodeur numérique.

Dans un second temps on ajoutera le module de communication UART (liaison série asynchrone) pour

charger les données à distance via un PC avec l’utilitaire PuTTY, (émulateur de terminal), à

télécharger sur https://www.putty.org/.

Enfin pour une communication plus haut niveau on installera Python 3.9.2 suivre le lien ci-dessous :

https://www.framboise314.fr/installer-python-et-pyserial-sur-windows/ pour interfacer la carte

FPGA et programmer des rampes en modifiant la fréquence du moteur pas à pas de façon dynamique.

La carte FPGA dispose d’un port USB double pont FTDI FT2232HQ USB-UART, un pour

programmer la puce FPGA et l’autre pour communiquer avec une liaison série, port COM.

Voir document ci-joint suivant la carte utilisée : NEXYS 4

https://reference.digilentinc.com/reference/programmable-logic/nexys-4-ddr/reference-manual

Voir document ci-joint suivant la carte utilisée : A7-100T

https://reference.digilentinc.com/reference/programmable-logic/nexys-a7/reference-

manual?s[]=a7&s[]=100t

En pratique, il faudra afficher la fréquence de fonctionnement du moteur, le pas ainsi que la vitesse

en tr/min. Attention dans le projet vous devrez afficher sur 12 afficheurs.

Le moteur fonctionne en boucle ouverte non asservi, moteur utilisé : 28BYJ-48 5V moteur unipolaire

à 4 enroulements avec réducteur, 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

Moteur utilisé : 28BYJ-48 5V moteur unipolaire

• Alimentation : 5 Vcc

• Résistance : 21 ohms

• Intensité : 25 mA

• Réduction : 1/64

• Nombre de pas par tour : 64 (réduction de 4096 en sortie d'axe)

• Entraxe de fixation : 35 mm

• Axe : Ø5 mm avec double méplat (épaisseur 3 mm)

• Longueur de l’axe : 12 mm

Page 4: TP projet FPGA Introduction au Moteur pas à pas

4

Présentation TP

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

Page 5: TP projet FPGA Introduction au Moteur pas à pas

5

Présentation TP

CW

CCW

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

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 3. Ajout du module UART sous ISE web pack 14.7 et communication via PuTTY et Python

Page 6: TP projet FPGA Introduction au Moteur pas à pas

6

Partie 1 CAO

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. Télécharger la version Etudiant pour le travail

hors TP en présentiel sur le site https://www.altium.com/solutions/academic-programs/student-

licenses. Licence gratuite pour 6 mois avec une adresse mail accréditée (EDU/Université).

D’un point de vue pratique nous utiliserons une machine à gravure anglaise, la LPKF protoMatE44

pour développer les deux circuits imprimés, (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.

Les deux cartes se connecterons sur les connecteurs « Pmod » de la carte FPGA.

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.

Logiciel de CAO électronique Altium Designer 20

Carte FPGA disponible

Page 7: TP projet FPGA Introduction au Moteur pas à pas

7

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

Page 8: TP projet FPGA Introduction au Moteur pas à pas

8

Carte à développer sous ALTIUM DESIGNER 20

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

Sous Altium designer 20 Vue PCB et 3D

Page 9: TP projet FPGA Introduction au Moteur pas à pas

9

Partie 2

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 suivre les instructions dans le

document texte fourni.

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 3 Xilinx ISE 14.7

Figure 2 Carte FPGA avec les cartes filles Figure 1 Carte FPGA avec les cartes filles

Page 10: TP projet FPGA Introduction au Moteur pas à pas

10

Les principaux modules en code VHDL à réaliser

Figure 4 vue RTL sous Xilinx ISE 14.7 du projet

Page 11: TP projet FPGA Introduction au Moteur pas à pas

11

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 Decode_2_to_4.vhd MUX_8_to_1.vhd Mux_4_to_1.vhd

Afficheur 7 segments:

BCD_7segments.vhd et BCD_7segments_carte_fille.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_et_affichage.vhd

Module affichage fréquence

Calcul_vitesse_stepper_motor_et_affichage.vhd

Module USB_or_codeur

USB_or_codeur_and_RAM.vhd

Page 12: TP projet FPGA Introduction au Moteur pas à pas

12

ANNEXES

Tests bench

Module CLOCK manager 1

Module CLOCK manager 2

Module encodeur numérique

Page 13: TP projet FPGA Introduction au Moteur pas à pas

13

ANNEXES

Tests bench

Module encodeur numérique

Module machine d’état moteur pas à pas

Module machine d’état moteur pas à pas

Page 14: TP projet FPGA Introduction au Moteur pas à pas

14

ANNEXES

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

Page 15: TP projet FPGA Introduction au Moteur pas à pas

15

ANNEXES Machine d’état du codeur incrémental

Page 16: TP projet FPGA Introduction au Moteur pas à pas

16

ANNEXES

--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—

Page 17: TP projet FPGA Introduction au Moteur pas à pas

17

ANNEXES

--Code codeur numérique à completer-

when S1=> if rotary_A ='1' and rotary_B = '1' then -- si pas d'action on reste en S1--

etat <= S1;

elsif rotary_A ='0' and rotary_B = '1' then -- si rotation CW --

etat <= S2;

elsif rotary_A ='1' and rotary_B = '0' then -- si rotation CCW --

etat <= S5;

end if;

when S2=> if rotary_A ='0' and rotary_B = '0' then

etat <= S3;

end if;

when S3=> if rotary_A ='1' and rotary_B = '0' then

etat <= S4;

end if;

when S4=> if rotary_A ='1' and rotary_B = '1' then

compteur <= compteur + 1;

etat <= S1;

end if;

… --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—

Chronogramme pour CW → or CCW

S1 S2 S3 S4 S1 or S7 S6 S5

Page 18: TP projet FPGA Introduction au Moteur pas à pas

18

ANNEXES

--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; --10 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;

Page 19: TP projet FPGA Introduction au Moteur pas à pas

19

ANNEXES

--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

when attente => Commandes_demi_pas <="0000"; --0--

if bouton_UP = '1' and bouton_DOWN='0' then

state_machine <= position1;

elsif bouton_UP = '0' and bouton_DOWN='1' then

state_machine <= position8;

else

state_machine <= attente;

end if;

--UP & DOWN--

when position1 => Commandes_demi_pas <="0001"; --1--

if bouton_UP = '1' and bouton_DOWN='0' then

state_machine <= position2;

elsif bouton_UP = '0' and bouton_DOWN='1' then

state_machine <= position8; --9--

else

state_machine <= attente;

end if;

when position2 => Commandes_demi_pas <="0011"; --3--

if bouton_UP = '1' and bouton_DOWN='0' then

state_machine <= position3;

elsif bouton_UP = '0' and bouton_DOWN='1' then

state_machine <= position1; --1--

else

state_machine <= attente;

end if;

… --code à completer

Page 20: TP projet FPGA Introduction au Moteur pas à pas

20

ANNEXES

--Code state machine moteur à completer—

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;

Page 21: TP projet FPGA Introduction au Moteur pas à pas

21

ANNEXES --Code clock manager 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_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

if reset='1' then

count1 <= 0;

count2 <= 0;

ELSIF rising_edge(clk) then

if ce ='1' then

IF count1 <= M1-1 THEN --Divise par 10000 FOUT = 1000Hz synchro affichage

count1 <= count1 + 1;

ELSE

count1 <= 0;

END IF;

IF count2 <= M2-1 THEN --Divise par 10000 FOUT = 1000Hz synchro affichage

count1 <= count1 + 1;

ELSE

count1 <= 0;

END IF;

end if;

END IF;

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;

Page 22: TP projet FPGA Introduction au Moteur pas à pas

22

ANNEXES --Code Mux 8 to 1---

-- 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;

when "010" => Sortie_Mux <= C;

when "011" => Sortie_Mux <= D;

when "100" => Sortie_Mux <= E;

when "101" => Sortie_Mux <= F;

when "110" => Sortie_Mux <= G;

when "111" => Sortie_Mux <= H;

when others => Sortie_Mux <= A;

end case;

end process;

end Behavioral;

Page 23: TP projet FPGA Introduction au Moteur pas à pas

23

ANNEXES

--Code decode 2 to 8 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 DECODE_2_to_8 is

Port (

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 DECODE_2_to_8;

architecture Behavioral of DECODE_2_to_8 is

begin

process(Sel)

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';

case sel is

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

when "001" =>afficheur_1 <='0'; DP1 <='1';

when "010" =>afficheur_2 <='0'; DP1 <='1';

when "011" =>afficheur_3 <='0'; DP1 <='1';

when "100" =>afficheur_4 <='0'; DP1 <='1';

when "101" =>afficheur_5 <='0'; DP1 <='1';

when "110" =>afficheur_6 <='0'; DP1 <='1';

when "111" =>afficheur_7 <='0'; DP1 <='0';

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

end case;

end process;

end Behavioral;

Page 24: TP projet FPGA Introduction au Moteur pas à pas

24

ANNEXES

--Code BCD 7 segments 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;

Page 25: TP projet FPGA Introduction au Moteur pas à pas

25

ANNEXES

--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

if reset ='1' then

compte <="000";

elsif rising_edge(CLK) then

if enable ='1' then

compte <= compte + 1;

end if;

end if;

END PROCESS;

Sortie_compteur <= compte;

end Behavioral;

Page 26: TP projet FPGA Introduction au Moteur pas à pas

26

ANNEXES --Code compteur BCD --

-- 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; --10 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

Page 27: TP projet FPGA Introduction au Moteur pas à pas

27

ANNEXES

--Code compteur BCD complet—

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

if IS_4096 = '1' then

COUNTER_U <= 0;

COUNTER_D <= 0;

COUNTER_H <= 0;

COUNTER_T <= 0;

elsif IS_4096 = '0' then

if COUNTER_U = 9 then

COUNTER_U <= 0;

if COUNTER_D = 9 then

COUNTER_D <= 0;

if COUNTER_H = 9 then

COUNTER_H <= 0;

if COUNTER_T = 9 then

COUNTER_T <= 0;

else

COUNTER_T <= COUNTER_T + 1;

end if;

else

COUNTER_H <= COUNTER_H + 1;

end if;

Page 28: TP projet FPGA Introduction au Moteur pas à pas

28

ANNEXES

--Code compteur BCD complet—

else

COUNTER_D <= COUNTER_D + 1;

end if;

else

COUNTER_U <= COUNTER_U + 1;

end if;

end if;

end if;

if bouton_DOWN ='1' then

if IS_0000 ='0' then

if COUNTER_U = 0 then

COUNTER_U <= 9;

if COUNTER_D = 0 then

COUNTER_D <= 9;

if COUNTER_H = 0 then

COUNTER_H <= 9;

if COUNTER_T = 0 then

COUNTER_T <= 9;

else

COUNTER_T <= COUNTER_T - 1;

end if;

else

COUNTER_H <= COUNTER_H - 1;

end if;

else

COUNTER_D <= COUNTER_D - 1;

end if;

else

COUNTER_U <= COUNTER_U - 1;

end if;

end if;

end if;

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;

Page 29: TP projet FPGA Introduction au Moteur pas à pas

29

ANNEXES

--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--

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 decalage_a_gauche: INTEGER;

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) --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

Page 30: TP projet FPGA Introduction au Moteur pas à pas

30

ANNEXES

--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;

Page 31: TP projet FPGA Introduction au Moteur pas à pas

31

ANNEXES

--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;

-- 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;

Page 32: TP projet FPGA Introduction au Moteur pas à pas

32

ANNEXES

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 5 schéma principal pour le projet

Page 33: TP projet FPGA Introduction au Moteur pas à pas

33

ANNEXES

Fichier principal VHDL TOP modul sous ISE Sous forme de déclaration des composants et 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';

Page 34: TP projet FPGA Introduction au Moteur pas à pas

34

ANNEXES

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;

Page 35: TP projet FPGA Introduction au Moteur pas à pas

35

ANNEXES

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;

Page 36: TP projet FPGA Introduction au Moteur pas à pas

36

ANNEXES

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

Page 37: TP projet FPGA Introduction au Moteur pas à pas

37

ANNEXES

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)

);

Page 38: TP projet FPGA Introduction au Moteur pas à pas

38

ANNEXES

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

);

Page 39: TP projet FPGA Introduction au Moteur pas à pas

39

ANNEXES

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;

Page 40: TP projet FPGA Introduction au Moteur pas à pas

40

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

## 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 = J15;

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;

Page 41: TP projet FPGA Introduction au Moteur pas à pas

41

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

## 7 segment display 2

#Bank = 34, Pin name = IO_L2N_T0_34,

NET "SEG2[0]" LOC = U11; #Sch name = JB10

NET "SEG2[0]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L3N_T0_DQS_34,

NET "SEG2[1]" LOC = V11; #Sch name = JB3

NET "SEG2[1]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L6N_T0_VREF_34,

NET "SEG2[2]" LOC = T9; #Sch name = JB9

NET "SEG2[2]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L5N_T0_34,

NET "SEG2[3]" LOC = P15; #Sch name = JB2

NET "SEG2[3]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L2P_T0_34,

NET "SEG2[4]" LOC = R16; #Sch name = JB8

NET "SEG2[4]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L6P_T0_34,

NET "SEG2[5]" LOC = G14; #Sch name = JB1

NET "SEG2[5]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L4N_T0_34,

NET "SEG2[6]" LOC = K16; #Sch name = JB7

NET "SEG2[6]" IOSTANDARD = LVCMOS33;

#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;

Page 42: TP projet FPGA Introduction au Moteur pas à pas

42

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

#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 "afficheur_8" LOC = E17; # Sch name = JA10

NET "afficheur_8" IOSTANDARD = LVCMOS33;

NET "afficheur_9" LOC = E18; # Sch name = JA4

NET "afficheur_9" IOSTANDARD = LVCMOS33;

NET "afficheur_10" LOC = D17; # Sch name = JA9

NET "afficheur_10" IOSTANDARD = LVCMOS33;

NET "afficheur_11" LOC = D18; # Sch name = JA3

NET "afficheur_11" IOSTANDARD = LVCMOS33;

NET "afficheur_8" DRIVE = 16;

NET "afficheur_9" DRIVE = 16;

NET "afficheur_10" DRIVE = 16;

NET "afficheur_11" DRIVE = 16;

NET "afficheur_8" SLEW = FAST;

NET "afficheur_9" SLEW = FAST;

NET "afficheur_10" SLEW = FAST;

NET "afficheur_11" SLEW = FAST;

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;

Page 43: TP projet FPGA Introduction au Moteur pas à pas

43

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

NET "reset" LOC = R10;

NET "reset" IOSTANDARD = LVCMOS33;

NET "FULL" LOC = R8;

NET "FULL" IOSTANDARD = LVCMOS33;

NET "EMPTY" LOC = V9;

NET "EMPTY" IOSTANDARD = LVCMOS33;

#NET "data_send" LOC = K2;

#NET "data_send" IOSTANDARD = LVCMOS33;

#NET "select_CW_or_CCW[1]" LOC = P4;

#NET "select_CW_or_CCW[1]" IOSTANDARD = LVCMOS33;

#NET "select_CW_or_CCW[0]" LOC = P3;

#NET "select_CW_or_CCW[0]" IOSTANDARD = LVCMOS33;

## Pmod Header JA

#Bank = 15, Pin name = IO_L1N_T0_AD0N_15, Sch name = JA7

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 = JA1

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 = JA8

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 = JA2

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;

Page 44: TP projet FPGA Introduction au Moteur pas à pas

44

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

the Nexys A7-100T

## This file is a general .xdc for the Nexys A7-100T

## To use it in a project:

## - uncomment the lines corresponding to used pins

## - rename the used ports (in each line, after get_ports) according to the top level signal names

in the project

## Clock signal

NET "CLK_BRD" LOC = E3;

NET "CLK_BRD" IOSTANDARD = LVCMOS33;

## Switches Sch name = SW0

NET "enable" LOC = U9;

NET "enable" IOSTANDARD = LVCMOS33;

#NET "select_freq_or_vitesse" LOC = V10;

#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 = T10;

NET "seg[0]" IOSTANDARD = LVCMOS33;

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

NET "seg[1]" LOC = R10;

NET "seg[1]" IOSTANDARD = LVCMOS33;

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

NET "seg[2]" LOC = K16;

NET "seg[2]" IOSTANDARD = LVCMOS33;

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

NET "seg[3]" LOC = K13;

NET "seg[3]" IOSTANDARD = LVCMOS33;

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

NET "seg[4]" LOC = P15;

NET "seg[4]" IOSTANDARD = LVCMOS33;

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

NET "seg[5]" LOC = T11;

NET "seg[5]" IOSTANDARD = LVCMOS33;

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

NET "seg[6]" LOC = L18;

NET "seg[6]" IOSTANDARD = LVCMOS33;

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

NET "dp" LOC = M4;

NET "dp" IOSTANDARD = LVCMOS33;

Page 45: TP projet FPGA Introduction au Moteur pas à pas

45

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

the Nexys A7-100T

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

NET "afficheur_0" LOC = J17;

NET "afficheur_0" IOSTANDARD = LVCMOS33;

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

NET "afficheur_1" LOC = J18;

NET "afficheur_1" IOSTANDARD = LVCMOS33;

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

NET "afficheur_2" LOC = T9;

NET "afficheur_2" IOSTANDARD = LVCMOS33;

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

NET "afficheur_3" LOC = J14;

NET "afficheur_3" IOSTANDARD = LVCMOS33;

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

NET "afficheur_4" LOC = P14;

NET "afficheur_4" IOSTANDARD = LVCMOS33;

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

NET "afficheur_5" LOC = T14;

NET "afficheur_5" IOSTANDARD = LVCMOS33;

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

NET "afficheur_6" LOC = K2;

NET "afficheur_6" IOSTANDARD = LVCMOS33;

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

NET "afficheur_7" LOC = U13;

NET "afficheur_7" IOSTANDARD = LVCMOS33;

NET "bouton_UP" LOC = M18;

NET "bouton_UP" IOSTANDARD = LVCMOS33;

NET "bouton_DOWN" LOC = P18;

NET "bouton_DOWN" IOSTANDARD = LVCMOS33;

## Pmod Header JD

NET "rotary_A" LOC =G2;

NET "rotary_A" IOSTANDARD = LVCMOS33;

NET "rotary_B" LOC =F3;

NET "rotary_B" IOSTANDARD = LVCMOS33;

NET "Visu_UP_freq" LOC = R12;

NET "Visu_UP_freq" IOSTANDARD = LVCMOS33;

NET "Visu_DOWN_freq" LOC = M16;

NET "Visu_DOWN_freq" IOSTANDARD = LVCMOS33;

Page 46: TP projet FPGA Introduction au Moteur pas à pas

46

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

the Nexys A7-100T

NET "reset" LOC = M17;

NET "reset" IOSTANDARD = LVCMOS33;

NET "FULL" LOC = R11;

NET "FULL" IOSTANDARD = LVCMOS33;

NET "EMPTY" LOC = N16;

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 = C17;

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 = D18;

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 = E18;

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 = G17;

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;

Page 47: TP projet FPGA Introduction au Moteur pas à pas

47

Ajout du module de communication UART (liaison série asynchrone)

Et des modules supplémentaires au projet Les modules ci-dessous permettrons de piloter via un PC la vitesse du moteur (fréquence entre 0 et

255Hz) le sens de rotation et le démarrage du moteur avec le clavier du PC et l’application PuTTY

Module_Uart, Module_selection USB_com_or_encodeur com et bloc RAM, Module_gestion_moteur

Page 48: TP projet FPGA Introduction au Moteur pas à pas

48

ANNEXES

--Code UART liaison Série asynchrone—

UART (Universal Asynchronous Receiver Transmitter) .

Appelé port série, interface RS-232, port COM, mais le nom correct est en fait UART (Universal

Asynchronous Receiver Transmitter). Un UART est l'une des méthodes les plus simples pour parler

à votre FPGA. Il peut être utilisé pour envoyer des commandes d'un ordinateur à un FPGA et vice

versa.

Un UART est une interface qui envoie généralement un octet à la fois sur un seul fil. Il ne transmet

pas le long d'une horloge avec les données, c'est pourquoi il est appelé asynchrone par opposition à

synchrone. Les UART peuvent fonctionner en semi-duplex (deux émetteurs partageant une ligne) ou

en duplex intégral (deux émetteurs chacun avec leur propre ligne). Les UART ont plusieurs

paramètres qui peuvent être définis par l'utilisateur. Ceux-ci sont :

Débit en bauds (9600, 19200, 115200, autres)

Nombre de bits de données (7, 8)

Bit de parité (activé, désactivé)

Bits d'arrêt (0, 1, 2)

Contrôle de flux (aucun, activé, matériel)

Le débit en bauds est la vitesse à laquelle les données série sont transmises. 9600 bauds signifie

9600 bits par seconde. Le nombre de bits de données est presque toujours défini sur huit. Un bit

de parité peut être ajouté après l'envoi des données. La parité est toujours calculée en effectuant

une opération XOR sur tous les bits de données. Un bit d'arrêt toujours mis à 1, et il peut y avoir 0,

1 ou 2 bits d'arrêt. Le contrôle de flux n'est généralement pas utilisé dans les applications

actuelles et sera probablement défini sur Aucun.

Comme mentionné précédemment, aucune horloge n'est envoyée avec les données. Dans toute

interface qui n'a pas d'horloge, les données doivent être échantillonnées pour les récupérer

correctement. Il doit être échantillonné au moins huit fois plus rapidement que le débit des bits de

données. Cela signifie que pour un UART de 115200 bauds, les données doivent être échantillonnées

à au moins 921,6 KHz (115200 baud * 8). Une horloge d'échantillonnage plus rapide peut être

utilisée.

Page 49: TP projet FPGA Introduction au Moteur pas à pas

49

ANNEXES

--Code UART liaison Série asynchrone— -- This file contains the UART Receiver and UART Transmitter.

--This receiver is able to receive 8 bits of serial data, one start bit, one stop bit, and no parity bit.

--When receive is complete data_send will be driven high for one clock cycle.

-- CLKS_PER_BIT = (Frequency of Clk) / (Frequency of UART) 100 MHz Clock, 9600 baud UART

-- (100000000) / (9600) = 10416

Library ;

use ieee.std_logic_1164.ALL;

use ieee.numeric_std.all;

entity UART_RX is

generic (

CLKS_PER_BIT : integer := 10416 -- pour 100MHz d’horloge et 9600 bps

);

port (

clk : in std_logic;

RX_Serial : in std_logic;

data_send : out std_logic;

RX_Byte : out std_logic_vector(7 downto 0)

);

end UART_RX;

architecture Behavioral of UART_RX is

type etat is (attente, Start_Bit, RX_Data_Bits,Stop_Bit, s_Cleanup);

signal state_machine: etat;

signal r_RX_Data_R : std_logic := '0';

signal r_RX_Data : std_logic := '0';

signal Clk_Count : integer range 0 to CLKS_PER_BIT-1 := 0;

signal r_Bit_Index : integer range 0 to 7 := 0; -- 8 Bits Total

signal r_RX_Byte : std_logic_vector(7 downto 0) := (others => '0');

signal r_data_send : std_logic := '0';

begin

-- Purpose: Double-register the incoming data.

-- This allows it to be used in the UART RX Clock Domain.

-- (It removes problems caused by metastabiliy)

process (clk)

begin

if rising_edge(clk) then

r_RX_Data_R <= RX_Serial;

r_RX_Data <= r_RX_Data_R;

end if;

end process;

Page 50: TP projet FPGA Introduction au Moteur pas à pas

50

ANNEXES

--Code UART liaison Série asynchrone—

-- Purpose: Control RX state machine

process(clk)

begin

if rising_edge(clk) then

case state_machine is

when attente =>

r_data_send <= '0';

Clk_Count <= 0;

r_Bit_Index <= 0;

if r_RX_Data = '0' then -- Start bit detected

state_machine <= Start_Bit;

else

state_machine <= attente;

end if;

-- Check middle of start bit to make sure it's still low

when Start_Bit =>

if Clk_Count = (CLKS_PER_BIT-1)/2 then

if r_RX_Data = '0' then

Clk_Count <= 0; -- reset counter since we found the middle

state_machine <= RX_Data_Bits;

else

state_machine <= attente;

end if;

else

Clk_Count <= Clk_Count + 1;

state_machine <= Start_Bit;

end if;

-- Wait CLKS_PER_BIT-1 clock cycles to sample serial data

when RX_Data_Bits =>

if Clk_Count < CLKS_PER_BIT-1 then

Clk_Count <= Clk_Count + 1;

state_machine <= RX_Data_Bits;

else

Clk_Count <= 0;

r_RX_Byte(r_Bit_Index) <= r_RX_Data;

Page 51: TP projet FPGA Introduction au Moteur pas à pas

51

ANNEXES

--Code UART liaison Série asynchrone—

-- Check if we have sent out all bits

if r_Bit_Index < 7 then

r_Bit_Index <= r_Bit_Index + 1;

state_machine <= RX_Data_Bits;

else

r_Bit_Index <= 0;

state_machine <= Stop_Bit;

end if;

end if;

-- Receive Stop bit. Stop bit = 1

when Stop_Bit =>

-- Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish

if Clk_Count < CLKS_PER_BIT-1 then

Clk_Count <= Clk_Count + 1;

state_machine <= Stop_Bit;

else

r_data_send <= '1';

Clk_Count <= 0;

state_machine <= s_Cleanup;

end if;

-- Stay here 1 clock

when s_Cleanup =>

state_machine <= attente;

r_data_send <= '0';

when others =>

state_machine <= attente;

end case;

end if;

end process;

data_send <= r_data_send;

RX_Byte <= r_RX_Byte;

end Behavioral;

Page 52: TP projet FPGA Introduction au Moteur pas à pas

52

ANNEXES

--Code gestion moteur à compléter—

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity Gestion_commande_motor is

Port (

bouton_montee : in STD_LOGIC;

bouton_descente : in STD_LOGIC;

start_motor_UP_PCcontrol : in STD_LOGIC;

start_motor_DOWN_PCcontrol : in STD_LOGIC;

bouton_UP : out STD_LOGIC;

bouton_DOWN : out STD_LOGIC

);

end Gestion_commande_motor;

architecture Behavioral of Gestion_commande_motor is

begin

process(bouton_montee,bouton_descente,start_motor_UP_PCcontrol,start_motor_DOWN_PCcont

rol)

begin

if bouton_montee ='1' or start_motor_UP_PCcontrol ='1' then

bouton_UP <='1';

else

bouton_UP <='0';

end if;

if bouton_descente ='1' or start_motor_DOWN_PCcontrol ='1' then

bouton_DOWN <='1';

else

bouton_DOWN <='0';

end if;

end process;

end Behavioral;

Page 53: TP projet FPGA Introduction au Moteur pas à pas

53

ANNEXES

--Code Communication USB or codeur and RAM—

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;

entity USB_codeur_and_RAM is

Port (

reset : in std_logic;

codeur_in : in STD_LOGIC_VECTOR (7 downto 0);

enable: in std_logic;

RX_DV : in STD_LOGIC;

Rx_data_Uart : in STD_LOGIC_VECTOR (7 downto 0);

select_codeur_or_uart : in STD_LOGIC;

start_motor_UP : out STD_LOGIC;

start_motor_down : out STD_LOGIC;

reglage_frequency_motor : out STD_LOGIC_VECTOR (7 downto 0)

);

end USB_codeur_and_RAM;

architecture Behavioral of USB_codeur_and_RAM is

-- define the new type for the 3x8 octets RAM

type RAM_ARRAY is array (0 to 2) of std_logic_vector (7 downto 0);

signal RST_RAM : STD_LOGIC;

signal RAM_ADDR: STD_LOGIC_VECTOR (1 downto 0); -- Address to write/read RAM

-- initial values in the RAM

signal RAM: RAM_ARRAY :=(

x"00",x"00",x"00" );

signal bin_out : STD_LOGIC_VECTOR (10 downto 0);

signal bcd_in_0 : STD_LOGIC_VECTOR (3 downto 0);

signal bcd_in_10 : STD_LOGIC_VECTOR (3 downto 0);

signal bcd_in_100 : STD_LOGIC_VECTOR (3 downto 0);

signal UP : STD_LOGIC :='0';

signal DOWN : STD_LOGIC :='0';

begin

Page 54: TP projet FPGA Introduction au Moteur pas à pas

54

ANNEXES

--Code Communication USB or codeur and RAM—

process(RX_DV,enable,reset,RST_RAM)

begin

if reset ='1' or RST_RAM ='1' then

RAM_ADDR <= "00";

RAM(0) <=X"00";

RAM(1) <=X"00";

RAM(2) <=X"00";

elsif rising_edge(RX_DV) then

if enable ='1' then

IF RAM_ADDR <=3 THEN

RAM_ADDR <= RAM_ADDR + 1;

END IF;

if Rx_data_uart>= X"30" and Rx_data_uart <= X"39" then

RAM(to_integer(unsigned(RAM_ADDR))) <= Rx_data_uart - X"30";

-- converts RAM_ADDR from std_logic_vector -> Unsigned -> Integer using numeric_std library

end if;

if Rx_data_uart< X"30" and Rx_data_uart> X"39" then

RAM(to_integer(unsigned(RAM_ADDR))) <= "00000000";

end if;

end if;

end if;

end process;

--this module is for converting a 4 digit BCD number into binary number.

--the range of the input in decimal is 0 to 999.

bcd_in_0 <= RAM(2)(3 downto 0); --use 4 bits in RAM 2

bcd_in_10 <= RAM(1)(3 downto 0); --use 4 bits in RAM 1

bcd_in_100 <= RAM(0)(3 downto 0); --use 4 bits in RAM 0

bin_out <= (bcd_in_0 * "01") --multiply by 1

+ (bcd_in_10 * "1010") --multiply by 10

+ (bcd_in_100 * "1100100"); --multiply by 100

RST_RAM <='1' when Rx_data_uart = X"72" else '0'; -- r du clavier

UP <='1' when Rx_data_uart = X"75" else '0'; -- u du clavier

DOWN <='1' when Rx_data_uart = X"64" else '0'; -- d du clavier

reglage_frequency_motor <= bin_out(7 downto 0) when select_codeur_or_uart ='1' else codeur_in;

start_motor_UP <= '1' when UP = '1' else '0';

start_motor_DOWN <= '1' when DOWN ='1' else '0';

end Behavioral;

Page 55: TP projet FPGA Introduction au Moteur pas à pas

55

ANNEXES

--Connection PC et Carte FPGA—

Figure 7 Carte FPGA avec les cartes filles Figure 6 Carte FPGA avec les cartes filles

Avec PuTTY on charge la fréquence de fonctionnement du

moteur entre 0 et 255Hz avec le pavé numérique du

clavier. Le sens de rotation UP and DOWN touche ‘u’ et ‘d’.

La touche ‘r’ pour le Reset des valeurs mémorisées en

RAM

Page 56: TP projet FPGA Introduction au Moteur pas à pas

56

ANNEXES

--Connection PC et Carte FPGA avec programme Python-

Modification du module USB_or_codeur_com

Page 57: TP projet FPGA Introduction au Moteur pas à pas

57

ANNEXES

--Connection PC et Carte FPGA avec programme Python- Modification du module USB_or_codeur_with_python_com

code VHDL

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;

entity USB_or_codeur_with_python_com is

Port (

select_CW_or_CCW : in STD_LOGIC_VECTOR (1 downto 0);

codeur_in : in STD_LOGIC_VECTOR (7 downto 0);

Rx_data_Uart : in STD_LOGIC_VECTOR (7 downto 0);

select_codeur_or_uart : in STD_LOGIC;

start_motor_UP : out STD_LOGIC;

start_motor_down : out STD_LOGIC;

reglage_frequency_motor : out STD_LOGIC_VECTOR (7 downto 0)

);

end USB_or_codeur_with_python_com;

architecture Behavioral of USB_or_codeur_with_python_com is

signal UP : STD_LOGIC :='0';

signal DOWN : STD_LOGIC :='0';

begin

process(select_CW_or_CCW,UP,DOWN)

begin

case select_CW_or_CCW is

when "00" => UP <='0'; DOWN <='0';

when "01" => UP <='0'; DOWN <='1';

when "10" => UP <='1'; DOWN <='0';

when "11" => UP <='0'; DOWN <='0';

when others => null;

end case;

end process;

reglage_frequency_motor <= Rx_data_Uart(7 downto 0) when select_codeur_or_uart ='1' else

codeur_in;

start_motor_UP <= '1' when UP = '1' else '0';

start_motor_DOWN <= '1' when DOWN ='1' else '0';

end Behavioral;

Page 58: TP projet FPGA Introduction au Moteur pas à pas

58

ANNEXES

--Connection PC et Carte FPGA avec programme Python- Code pour IDE Python : rampe de fréquence

# -*- coding: utf-8 -*-

# On importe Tkinter

import serial

import struct

import time

# definition du port série

ser =serial.Serial(

port ='COM15',

baudrate = 9600,

parity = serial.PARITY_NONE,

stopbits = serial.STOPBITS_ONE,

bytesize = serial.EIGHTBITS,

timeout = 100

)

def packUnsignedCharAsUChar(valeur):

"""Packs a python 1 byte unsigned char"""

return struct.pack('B', valeur) #should check bounds

def compteur1(): # rampe montante

i = 1

while i <= 255:

time.sleep(0.05) # délais entre chaque valeur à envoyer

ser.write(packUnsignedCharAsUChar(i))

print(i)

i = i + 1

if i == 255:

compteur2()

def compteur2(): # rampe descendante

i = 255

while i >= 0:

time.sleep(0.1) # délais entre chaque valeur à envoyer

ser.write(packUnsignedCharAsUChar(i))

print(i)

i = i - 1

if i == 0:

compteur1()

while True: # boucle continu

compteur1()

Page 59: TP projet FPGA Introduction au Moteur pas à pas

59

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

Pour l’ajout du module UART

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

## 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 = J15;

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;

Page 60: TP projet FPGA Introduction au Moteur pas à pas

60

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

## 7 segment display 2

#Bank = 34, Pin name = IO_L2N_T0_34,

NET "SEG2[0]" LOC = U11; #Sch name = JB10

NET "SEG2[0]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L3N_T0_DQS_34,

NET "SEG2[1]" LOC = V11; #Sch name = JB3

NET "SEG2[1]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L6N_T0_VREF_34,

NET "SEG2[2]" LOC = T9; #Sch name = JB9

NET "SEG2[2]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L5N_T0_34,

NET "SEG2[3]" LOC = P15; #Sch name = JB2

NET "SEG2[3]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L2P_T0_34,

NET "SEG2[4]" LOC = R16; #Sch name = JB8

NET "SEG2[4]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L6P_T0_34,

NET "SEG2[5]" LOC = G14; #Sch name = JB1

NET "SEG2[5]" IOSTANDARD = LVCMOS33;

#Bank = 34, Pin name = IO_L4N_T0_34,

NET "SEG2[6]" LOC = K16; #Sch name = JB7

NET "SEG2[6]" IOSTANDARD = LVCMOS33;

NET "reset" LOC = R10;

NET "reset" IOSTANDARD = LVCMOS33;

#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;

Page 61: TP projet FPGA Introduction au Moteur pas à pas

61

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

#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 "afficheur_8" LOC = E17; # Sch name = JA10

NET "afficheur_8" IOSTANDARD = LVCMOS33;

NET "afficheur_9" LOC = E18; # Sch name = JA4

NET "afficheur_9" IOSTANDARD = LVCMOS33;

NET "afficheur_10" LOC = D17; # Sch name = JA9

NET "afficheur_10" IOSTANDARD = LVCMOS33;

NET "afficheur_11" LOC = D18; # Sch name = JA3

NET "afficheur_11" IOSTANDARD = LVCMOS33;

NET "afficheur_8" DRIVE = 16;

NET "afficheur_9" DRIVE = 16;

NET "afficheur_10" DRIVE = 16;

NET "afficheur_11" DRIVE = 16;

NET "afficheur_8" SLEW = FAST;

NET "afficheur_9" SLEW = FAST;

NET "afficheur_10" SLEW = FAST;

NET "afficheur_11" SLEW = FAST;

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;

Page 62: TP projet FPGA Introduction au Moteur pas à pas

62

ANNEXES

Le fichier de contrainte (entrées-sorties à “cabler”)

À completer et à verifier suivant la carte FPGA utilisée

Nexys4 rev B board

NET "data_send" LOC = K2;

NET "data_send" IOSTANDARD = LVCMOS33;

NET "select_CW_or_CCW[1]" LOC = P4;

NET "select_CW_or_CCW[1]" IOSTANDARD = LVCMOS33;

NET "select_CW_or_CCW[0]" LOC = P3;

NET "select_CW_or_CCW[0]" IOSTANDARD = LVCMOS33;

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;

NET "select_data_in" LOC = U8;

NET "select_data_in" IOSTANDARD = LVCMOS33;

NET "RX" LOC = C4;

NET "RX" IOSTANDARD = LVCMOS33;

Page 63: TP projet FPGA Introduction au Moteur pas à pas

63

ANNEXES

Carte de développement Digilent Nexys A7

Ci-dessous contenu de la boîte

A. Nexys a7-100t 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.

Page 64: TP projet FPGA Introduction au Moteur pas à pas

64

ANNEXES

Carte de développement Digilent Nexys 4

Ci-dessous contenu de la boîte

D. Nexys 4 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.