IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

f-leb

[FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur

Noter ce billet
par , 11/08/2022 à 08h00 (471 Affichages)
Les interrupteurs mécaniques en général (boutons-poussoirs, interrupteurs à bascule, à glissière, à levier, etc.) ont une fâcheuse habitude : ils sont sujets aux rebonds à la fermeture ou à l’ouverture du circuit. Ces rebonds sont parfois néfastes pour le fonctionnement de votre application, et il faut trouver des systèmes matériels ou logiciels pour les éviter.
Je présente ici la configuration d’un circuit logique d’une solution antirebonds sur une carte de développement FPGA, au travers de sa description avec un langage HDL (ici, Verilog).

L’objectif est décrit par les chronogrammes ci-dessous (simulation) :

Nom : debounce01.png
Affichages : 67
Taille : 14,9 Ko

En haut, le signal issu de la fermeture/ouverture d’un circuit par un interrupteur ou bouton. Le signal est « parasité » avec de multiples rebonds rapprochés. En bas, le signal debounce « nettoyé ». Une fois que le système considère le signal stabilisé (après un délai repéré en rouge), il bascule.

On utilisera les principes déjà vus lors des précédents billets :


En effet, le circuit logique à synthétiser est le suivant :

Nom : circuit-logique.png
Affichages : 66
Taille : 18,4 Ko

Le circuit est synchronisée avec l’horloge principale de la carte (entrée CLOCK_50), ici à la fréquence de 50MHz.
La structure de la partie gauche avec les deux bascules et la porte XOR (OU exclusif) a été vue dans le billet [FPGA] Créer un circuit logique pour détecter les fronts d’un signal.
Cette structure permet d’avoir une impulsion envoyée sur la sortie de la porte XOR à chaque rebond du bouton (front montant ou descendant).
La sortie de la porte XOR est reliée à l’entrée SCLR (Synchronous clear) d’un compteur (voir [FPGA] Créer un circuit logique pour faire un compteur), qui est donc remis à zéro à chaque rebond. C’est ce compteur qui contribue à définir la stabilité du signal après les rebonds. Le signal sera considéré comme stable si le compteur a le temps d’évoluer jusqu’à une valeur maximale. Si les rebonds sont trop rapprochés, le compteur est remis à zéro à chaque rebond avant d’attendre cette valeur maximale.

Nom : counter01.png
Affichages : 67
Taille : 25,8 Ko
Après chaque rebond, le compteur revient à zéro. Le signal n’est pas stable…

Quand le compteur atteint sa valeur limite, la sortie TC du compteur (Terminal count) bascule à l’état haut. En configurant un compteur 19 bits, une impulsion est donc envoyée sur la sortie TC si le compteur peut atteindre la valeur 219-1 sans être interrompu par un rebond, soit pendant une durée de (1/50.106)x219=10,49ms. Après cette durée, on considère que les rebonds du bouton sont terminés.

À ce moment-là, les choses s’enchaînent, suivez les connexions du circuit…
  1. Le compteur se bloque (parce que son entrée ENA (enable) est reliée au signal TC inversé). Il sera débloqué au prochain rebond (par la remise à zéro du compteur qui va abaisser le signal TC, et donc réactiver le compteur).
  2. La sortie TC étant bloquée à l’état haut en attendant le prochain rebond, la dernière bascule c est activée et le signal stabilisé du bouton est dirigé vers la sortie debounce.


On rappelle le code du compteur (counter.v) :
Code verilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
module counter (CLK, ENA, SCLR, TC);

	parameter N = 4;	// compteur N bits, valeur N par défaut

	input	CLK,	// horloge 'clock'
		ENA,  // enable
		SCLR;	// synchronous clear
	output TC;	// terminal count

	reg [N-1 : 0] count;	// compteur N bits

	assign TC = (count == {N{1'b1}});	// concaténation de 1, N fois

	always @(posedge CLK) begin	// sur front montant de l'horloge	
		if (SCLR) count <= 0; // synchronous clear
		else begin
			if (ENA) count <= count + 1'b1;		
		end
	end
	
endmodule

On donne le code du module principal top.v (top level hierarchy) :
Code verilog : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module top(CLOCK_50, button, debounce);

	input	CLOCK_50,	// horloge principale 50MHz
		button;	// signal du bouton, avec rebonds
	output	debounce;	// signal sans les rebonds

	reg a, b, c;			// registres internes
	wire bounce, stability;	// noeuds internes
	

	counter #(.N(19))	U1	// instanciation compteur 19 bits, paramètre N=19
					(.CLK(CLOCK_50),
					 .SCLR(bounce),	// à chaque rebond, il faut remettre à 0 le compteur
					 .ENA(~stability),  // comptage si pas de stabilité
					 .TC(stability)	// stable si le compteur atteint la valeur Terminal Count
					);

	assign bounce = a ^ b;	// ^ : opérateur Xor
	assign debounce = c;		  
				  
	always @(posedge CLOCK_50) begin	// processus sur front montant de l'horloge
		a <= button;
		b <= a;
		if (stability) c <= b;
	end

endmodule

Notez comment le compteur est instancié (lignes 11 à 16) et comment ses entrées-sorties sont raccordées aux nœuds du circuits.

Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Viadeo Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Twitter Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Google Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Facebook Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Digg Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Delicious Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog MySpace Envoyer le billet « [FPGA] Créer un circuit logique pour gérer les rebonds d’un interrupteur » dans le blog Yahoo

Tags: fpga, verilog
Catégories
Programmation , FPGA

Commentaires