Les compteurs servent à créer divers circuits fortement liés la gestion de la fréquence, ainsi qu'à la mesure du temps. L'idée derrière ces circuits est tout simplement de compter les cycles d'horloge. Vu qu'un compteur/décompteur est cadencé par le signal d'horloge, on peut l'incrémenter ou le décrémenter à chaque cycle d'horloge, ce qui lui fait compter les cycles d'horloge. Compter les cycles d'horloge a plusieurs utilités. On peut s'en servir pour mesurer des durées, ou pour diviser une fréquence. Dans ce qui va suivre, nous allosn voire deux types de circuits : les diviseurs de fréquence, et les "timers".
Les diviseurs de fréquence.
Les diviseurs de fréquence sont des circuits qui prennent en entrée un signal d'horloge et fournissent en sortie un autre signal d'horloge de fréquence plus faible. Plus précisément, la fréquence de sortie est 2, 3, 4, ou 18 fois plus faible que la fréquence d'entrée. La fréquence est donc divisée par un nombre N, qui dépend du diviseur de fréquence. Il existe des diviseurs de fréquence qui divisent la fréquence par 2, d'autres par 4, d'autres par 13, etc. On peut globalement les classer en deux types, dont la conception interne est légèrement différente : ceux qui divisent la fréquence d'entrée par une puissance de 2 (2, 4, 8, 16) et les autres.
Les diviseurs de fréquence par 2, 4, 8, ....
Pour commencer, nous allons voir le premier type de diviseur de fréquence : ceux qui divisent la fréquence d'entrée par une puissance de deux. Pour comprendre comment les fabriquer, nous allons étudier le cas le plus simple : celui qui divise par 2 la fréquence d'entrée. Et bien sachez qu'il s'agit d'une simple bascule T. En effet, regardons ce qui se passe quand on envoie un signal constamment à 1 sur son entrée T. Dans ce cas, la bascule s'inversera une fois par chaque cycle d'horloge. Un cycle d'horloge sur la sortie correspond au temps passé entre deux inversions.
Pour créer un diviseur de fréquence par 4, il suffit d'enchainer deux fois le circuit précédent. La sortie de la première bascule T doit être envoyée sur l'entrée T de la seconde bascule. Et pour créer un diviseur de fréquence par 8, il suffit d'enchainer trois fois le circuit précédent. Et ainsi de suite. Au final, un diviseur de fréquence qui divise la fréquence d'entrée par 2^N est un enchainement de N bascules T, qui n'est autre qu'un circuit incrémenteur. La sortie d'un tel diviseur de fréquence se situe en sortie de la dernière bascule.
On peut en profiter pour créer un circuit à plusieurs sorties, en mettant une sortie par bascule. Le circuit, illustré ci-dessous, fournit donc plusieurs fréquences de sortie : une à la moitié de la fréquence initiale, une autre au quart de la fréquence d'entrée, une autre au huitième, etc.
Les autres diviseurs de fréquence.
Nous venons de voir qu'un simple incrémenteur se comporte comme un diviseur de fréquence. Dans le chapitre précédent, nous avions vu un type d’incrémenter particulier : l'incrémenteur modulo, qui est remis à zéro quand il atteint une valeur limite et recommence à compter à partir de 0. Un tel incrémenteur se comporte comme un diviseur de fréquence un peu particulier.
Prenons un compteur modulo 6, par exemple, ce qui veut dire qu'il compte de 0 à 5, et est remis immédiatement à zéro quand il dépasse 5. Il compte donc comme suit : 0, 1, 2, 3, 4, 5, 0, 1, 2, ... Un tel circuit est composé d'un incrémenteur simple, auquel on ajoute un petit circuit comparateur qui vérifie si le contenu du compteur est égal à la valeur limite, ici égale à 6. La sortie de ce circuit se comporte comme un diviseur de fréquence par 6. Et on peut généraliser : la sortie d'un compteur par N se comporte comme un diviseur de fréquence par N.
Une autre manière de créer le diviseur de fréquence précédent est la suivante. L'idée est de prendre la sortie d'un diviseur de fréquence par 3 et de diviser par deux sa fréquence de sortie avec une bascule T. Le circuit est légèrement plus rapide, car les premières bascules sont traitées en premier.
Pour résumer, un diviseur de fréquence par N s'implémente avec un compteur modulo N. Le compteur compte pendant N cycles, puis est remis à zéro. La remise à 0 prévient quand il faut inverser la sortie.
Les "timers".
Les timers, aussi appelés "Programmable interval timer", sont des circuits capables de compter des durées. Leur fonctionnement est assez simple : on leur envoie un certain nombre de cycles d'horloge en entrée, et ils émettent un signal quand ce nombre de cycles est écoulé. Le signal en question est disponible sur une sortie de 1 bit, et correspond tout simplement au fait que cette sortie est mise à 1, pendant un cycle d'horloge. Ils permettent de compter des durées, exprimées en cycles d'horloge. On peut aussi générer un signal qui surviendra après 50 cycles d'horloge, ou après 100 cycles d'horloge, etc.
Les "timers" sont composés d'un compteur/décompteur cadencé par un signal d'horloge. Le compteur initialisé à 0, puis est incrémenté à chaque signal d'horloge, jusqu’à atteinte d'une valeur limite où il génère un signal. Pour un décompteur, c'est la même chose, sauf que le décompteur est initialisé à sa valeur limite et est décrémenté à chaque cycle, et envoie un signal quand il atteint 0. Les "timers" basés sur des décompteurs sont nettement plus simples que les autres, ce qui fait qu'ils sont plus utilisés. Pour que les "timers" soient configurables, on doit pouvoir préciser combien de cycles il faut (dé-)compter avant d'émettre un signal. On peut ainsi préciser s'il faut émettre le signal après 32 cycles d'horloge, après les 50 cycles, tous les 129 cycles, etc. Pour cela, il suffit de préciser le nombre de cycles à compter/décompter en entrée et d'initialiser le compteur/décompteur avec. 
Les "timers" matériels peuvent compter de deux manières différentes, appelées mode une fois et mode périodique. Concrètement, le mode périodique divise la fréquence d'entrée, alors que le mode une fois compte durant une durée fixe avant de s'arrêter.
Un ordinateur est rempli de "timers" divers. Dans ce qui va suivre, nous allons voir les principaux "timers", qui sont actuellement intégrés dans les PC modernes. Ils se trouvent sur la carte mère ou dans le processeur, tout dépend du "timer".
Le "watchdog timer".
Le watchdog timer est un "timer" spécifique dont le but est d'éteindre ou de redémarrer automatiquement l'ordinateur si jamais celui-ci ne répond plus ou plante. Tous les ordinateurs n'ont pas ce genre de "timer", et beaucoup de PC s'en passent. Mais ce "timer" est très fréquent dans les architectures embarquées. Le "watchdog timer" est un compteur:décompteur) qui doit être réinitialisé régulièrement. S'il n'est pas réinitialisé, le "watchdog timer" déborde (revient à 0 ou atteint 0) et envoie un signal qui redémarre le système. le système est conçu pour réinitialiser le "watchdog timer" régulièrement, ce qui signifie que le système n'est pas censé redémarrer. Si jamais le système dysfonctionne gravement, le système ne pourra pas réinitialiser le "watchdog timer" et le système est redémarré automatiquement ou mis en arrêt.
Le "Time Stamp Counter" des processeurs x86.
Tous les processeurs des PC actuels sont des processeurs dits x86. Nous ne pouvons pas expliquer ce que cela signifie pour le moment, retenez juste ce terme. Sachez que tous les processeurs x86 contiennent un compteur de 64 bits, appelé le Time Stamp Counter, qui mémorise le nombre de cycles d'horloge qu'a effectué le processeur depuis son démarrage. Les programmes peuvent accéder à ce registre assez facilement, ce qui est utile pour faire des mesures ou comparer les performances de deux applications. Il permet de compter combien de cycles d'horloge met un morceau de code à s’exécuter, combien de cycles prend une instruction à s’exécuter, etc. Les processeurs non-x86 ont un registre équivalent, que ce soit les processeurs ARM ou d'autres.
Malheureusement, ce compteur est tombé en désuétude pour tout un tas de raisons. La principale est que les processeurs actuels ont une fréquence variable. Nous expliquerons cela plus en détail dans quelques chapitres, mais les processeurs actuels font varier leur fréquence suivant les besoins. Ils augmentent leur fréquence quand on leur demande de faire beaucoup de calculs, et se mettent en mode basse(fréquence pour économiser de l'énergie si on ne leur demande pas grand chose. Avec une fréquence variable, le "Time Stamp Counter" perd complétement en fiabilité. Intel a tenté de corriger ce défaut en incrémentant ce registre à une fréquence constante, différente de celle du processeur, ce qui est encore le cas sur les processeurs Intel actuels. Le comportement est un peu différent sur les processeurs AMD, mais il compte par cycle d'horloge, avec des mécanismes de synchronisation assez complexes pour corriger l'effet de la fréquence variable.
L'horloge temps réel.
L'horloge temps réel est un "timer" qui génère une fréquence de 1024 Hz, soit près d'un Kilohertz. Dans ce qui suit, nous la noterons RTC, ce qui est l'acronyme du terme anglais "Real Time Clock". La RTC prend en entrée un signal d'horloge de 32KHz, généré par un oscillateur à Quartz, et fournit en sortie un signal de fréquence 32 fois plus faible, c'est à dire de 1 KHz. Pour cela, elle est réglée en mode répétitif et son décompteur interne est initialisé à 32. La RTC génère donc un signal toutes les millisecondes, qui est envoyé au processeur. On peut, en théorie, changer la fréquence de la RTC, mais c'est rarement une bonne idée.
En théorie, la RTC permet de compter des durées assez courtes, comme le "ping" (le temps de latence d'un réseau, pour simplifier), le temps de rafraichissement de l'écran, ou bien d'autres choses. Mais dans les faits, les systèmes d'exploitation modernes ne l'utilisent pas pour ça. L'horloge temps réel est trop imprécise et sa fréquence n'aide pas. En effet, 1024 Hz est proche de 1000, mais pas assez pour faire des mesures à la missliseconde près, chose qui est nécessaire pour mesurer le "ping" ou d'autres choses utiles.
A la place, l'ordinateur l'utiliser pour compter les secondes, afin que l'ordinateur soit toujours à l'heure. Vous savez déjà que l'ordinateur sait quelle heure il est (vous pouvez regarder le bureau de Windows dans le coin inférieur droite de votre écran pour vous en convaincre) et il peut le faire avec une précision de l'ordre de la seconde. Mais pour savoir quel jour, heure, minute et seconde il est, l'ordinateur doit faire deux choses : mémoriser la date exacte à la seconde près, et avoir la capacité de compter le temps qui s'écoule, seconde par seconde. Pour cela, un ordinateur contient une CMOS RAM qui mémorise la date, et la RTC.
Le "Programmable Interval Timer" : l'Intel 8253.
L'Intel 8253 est un "timer" programmable qui était autrefois intégré dans les cartes mères des ordinateurs personnels de type PC. Les premiers processeurs x86 étaient souvent secondés avec un Intel 8253 soudé à la carte mère. Il fût suivi par l'Intel 8254, qui en était une légère amélioration. S'il n'est plus présent dans un boitier de la carte mère, on trouve toujours un circuit semblable au 8253 à l'intérieur du "chipset" de la carte mère, voire à l'intérieur du processeur, pour des raisons de compatibilité. Sur les PC, il est cadencé par une horloge maitre, générée par un oscillateur à Quartz, dont la fréquence est de 32 768 Hertz, soit 2^15 cycles d'horloge par seconde. La fréquence générée par un compteur va donc de 18,2 Hz à environ 500 KHz. Il était utilisé pour dériver un grand nombre de fréquences utilisées dans l'ordinateur. Par exemple, le second compteur était utilisé par défaut pour le rafraichissement de la mémoire (D)RAM, mais il était souvent reprogrammé pour servir à générer des fréquences spécifiques par le BIOS ou la carte graphique.
L'intérieur de l'Intel 8253 est illustré ci-dessous. Nous allons expliquer l'ensemble de ce schéma, rassurez-vous, mais les explications seront plus simples à comprendre si vous survolez ce schéma en premier lieu.
L'Intel 8253 contient trois compteurs de 16 bits, numérotés de 0 à 2. Chaque compteur possède deux entrées et une sortie : l'entrée CLOCK est celle de l'horloge de 32 MHz, l'entrée GATE active ou désactive le compteur, la sortie fournit le signal voulu et/ou la fréquence de sortie.
L'Intel 8253 lui-même possède plusieurs entrées et sorties. En premier lieu, on voit un port de 8 bits connecté aux trois compteurs, qui permet à l'Intel 8253 de communiquer avec le reste de l'ordinateur. La communication se fait dans les deux sens : soit de l'ordinateur vers les compteurs, soit des compteurs vers l'ordinateur. Dans le sens ordinateur -> compteurs, cela permet à l'ordinateur de programmer les compteurs, de les initialiser. Dans l'autre sens, cela permet de récupérer le contenu des compteurs, même si ce n'est pas très utilisé.
Ensuite, on trouve un registre de 8 bits, le "Control Word register" qui mémorise la configuration de l'Intel 8253. Le contenu de ce registre détermine le mode de fonctionnement du compteur, de combien doit compter le compteur et bien d'autres choses. Pour programmer les trois compteurs, il faut écrire un mot de 8 bits dans le "Control Word register". La configuration de l'Intel 8253 fournie en sur le port de 8 bits pendant un cycle d'horloge, puis est mémorisée dans ce registre et reste pour les cycles suivants.
Mais l'écriture a lieu à condition que les 5 entrées de configuration soit bien réglées. Les 5 entrées de configuration sont les suivantes :
Pour écrire dans le "Control Word register", il faut mettre le bit CS à 0 (on active l'Intel 8253), mettre à 1 le bit RD et à 0 le bit WR (on indique qu'on fait une écriture), et sélectionner le "Control Word register" en mettant les deux bits A0 et A1 à 1. Pour écrire dans un compteur, il faut faire la même chose, sauf que les bits A0 et A1 doivent être configurés de manière à donner le numéro du compteur voulu. LA lecture s'effectue elle aussi de la même manière, mais il faut inverser les bits RD et WR.
Le "High Precision Event Timer" (HPET).
De nos jours, l'horloge temps réel et l'Intel 8253/8254 tendent à être remplacé par un autre "timer", le "High Precision Event Timer" (HPET). Il s'agit d'un compteur de 64 bits, dont la fréquence est d'au moins 10 MHz. Il s'agit bien d'un compteur et non d'un décompteur. Il est couplé à plusieurs comparateurs, qui vérifient chacun une valeur limite, une valeur à laquelle générer un signal. La valeur limite peut être programmée, ce qui fait que chaque comparateur est associé à un registre pour mémoriser la valeur limite. Il doit y avoir au moins trois comparateurs, mais le nombre peut monter jusqu’à 256. Chaque comparateur doit pouvoir fonctionner en mode une fois, et au moins un comparateur doit pouvoir fonctionner en mode périodique.
Il faut noter que les systèmes d'exploitation conçus avant le HPET ne peuvent pas l'utiliser, pour des raisons techniques de compatibilité matérielle. C'est le cas de Windows XP avant le Service Pack 3. C'est la raison pour laquelle les cartes mères possèdent encore un PIT et une RTC, ou au moins qu'elles émulent RTC et PIT dans leurs circuits. D'ailleurs, pour économiser des circuits, les cartes mères modernes émulent le PIT et la RTC avec le HPET. Le HPET est configuré de manière à ce que le premier comparateur fournisse une fréquence de 1024 Hz, comme la RTC, et les 3 comparateurs suivants remplacent l'Intel 8253.
Le HPET gère de nombreux modes de fonctionnement : ses comparateurs peuvent être configuré en mode une fois ou périodique, on peut lui demander d'émuler la RTC et le PIT, etc. Aussi, il contient aussi de nombreux registres de configuration. En tout, on trouve 3 registres de configuration. à Cela, il faut ajouter trois registres pour configurer chaque comparateur indépendamment les uns des autres. Notons qu'il est aussi possible de lire ou écrire dans le compteur de 64 bits, mais ce n'est pas recommandé.