baf5e4b6
rduhr
7Segment_display ...
|
1
2
3
4
|
# 7 Segment display
1. But du projet
1. I/O utilisées
|
45802ae2
rduhr
7Segment_display ...
|
5
6
|
1. Explication de l'algorithme
1. Résultats
|
baf5e4b6
rduhr
7Segment_display ...
|
7
8
9
10
11
12
13
|
> L'ensemble des codes, images et vidéos sont compris dans ce répertoire.
## But du projet
Nous avons décider de nous intéresser à l'affichage 7 segments grâce au but suivant:
|
e3f42ce5
rduhr
7Segment_display ...
|
14
|
- Créer un compteur de 0 à 9999 à l'aide des 4 afficheurs. En cas de dépassement ou d'appuye sur un bouton reset le compteur redémarrera à 0.
|
baf5e4b6
rduhr
7Segment_display ...
|
15
16
17
18
|
## I/O utilisées
Tout d'abord, voyons les entrées/sortie que nous avons utilisé.
|
122d531c
rduhr
7Segment_display ...
|
19
20
21
22
23
24
25
|
```vhdl
entity display is
port {
clk_fpga : in STD_LOGIC;
reset : in STD_LOGIC;
aff : out STD_LOGIC_VECTOR{7 downto 0};
|
baf5e4b6
rduhr
7Segment_display ...
|
26
|
an : out STD_LOGIC_VECTOR{3 downto 0}
|
122d531c
rduhr
7Segment_display ...
|
27
28
29
|
};
end display;
```
|
baf5e4b6
rduhr
7Segment_display ...
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
- clk_fpga : le signal de clock du fpga
Dans le fichier de contrainte :
```
## Clock signal
set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports clk_fpga]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
```
- reset : le signal permettant de remettre le compteur à zéro grâce à un bouton
Dans le fichier de contrainte :
```
## Switches
set_property -dict { PACKAGE_PIN R2 IOSTANDARD LVCMOS33 } [get_ports reset]
```
- aff : un tableau de 8 bits relier à chaque led d'un segment à afficher (en ajoutant le point de l'afficheur)
Dans le fichier de contrainte :
```
##7 Segment Display
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports {aff[0]}]
set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports {aff[1]}]
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports {aff[2]}]
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports {aff[3]}]
set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports {aff[4]}]
set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports {aff[5]}]
set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports {aff[6]}]
set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports {aff[7]}]
```
|
33423a82
rduhr
7Segment_display ...
|
62
|
> exemple : aff à "11111110" allumera la led du point de l'afficheur séléctionné.
|
baf5e4b6
rduhr
7Segment_display ...
|
63
64
65
66
67
68
69
70
71
72
73
|
- an : un tableau comprenant 4 bits permettant de sélectionner l'un des 4 afficheurs 7 segments
Dans le fichier de contrainte :
```
set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports {an[0]}]
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports {an[1]}]
set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports {an[2]}]
set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports {an[3]}]
```
|
33423a82
rduhr
7Segment_display ...
|
74
75
|
> exemple : an à "1110" sélectionnera l'afficheur le plus à droite.
|
45802ae2
rduhr
7Segment_display ...
|
76
77
|
## Explication de l'algorithme
|
a3654f0d
rduhr
7Segment_display ...
|
78
|
Les signaux
|
ccc0875f
rduhr
7Segment_display ...
|
79
80
81
82
83
84
|
les signaux utilisés vont nous permettre d'avoir un code clean et plus ou moins factorié.
```
architecture Behavioral of display is
|
c557f24c
rduhr
7Segment_display ...
|
85
|
signal count_an : integer range 3 downto 0 := 0;
|
ccc0875f
rduhr
7Segment_display ...
|
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
signal clk_enable : integer range 4999 downto 0 := 0;
signal clk_counter : integer range 2999999 downto 0 := 0;
constant nb0 : std_logic_vector(7 downto 0) := "11000000";
constant nb1 : std_logic_vector(7 downto 0) := "11111001";
constant nb2 : std_logic_vector(7 downto 0) := "10100100";
constant nb3 : std_logic_vector(7 downto 0) := "10110000";
constant nb4 : std_logic_vector(7 downto 0) := "10011001";
constant nb5 : std_logic_vector(7 downto 0) := "10010010";
constant nb6 : std_logic_vector(7 downto 0) := "10000010";
constant nb7 : std_logic_vector(7 downto 0) := "11111000";
constant nb8 : std_logic_vector(7 downto 0) := "10000000";
constant nb9 : std_logic_vector(7 downto 0) := "10010000";
constant seg0 : std_logic_vector(3 downto 0) := "1110";
constant seg1 : std_logic_vector(3 downto 0) := "1101";
constant seg2 : std_logic_vector(3 downto 0) := "1011";
constant seg3 : std_logic_vector(3 downto 0) := "0111";
signal chiffre4 : integer range 9 downto 0 := 0;
signal chiffre3 : integer range 9 downto 0 := 0;
signal chiffre2 : integer range 9 downto 0 := 0;
signal chiffre1 : integer range 9 downto 0 := 0;
type mynumbers is array(9 downto 0) of std_logic_vector(7 downto 0);
signal numbers : mynumbers := (nb9,nb8,nb7,nb6,nb5,nb4,nb3,nb2,nb1,nb0);
```
|
c557f24c
rduhr
7Segment_display ...
|
111
112
113
114
115
116
117
118
119
|
On a:
- count_an : compte pour effectuer les opérations sur les afficheurs un par un.
- clk_enable : diviser la clock pour l'affichage et évite les recouvrements.
- clk_counter : divise la clock pour le compteur et lui évite de compter bien trop rapidement.
- nb* : représentation des chiffres par leurs segments.
- seg* : attribue chaque segment à une valeur constante.
- chiffre* : variable représentant le chiffre en * position
- numbers : associe la représentation logique d'un chiffre à un entier.
|
cdbcafa7
rduhr
7Segment_display ...
|
120
121
122
123
|
Les process
|
96057910
rduhr
7Segment_display ...
|
124
|
- 1er process :
|
cdbcafa7
rduhr
7Segment_display ...
|
125
126
127
128
|
```
begin
|
46eee1ff
rduhr
7Segment_display ...
|
129
|
-- display process
|
cdbcafa7
rduhr
7Segment_display ...
|
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
process(clk_fpga)
begin
if clk_fpga'event and clk_fpga = '1' then
if clk_enable = 4999 then
clk_enable <= 0;
if count_an = 0 then
aff <= numbers(chiffre4);
an <= seg0;
count_an <= count_an + 1;
elsif count_an = 1 then
aff <= numbers(chiffre3);
an <= seg1;
count_an <= count_an + 1;
elsif count_an = 2 then
|
f85ce7b3
rduhr
7Segment_display ...
|
144
|
aff <= numbers(chiffre2);
|
cdbcafa7
rduhr
7Segment_display ...
|
145
146
147
|
an <= seg2;
count_an <= count_an + 1;
elsif count_an = 3 then
|
f85ce7b3
rduhr
7Segment_display ...
|
148
|
aff <= numbers(chiffre1);
|
cdbcafa7
rduhr
7Segment_display ...
|
149
150
151
152
153
154
155
156
157
|
an <= seg3;
count_an <= 0;
end if;
else
clk_enable <= clk_enable + 1;
end if;
end if;
end process;
```
|
46eee1ff
rduhr
7Segment_display ...
|
158
159
160
161
162
163
|
Ce premier processus permet à chaque tick de clock + diviseur d'afficher un chiffre sur le premier afficheur. Au prochain tick sur le second puis le 3ème et enfin le 4ème. Ensuite l'algorithme boucle.
> le diviseur (clk_enable) ralentit la cadence de switch entre afficheur. Si l'on ne divise du fait de la vitesse les chiffres ne s'affichent pas correctement.
Ainsi la logique et l'électronique étant ici très rapide devant la fréquence de percepetion de l'oeil humain, l'utilisateur à l'impression que l'affichage et statique et que rien ne clignote.
|
96057910
rduhr
7Segment_display ...
|
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
- 2ème processus :
```
-- process counter
process(clk_fpga)
begin
if clk_fpga'event and clk_fpga = '1' then
if clk_counter = 2999999 then
clk_counter <= 0;
if reset = '1' then
chiffre1 <= 0;
chiffre2 <= 0;
chiffre3 <= 0;
chiffre4 <= 0;
else if chiffre4 = 9 then
chiffre4 <= 0;
if chiffre3 = 9 then
chiffre3 <= 0;
if chiffre2 = 9 then
chiffre2 <= 0;
if chiffre1 = 9 then
chiffre1 <= 0;
else
chiffre1 <= chiffre1 + 1;
end if;
else
chiffre2 <= chiffre2 + 1;
end if;
else
chiffre3 <= chiffre3 + 1;
end if;
else
chiffre4 <= chiffre4 + 1;
end if;
else
clk_counter <= clk_counter + 1;
end if;
end if;
end process;
end Behavioral;
```
|
c51fda06
rduhr
7Segment_display ...
|
206
207
208
209
210
211
|
Ce processus permet de compter avec un diviseur de la clock de base.
Lorsque le chiffre tout à droite et à 9 et qu'il doit être incrémenter alors il passe à 0. Si le chiffre à sa gauche n'est pas à 9 alors il est incrémenter sinon il passe à 0 et on regarde le chiffre de gauche en suivant le même algorithme.
Si on a 9999 ou un 1 logique sur reset alors tout les chiffres repassent à 0.
|
45802ae2
rduhr
7Segment_display ...
|
212
213
|
## Résultats
|
78d80e83
rduhr
7Segment_display ...
|
214
|
- Nous avons dans un premier temps essayer d'afficher sur les 4 afficheurs sans recouvrement. C'est pour cela qu'il a fallu baisser la clock.
|
45802ae2
rduhr
7Segment_display ...
|
215
|
|
9b8bb3da
rduhr
7Segment_display ...
|
216
217
|
![img1](img1.jpg)
|
78d80e83
rduhr
7Segment_display ...
|
218
|
- Ensuite il a fallu donner du sens à ce que nous affichions. C'est pourquoi nous avons tenté d'afficher 1 2 3 4.
|
9b8bb3da
rduhr
7Segment_display ...
|
219
|
|
3d1a916a
rduhr
7Segment_display ...
|
220
221
222
223
|
![img2](img2.jpg)
- Enfin il a fallu implémanter un simple algorithme pour le compteur.
|
d8ca565d
rduhr
7Segment_display ...
|
224
|
![counter](counter.gif)
|