Dernière mise à jour :
14/02/2016
Présentation
Le système présenté ici est un diviseur de fréquence programmable basé sur un PIC de
type 16F84A ou 16F628A, capable de diviser entre 1 et 1023, par pas de 1, au moyen
de dix interrupteurs.
On peut se limiter à huit interrupteurs de
programmation, si le taux de division maximal souhaité est de
256.
Fréquence
maximale du signal d'entrée : entre 25 kHz
et 30 kHz pour les versions 001a à 001c, 40 kHz pour la version 001d et
150 kHz pour la version 001e. Je conseille les deux dernières
versions 001d et 001e (pour 16F628A).
Schémas 001 (code logiciel 001a à 001c, avec 16F84A)
Pas spécialement complexe, mais requiert un
composant programmé. Un PIC, si vous voulez tout savoir.
Schéma désormais déconseillé, voir schéma 001d et 001e à base de 16F628A. Mais le descriptif texte est encore valable pour le principe de base.
Principe de base
Il est extrêmement simple, et consiste à compter le nombre
de changements d'état logique sur la ligne RB7 du PIC,
configurée en entrée et recevant le signal d'horloge
à diviser. Quant le nombre de changements d'état a
atteint le facteur de division spécifié (entre 1 et
1024), la ligne RA4 du PIC, configurée en sortie, change
d'état et le compteur d'impulsions d'entrée est remis
à zéro.
Facteur de division
Il est spécifié au moyen de microswitches (ou tout autres
types d'interrupteurs ou commande parallèle externe), sur un bus
de 10 bits. Sur le schéma, l'interrupteur le plus à
droite (faisant partie du bloc appelé SW1 et relié
à RA0) est celui de poids faible, et celui le plus à
gauche (relié à RB5) est celui de poids fort. Sur le
schéma, les interrupteurs "activés" sont ceux dont la
partie noire est en bas (côté ON de SW1), en l'occurence
les deuxième et quatrième interrupteurs en partant de la
droite. Le deuxième interrupteur (toujours en partant de la
droite) correspond à la valeur "2 puissance 1", soit 2. Le
quatrième interrupteur correspond quant à lui à la
valeur "2 puissance 3", soit 8. Si on additionne ces deux valeurs, on
obtient 10 (8 + 2) : le facteur de division est donc de 10, et pour un
signal entrant de fréquence 10 KHz, on dispose d'un signal
sortant de fréquence 1 KHz.
Limitation à un facteur de
division de 256
Vous pourrez préférer n'utiliser que huit microswitches
au lieu de 10. Si tel est le cas, rien de plus simple, il vous suffit
d'ignorer les lignes RB4 et RB5, qui restent portées au
potentiel de masse au travers des résistances de rappel de 10K
prévues sur le schéma. Si vous voulez économiser
sur ces deux résistances, n'oubliez pas de mettre ces deux
lignes RB4 et RB5 à la masse !
Relation de phase entre entrée et sortie
Il est important de noter que le traitement des changements
d'états du signal d'entrée prend un certain temps, qui
est lié à la durée d'exécution des routines
du programme interne au PIC. Le signal de sortie n'est donc pas en
phase avec le signal d'entrée, et la valeur du déphasage
dépend de la fréquence du signal d'entrée. Ce
n'est pas gênant pour certaines applications, mais ça peut
l'être pour d'autres.
Niveaux d'entrée et de sortie
Le schéma électronique est simplifié au maximum,
il n'y a ni adaptation en entrée, ni adaptation en sortie. Cela
va très bien pour des signaux au format TTL (0V / +5V). Mais si
vous souhaitez appliquer à l'entrée du montage des
signaux d'amplitude inférieure, il faut impérativement
ajouter un petit étage d'entrée, de
préférence à haute ou moyenne impédance (un
simple NPN de type BC109 - ou même un FET, pourquoi pas -
conviendra très bien). Pour la sortie, même topo : un
petit buffer de sortie permettra de ne pas exposer la sortie du PIC
à un environnement qui peut parfois s'avérer "hostile".
Vue les fréquences maximales mises en jeux, vous pouvez fort
bien vous contenter d'une paire de transistors classiques (2N1711 +
2N2905) montés en push-pull.
Schéma 001d (code logiciel 001d, avec 16F628A)
Schéma légèrement modifié suite remplacement 16F84A par 16F628A (celui à base de 16F84 est
désormais déconseillé).
Rien de spécial à dire, c'est le schéma que je préconise désormais. Les modifications matérielles suivantes ont été apportées :
-
L'entrée se fait désormais sur la broche RB0 du PIC, les entrées de
sélection du taux de division on été décallées en conséquence.
- Le
changement du taux de division se fait désormais via la broche de reset
général.
Schéma 001e (code logiciel 001e, avec 16F628A)
Schéma 001d légèrement modifié pour utilisation du Timer1 en mode compteur, les interruptions sur RB0 ne sont plus utilisées.
Avec
la moitié inférieure de ce schéma 001e et le code 001e, la
fréquence d'entrée max peut désormais atteindre 150 kHz. Mais petit
inconvénient, la configuration des switches correspond à un taux de
division double. Par exemple en configurant les switches SW1 pour un
taux de division de 5, la fréquence du signal de sortie est 10
fois moindre que celle du signal d'entrée. Cela est lié au fait que le
Timer1 configuré en compteur ne peut s'incrémenter que sur des fronts
montants ou descendants, mais pas les deux. En préchargeant par exemple
la valeur 65530 dans le Timer1, le débordement à lieu après six
périodes complètes du signal entrant, et on a donc une division par 12
au lieu de 6. Une solution consiste à ajouter en amont du PIC, un
circuit détecteur de fronts qui délivre une brève impulsion positive à
chaque front montant ET desendant du signal entrant. C'est ce
circuit que l'on voit en haut du schéma, et qui ne comporte que de
classiques portes logiques TTL (ce bout de schéma peut bien sûr être
utilisé à d'autres sauces). En procédant ainsi, le taux de division
réel correspond bien à la valeur spécifiée par SW1. Pourquoi ne pas
avoir adopté le circuit - bien plus simple - du détecteur de fronts
composé d'une porte XOR et d'un circuit RC retardateur ? Tout
simplement pour que notre circuit puisse fonctionner sur une large
plage de fréquence.
Remarque
: si le facteur de division souhaité est toujours un multiple de 2,
point besoin de s'embêter avec ce complexe ajout, il suffit d'appliquer
le signal à diviser directement sur la broche RB6 (JP1 orienté vers
l'entrée In) !
Approches pour les différents programmes (16F84A ou 16F628A)
J'ai adopté deux approches (deux programmes différents)
pour la lecture du signal d'horloge appliqué sur l'entrée
RB7 :
Programme "diviseur_frequence_001a"
Approche avec interruptions pour le comptage des impulsions d'horloge :
le programme ne réagit que lors des changements d'état du
signal d'entrée, et le reste du temps il ne fait rien. Avec un
quartz 20 MHz, j'obtiens une division correcte jusqu'à 34 KHz en
entrée.
Programme "diviseur_frequence_001b"
Approche dans laquelle l'entrée d'horloge est continuellement
analysée, dans la routine principale du programme. Avec un
quartz 20
MHz, j'obtiens une division correcte jusqu'à 25 KHz en
entrée. C'est donc un peu moins "bon" et l'on
préfèrera sans doute la version avec interruptions.
Programme "diviseur_frequence_001c"
Même approche qu'avec le programme 001a, mais avec moins de code
dans la routine d'interruption, le plus gros étant
désormais déporté dans la procédure
principale. Merci à Pierre pour ses conseils utiles !
Programme "diviseur_frequence_001d"
Même code que le programme 001c, mais avec 16F628A, désormais moins
cher que le 16F84. La fréquence du signal d'entrée peut grimper un peu
plus haut (40 kHz au lieu de 30 kHz auparavant).
Programme "diviseur_frequence_001e"
Dans ce programme, on
utilise le Timer1 configuré en compteur avec entrée de comptage
externe. Cette méthode permet de faire grimper la fréquence
d'entrée max à une valeur de 150 kHz.
Comparaison avec des diviseurs spécialisés
Une fréquence d'entrée maximale de 150 kHz (ou pire encore
de 25 kHz) peut prêter à sourire, si on la compare aux
fréquences maximales tolérées par les circuits
spécialisés, qu'ils appartiennent à la
famille TTL ou CMOS. L'idée est ici de disposer d'un compteur
programmable simple à mettre en oeuvre, avec un seul composant.
Et le code que j'ai écrit, malgré son évidente
simplicité, n'est sans doute pas un exemple à suivre d'un
point de vue optimisation et compacité. Comme pour tout
programme, il y a bien souvent possibilité de faire mieux. Mais
à l'époque où j'ai développé les codes 001a à 001d, je débutais tout juste dans le monde des PICs, et il ne fallait pas
trop m'en demander ;-)
Edition 12/12/2010
: ça monte maintenant à 40 kHz avec le 16F628A (version 001d). Cool. A
la prochaine mise à jour, ça montera peut-être à 45 kHz ;-)
Edition 14/02/2016
: ça monte maintenant à 150 kHz avec le 16F628A (version 001e).
Le truc idiot qui m'a fait perdre une journée entière (c'était en 2010)
Quand j'ai entrepris ce montage, j'étais vraiment débutant dans la programmation des PIC. Je suis resté bloqué sur un
problème qui m'a pris une pleine journée et pour lequel
je ne m'en suis sorti qu'avec l'aide de personnes compétentes,
sur le forum de MikroPascal. L'ensemble tournait correctement me
semblait-il, mais version avec ou sans interruptions, le montage
bloquait après le premier changement d'état de la sortie
RA4, qui avait pourtant toujours lieu au bon moment, c'est à
dire une fois que le nombre de changements d'état logique de
l'entrée RB7 avait atteint la valeur du facteur de division
spécifé. Le changement d'état avait lieu, oui,
mais en même temps, il me semblait que la sortie RA4 restait dans
un état indéterminé, au lieu de passer franchement
à l'état logique haut. Cela aurait pû me mettre la
puce à l'oreille, mais j'étais tellement persuadé
que j'avais fait une erreur dans le logiciel, qu'il ne m'est pas venu
un seul instant à l'esprit, que le problème pouvait
être d'ordre matériel. Oui, j'avais lu le datasheet du PIC
16F84. Mais une information essentielle m'avait échappée :
"Pin RA4 is multiplexed with the
Timer0 module clock input to become the RA4/T0CKI pin. The RA4/T0CKI
pin is a Schmitt Trigger input and an open
drain output. All other RA port pins have TTL input levels and
full CMOS output drivers."
La sortie RA4, contrairement aux autres "sorties" du port RA, est de
type Drain ouvert et l'on doit donc impérativement y racorder
une résistance de rappel vers la borne positive de
l'alimentation. Il est fort probable que j'aurais rapidement
localisé l'erreur en allant consulter des schémas
existants sur le net. Mais je cherchais désespérement des
exemples
logiciels et non
des exemples
matériels !
Oh, je sais, j'en verrai d'autres du même genre...
Code source
L'archive zip suivante contient l'ensemble des fichiers sources et
compilés du programme du PIC (versions 001a, 001b, 001c pour 16F84A et 001d/001e pour 16F628A),
ainsi que
le fichier source de
Isis (Proteus).
Bien entendu, les codes sources ne vous seront utiles que si vous
disposez des logiciels aptes à les ouvrir (Proteus pour la
partie électronique et MikroPascal pour la partie logiciel). Si
vous ne disposez pas de ces logiciels, vous pouvez toujours utiliser
les fichiers compilés (format hex) pour programmer votre PIC.
Diviseur
fréquence 001 - (14/02/2016)
Si
vous souhaitez recevoir par la poste un PIC préprogrammé
et prêt à utiliser, merci de consulter la page
PIC - Sources.
Circuit imprimé
Non réalisé. La vue 3D n'est là que pour donner un aperçu des
composants utilisés.
Historique
14/02/2016
- Ajout version 001e qui permet de passer d'une fréquence d'entrée max de 40 kHz à une fréquence d'entrée max de 150 kHz.
12/12/2010
- Remplacement PIC 16F84A par un PIC 16F628A.
- Portage code logiciel sous MikroPascal Pro V3.80.
-
L'entrée se fait désormais sur la broche RB0 du PIC, les entrées de
sélection du taux de division on été décallées en conséquence.
- Le
changement du taux de division se fait désormais via la broche de reset
général. Cela permet de simplifier le code et de le faire tourner un
peu plus vite (25% plus rapide).
xx/01x/2010
- Première mise à disposition