
Montage sur MSP430F449
Présentation
J'ai plein d'horloges et de montres mécaniques, électriques ou électroniques mais je ne suis jamais sûr qu'elles soient à l'heure. Il me fallait donc une petite horloge de confiance. Et je voulais qu'elle fonctionne sur piles sans avoir à les changer trop souvent. Et puis, ça m'amusait...
Donc voici la présentation de deux horloges synchronisées sur le signal DCF77 ainsi que leurs programmes dont l'un tourne sur un processeur Texas Instrument (TI) MSP430F449 qui comme toute la série des processeurs MSP430, est réputé pour sa très faible consommation tout en étant capable de gérer en permanence un afficheur LCD et l'autre tourne sur un processeur STM32L476 d'une génération beaucoup plus récente que le MSP430 utilisé. Comme je suis masochiste, j'ai aussi fait le développement pour le STM32L152.
Le gros avantage de cette horloge par rapport à un smartphone : pas besoin de la recharger tous les jours. Normalement, un changement de pile toutes les X années suffit (X de l'ordre de 5 à 7 ans).
Pour ceux qui ont parcouru ce site, vous avez pu voir tout une série de compteurs Geiger-M uller de ma conception qui utilisent le processeur MSP430 et dont la consommation moyenne est de l'ordre de 20 à 60µA selon les versions.
Pour terminer cette introduction, vous trouverez pléthore d'horloges synchronisées sur le signal DCF77 à des prix très raisonnables (une vingtaine d'euro ou moins) et qui font beaucoup plus de chose que celle présentée ici. Cette horloge n'a ni réveil matin, ni réglage de l'heure (elle ne fonctionne donc que dans certains pays d'Europe) et n'a aucune autre prétention que de permettre d'expérimenter et d'avoir la satisfaction de l'avoir faite soit même.
Et vous trouverez également, outre les programmes sources, quelques réflexions sur la façon de traiter le signal DCF77 et aussi, quelques commentaires sur le MSP430F449 et les STM32L476/STM32L152. Ceux qui envisagent de développer sur ces processeurs pourront ainsi se faire une idée de ce qui les attend. Pour information, j'ai porté la version MSP430 sur STM32L4 car je voulais me familiariser avec ce dernier sachant que j'avais déjà de l'expérience sur STM32, mais les versions F (STM32F407. Voir par exemple la réalisation d'un chronocomparateur très performant). Quant au STM32L152 (obsolète), c'est parce que j'en avais un et que j'ai cru un moment avoir détruit ma carte STM32L4 (mais non, c'est solide ces petites bêtes).
Spécifications
Les spécifications sont les suivantes :
- Affichage permanent de l'heure sur 24 heures (heures, minutes, secondes) avec une précision raisonnable.
- Affichage de la date (année, mois, jour).
- Mise à jour de ces données à partir du signal DCF77 (une fois par jour).
- Consommation faible autorisant plusieurs années de fonctionnement sur piles.
- Indicateurs divers dont le fait que l'horloge a pu se mettre à jour ou pas depuis les dernières 24H00.
L'afficheur est le seul interface disponible (avec éventuellement, les boutons poussoirs)

Affichage de l’heure
Entre deux mise à l’heure à partir du signal DCF77, l’horloge fonctionne « en roue libre » sur sa propre base de temps interne.
Elle resynchronise sa base de temps interne et se remet à l’heure lorsqu’un signal DCF77 correct est reçu.
Affichage de la date
L’affichage de la date se fait sur l’afficheur en haut à gauche. Il affiche alternativement (chaque seconde) l’année (exemple : 2023) ou le jour et le mois (exemple : 23:08 pour le 23 août).
Cette date se resynchronise tous les jours (ou à la demande) lorsqu’un signal DCF77 correct est reçu.
Indicateurs
4 indicateurs sont présents sur l’afficheur :
- La charge des piles « Bat » (mise à jour tous les 24 heures). Il y a trois barres (4 = charge maximum, 0 = charge faible). À partir de 1 barre, il faut penser à changer les piles.
- L’indicateur clignotant « DCF77 » (une clé) indique que l’horloge n’a pas pu se mettre automatiquement à l’heure depuis plus de 24H00.
- L’indicateur « Ant » indique que l’horloge tente de recevoir un signal DCF77.
- L’indicateur « signal » (1 à 3 barres) indique que l’horloge reçoit un signal DCF77.
Matériel
Version MSP430
Le processeur utilisé est ici un MSP430 disponible sur un petit circuit de développement conçu par Olimex. Il dispose d'un afficheur (que j'avais cassé il y a plusieurs années. Je l'ai remplacé par un autre modèle d'où les fils un peu partout pour relier l'afficheur à la carte de développement), 4 boutons poussoirs et d'autres bricoles que j'ai viré (prise V24, buzzer...).

MSP430-449STK2
Version STM32L476
Le processeur utilisé est ici un STM32L476 disponible sur un petit circuit de développement chinois qui se veut minimum. Il ne comporte que le processeur, ses quartz, 2 LED (dont une qu'il faut supprimer en régime permanent), un régulateur 5V vers 3,3V si la carte est alimentée via l'USB (il s'agirait d'un LDO ME6211C33M5G) et le même afficheur que sur la version MSP430. En fait, j'ai démonté la version MSP430 pour faire la version STM32L4.

Cette carte a l'avantage d'être très petite, de donner accès à quasiment toutes les pins du processeur (avec une bizarrerie que je n'ai pas chercher à élucider, cf. le GPIO D1 qui n'est pas dans la spécification). Par ailleurs, pour éviter tout problème en alimentation sur pile, j'ai retiré le régulateur de l'USB.
Version STM32L152
Le processeur utilisé est ici un STM32L152 en 100 broches disponible sur un petit circuit de développement Olimex. Il comporte le processeur, ses quartz, 2 LED, une alimentation avec chargeur de batterie LIPO, un régulateur 5V vers 3,3V si la carte est alimentée via l'USB ou une batterie. J'ai utilisé le même afficheur que sur la version MSP430.
Sur l'environnement du processeur (alimentation, horloges, etc.), la carte n'est pas mal faite. Par contre, comme une autre carte Olimex que j'ai utilisé dans le passé, l'affectation des pins du processeur est stupide, surtout si l'on considère qu'on achète ce genre de processeur pour sa capacité à gérer des LCD à segments. En résumé, plusieurs pins de gestion des segments (dans les numéros bas) sont préaffectées d'office à d'autres fonctions ce qui limite les possibilités de géstion ou complique énormément la programmation. De plus, la documentation comporte plusieurs erreurs. Bref, je ne recommande pas cette cartes dont le processeur est de toute façon obsolète. Mais de manière générale, analysez bien le schéma des cartes que vous achetez chez ce fournisseur avant de prendre une décision et pour faire simple, orientez vous plutôt sur des cartes du fabricant du STM32.
Module DCF77
Pour le module DCF77, j’en ai pris un tout fait sur Aliexpress (environ 3€ port compris en 2023). Il est donné pour avoir une consommation maximum de 85µA ce qui est assez élevé. Mais en mode « désactivé », sa consommation est imperceptible.

Module RCC02C03A
Pour ceux qui auraient du mal à trouver la spécification, voici quelques indications utiles :
- L'interface comporte 4 fils. Sur la photo, Vdd est à droite. En partant de Vdd et en allant vers la gauche, on a donc :
- Vdd = (+) de la tension d'alimentation
- Vss ou Ground = 0V de la tension alimentation
- P ou P1 (entrée) = activation (signal = 0V) ou désactivation (signal = Vdd) du module.
- T (sortie) = signal démodulé.
- Tension d'alimentation = 1,1 à 3,3V
- Consommation maximum = 85µA
Réalisation
Ci-après, la réalisation matérielle (avec l'afficheur qui n'est pas d'origine !). On y trouve la connexion du module DCF77 sur un connecteur de la carte de développement avec son alimentation, le signal d'activation (port GPIO P2.1 sur MSP430 GPIOB 2 sur le STM32) et le signal démodulé (sur le port GPIO P2.0 sur MSP430, GPIOA 4 sur STM32). L'autre connexion est celle du porte pile qui fournit l'alimentation de 3V.

Version avec MSP430
Voici l'affectation des pins pour la version STM32L4 :
On peut mettre tout ça dans un petit boitier imprimé en 3D, ici, en ASA (sans le capot qui ferme le tout) pour la version MSP430.
Boitier qui présente une légère rétractation des bords, problème malheureusement courant avec le ASA.
Logiciel
La partie la plus complexe mais la plus intéressante concerne le logiciel. Celui-ci est téléchargeable pour la version STM32 au cas (improbable) où quelqu'un voudrait réaliser cette horloge ou au cas (plus probable) où quelqu'un voudrait des tuyaux sur la programmation du STM32L4.
La partie concernant l'affichage de l'heure, de la date et des indicateurs n'appelle pas d'attention particulière et je ne la détaillerai pas.
La partie réellement intéressante concerne le décodage du signal DCF77 et la gestion de la basse consommation. C'est ce qui est expliqué ci-après.
Réception du signal DCF77
La réception du signal se fait donc via un module spécialisé qui peut être activé ou non. Il n’est activé que lorsque l’horloge le demande (lors d’une mise à l’heure automatique à 00:00:00). Si au bout de 10mn, l’horloge n’a pas reçu de trame correcte, le module DCF77 est désactivé et l’horloge continue de fonctionner en roue libre. Un indicateur permet de savoir si la dernière tentative de réception à 00:00:00 a fonctionné ou pas.
Rappel sur le signal DCF77
On trouve une spécification du signal DCF77 sur le site Wikipedia. Les explications qui suivent résument les points importants de cette spécification.
Le signal DCF77 est constitué d’une porteuse à 77,5kHZ. La modulation de cette porteuse code l’information à transmettre (un bit) sous forme temporelle.
Cette modulation se retrouve sur une sortie du module spécialisée sous la forme d’un 0 (tension nulle) ou d’un 1 (tension d’alimentation du module).
- La durée d’un 0 est de 100ms
- La durée d’un 1 est de 200ms
- La durée totale de la transmission d’un bit est de 1000ms (1 seconde).
On retiendra que si on reçoit un signal à 1 pendant plus de 200ms ou si l'on reçoit un signal à 0 pendant plus de 1900ms, on a soit un gros problème de réception, soit un module en panne.
Donc, chaque seconde, on doit recevoir un signal à 1 (dont la durée donne la valeur du bit), puis après 100ms (respectivement 200ms), un signal à 0 pendant 900ms (respectivement 800ms), puis de nouveau, un signal à 1, etc.
On appelle « trame » l'ensemble des bits du signal horaire émis périodiquement.
La trame comporte 59 bits utiles véhiculés à raison d'un bit par seconde (donc 59 secondes). La 60ème seconde sert à la synchronisation et vaut 0 pendant une seconde (pas de modulation). Elle marque la fin de la trame courante et le premier front montant qui suit détermine le début de la trame suivante. Il détermine également le moment où les signaux reçus de la trame précédente peuvent être utilisés.
Dit autrement, l’heure reçue dans une trame est valide lorsqu’on reçoit le début de la trame suivante. En supposant que l'heure reçue soit 09:56, le front montant du début de la trame suivante (qui code 09:57) permettra de mettre une horloge à l'heure avec l'heure (09:56:00. Il y a un cas particulier, voir la spécification sur Wikipédia)
La durée du signal de synchronisation permet de faire sans difficulté le décodage des informations reçues afin d’être prêt à les utiliser lors de l’apparition de la trame suivante. Pour la signification des bits reçus, voir sur Wikipedia.
Stratégie de synchronisation (début d'une trame)
On attend un signal à 0 dont la durée est supérieure à 1700ms. Lorsqu’on le trouve, le front montant suivant (signal à 1) marque le début d’une nouvelle trame et on a réussi à se synchroniser. On notera que dans le cas d’une réception correcte, il faut parfois attendre une minute avant de recevoir le signal de synchronisation.
Cette recherche peut se faire par test d'état (déconseillé) ou en utilisant des interruptions sur fronts montants et descendants. Un front descendant déclenche une mesure de durée que l'on arrête sur le prochain front montant. Si cette durée est entre 1800ms et 1900ms, on a trouvé le début d'une trame.
Sauf que si l'on procède ainsi, ça ne fonctionne pas bien parce que le signal est très sensible au bruit et qu'il y a souvent des impulsions parasites.
Il faut donc filtrer ces parasites ce qui implique de mesurer la durée entre chaque front (front montant ou front descendant) pour savoir si l’on doit prendre en compte le signal ou pas. Mais on se heurte à un autre problème qui est de savoir si l’impulsion parasite était en fait le début d’un signal valide ou pas. On doit donc aussi mesurer la temps dans le signal auquel s’est produite cette impulsion pour lever le doute.
On a bien sûr le même problème pour la détection des signaux codant les bits. Mais en supposant que l'on a trouvé le début d'une trame, on peut procéder plus simplement que pour le signal de synchronisation.
Stratégies de traitement du signal
J'ai envisagé deux stratégies pour le traitement du signal. On fait l'hypothèse que l'on est en mesure de détecter le signal de synchronisation :
- La première consiste à échantillonner chaque seconde le signal entre 100ms et 200ms. Si l'on détecte un 1, on a alors un bit à 1. Si on détecte un 0, on a un bit à 0. Cela suppose de disposer d'une horloge de réception stable afin d'échantillonner le signal au bon moment.
- La seconde consiste à mesurer la durée des signaux à 1 entre deux fronts montants et descendant. Si on obtient 100ms, on a un zéro. Si on obtient 200ms, on a un 1.
La première stratégie impose que les horloges du récepteur soient très stable (par hypothèse, celle de l'émetteur l'est). Ayant eu quelques problèmes de dérive (sur un simulateur de DCF77 basique que j'ai réalisé sur un Arduino), il faut prévoir un recalage périodique des horloges ce qui implique de détecter les fronts du signal. Or le signal est souvent très bruité ce qui implique de réaliser aussi un filtrage efficace durant toute la durée de la réception. C'est assez complexe mais c'est faisable.
Si l'on exclut la phase de synchronisation, la seconde stratégie est immunisée contre les parasites et contre les dérives d'horloge mais cela nécessite une petite explication.
Dans le signal modulé, on part du principe qu'il ne peut pas y avoir de parasite visible. En effet, le signal étant modulé à 100%, un parasite va ajouter de l'énergie à la modulation qui en pratique sera écrêtée par le récepteur. Donc, pour les signaux modulés à 100%, on peut admettre qu'il n'y a pas de parasite visible après la démodulation.
Les seuls parasites détectables correspondent donc aux signaux courts qui passent de 1 à 0 puis de 0 à 1 en l'absence de modulation. Si la durée de ces signaux est toujours inférieure à 100ms, ils ne seront pas pris en compte par le programme. S'ils sont supérieurs à 100ms, cela veut dire que le signal est trop bruité pour qu'on puisse envisager un décodage et mieux vaut abandonner ou attendre un moment où les parasites sont moins importants.
La première stratégie est complexe à implémenter mais elle fonctionne (c'est la première que j'ai réalisé). La seconde est triviale et simple à implémenter... Sauf qu'il reste à détecter la synchronisation.
Implémentation de la première stratégie
J'ai adopté une programmation sous forme d'automates d'états finis dont le fonctionnement général est le suivant :
- Un premier état attend un front descendant. Lorsqu'il le trouve, il initialise quelques variables puis l'automate se met en attente d'un front montant.
- La transition qui prend en compte ce front montant calcule la durée entre ce front et le dernier front descendant. Si cette durée est inférieure à celle définie pour un parasite (par exemple, 80ms), le signal est éliminé et le programme se met en attente d'un front bas pour revenir à l'état antérieur.
Si la durée est supérieure à celle d'un parasite, le signal est accepté et on considère arbitrairement que le front bas précédent correspond à un signal valide. - L'automate bascule ensuite en permanence entre front haut et front bas, éliminant les signaux parasites et attendant de trouver un signal bas dont la durée est supérieure à 1700ms.
- Lorsqu'il a trouvé le signal de synchronisation, un autre automate se déroule en parallèle pour faire l'échantillonnage du signal (entre 130ms et 170ms) après chaque arrivée d'un nouveau bit (un toute les secondes).
- L'automate qui élimine les parasites et recherche le signal de synchronisation reste actif. S'il détecte un nouveau signal de synchronisation, il redémarre complètement la mesure. Sinon, il continue de détecter les fronts afin de pouvoir recaler l'horloge de mesure du temps des signaux afin que l'automate échantillone le signal au bon moment.
c'est une partie un peu délicate car il y a toujours le risque qu'en faisant un recalage, on se désynchronise si le signal est trop bruité. Néanmoins, ayant eu quelques problèmes de décalage durant les tests, j'ai introduit et conservé ce recalage.
L'échantillonnage fait par le second automate fonctionne de la façon suivante :
- On échantillonne le signal présent entre 100ms et 200ms. S’il est présent, on a un 1, sinon, un 0.
- Idéalement, il faudrait pouvoir détecter le front montant de chaque nouveau signal codant un bit afin d'être certain d'échantillonner au bon endroit dans le signal. Mais on se retrouve avec le problème d'éliminer les signaux parasites comme dans le cas du signal de synchronisation.
- Une autre solution consiste à disposer d'une horloge suffisamment stable et précise sur 60 secondes que l'on déclenche au début du signal de synchronisation. Puis toutes les 1000ms, on passe à l'échantillonnage du bit suivant.
C'est l'approche adoptée dans la présente stratégie avec un échantillonnage toute les millisecondes. Elle est très similaire à celle d’une classique réception asynchrone aux parasites près.
Voici une capture de mesure à l'oscilloscope pour illustrer le fonctionnement de l'automate. En jaune, le signal DCF77 capturé, en bleu, un signal émis par le programme qui implémente cette stratégie. Chaque pic indique la détection d'un parasite.
Petit test de culture réseau : indiquez le débit en baud et le débit en bits par seconde (bps) de la communication (si vous regardez les définitions que l'on trouve de bauds et bps sur le net, vous avez toutes les chances de donner une réponse fausse).
Implémentation de la seconde stratégie
Il n'y a rien de plus à dire que ce qui a été exposé dans la présentation générale : on compte le nombre de signaux modulés d'une durée de 100 ou 200ms (à disons, 10ms près) sans se préoccuper de garder une synchronisation localement.
Voici une capture de mesure à l'oscilloscope pour illustrer le fonctionnement de cette stratégie. En jaune, le signal DCF77 capturé, en bleu, un signal émis par le programme qui implémente cette stratégie. Chaque pic indique la détection d'un signal utile (0 ou 1). Les parasites sont complètement ignorés. Tant que la durée d'un parasite est inférieure à 90ms, le programme détecte les signaux à 1 ou à 0 sans avoir besoin de maintenir une synchronisation complexe sur le signal. La beauté de la chose est que le programme est d'une grande simplicité et tient en quelques lignes de code. Etant donné la date ancienne de la conception du DCF77 et les moyens de l'époque, il est possible que les concepteurs aient conçu le signal pour ce type de stratégie.
Synchronisation
Quel que soit la stratégie adoptée, il faut néanmoins détecter le signal de synchronisation. Si on veut le faire de façon efficace, il faut alors éliminer le bruit. Là encore, on peut procéder de plusieurs façon :
- Si on ne détecte aucun signal entre 100 et 200 ms pendant environ 1700ms, alors, on a détecté le signal de synchronisation et on peut commencer à compter les signaux modulés d'une durée de 100 ou 200ms.
- On créé un automate pour éliminer les parasites. Si on a une durée d'au moins 1700ms entre un front bas et un front haut une fois les parasites éliminés, alors on a trouvé la synchronisation et on peut commencer à faire le traitement du signal.
La seconde approche, plus complexe, présente néanmoins un intérêt : elle permet de déterminer de façon assez sûre le début (et la fin) de la période de mesure. Or, la mise à l'heure de l'horloge sur la base du signal reçu ne doit se faire qu'au début de la trame suivante ce qui implique de la détecter de façon précise.
Néanmoins, la première approche fonctionne aussi très bien : lorsqu'on détecte le dernier signal de la trame (le 58ème), on conserve le début du front montant de ce signal dans un coin, on détecte pour la beauté de la chose qu'on a bien une synchronisation qui suit, et on peut calculer à quelques millisecondes près le moment où l'on fait la mise à l'heure de l'horloge.
Le logiciel implémente les deux approches (voir le define STRATEGIE1. Si présent, l'implémentation est celle de la première stratégie. Si absent, il s'agit de la seconde stratégie).
Stratégie 1 ou stratégie 2 ?
La stratégie 2 est très efficace et bénéficie d'un code extrêmement compact. C'est donc celle que j'ai retenue pour la version que j'utilise. La stratégie 1 avec ses deux automates imbriqués est intellectuellement assez belle mais elle s'avère au final un peu moins efficace et de toute façon, ce n'est probablement pas l'approche qui a été pensée lors de la conception du DCF77 car elle aurait été difficilement implémentable à l'époque (ou du moins, coûteuse à implémenter).
Décodage
Le décodage consiste à interpréter les bits reçus. Certains contrôles (parité, cohérence) permettent de valider que la trame est correcte ou pas (note : la numérotation des bits de la trame commence à 0).
Parité : elle concerne les minutes, les heures, la date.
Valeurs fixes : elles concernent le bit 0 (toujours à 0) et le bit 20 (toujours à 1).
Cohérence : certaines valeurs doivent se trouver dans des limites connues (heures, minutes, secondes, dates, jour de la semaine).
Qualité du signal
La réception du signal DCF77 peut être assez problématique. Surtout que les environnements actuels sont très bruités du fait des alimentations à découpage présentes dans de nombreux appareils ou des éclairages à LED. La simple proximité d'un appareil d'éclairage allumé peut empêcher toute réception.
Selon les fréquences et la modulation utilisée, la réception peut être meilleure à certaines heures, en particulier, la nuit.
L’afficheur indique la qualité du signal reçu en affichant de 0 à 3 barres à côté de l’antenne. L’algorithme est le suivant :
- 0 barres : on n’a pas reçu de signal depuis 3 secondes.
- 3 barres : on reçoit le signal et il n’y a pas d’impulsions parasites.
- 2 barres : on reçoit le signal et il y a 3 impulsions parasites au plus par seconde.
- 1 barre : on reçoit le signal et il y a plus de 3 impulsions parasites par seconde.
Sauf lorsqu’il n’y a pas de réception du tout (0 barre), la modification du nombre de barres est mise à jour toutes les secondes.
Une impulsion est définie ici comme parasite si sa durée est inférieure ou égale à 80ms.
Stratégie pour une basse consommation
MSP430
4 mode de basse consommation sont disponibles. LPM4 est exclu d’office dans la mesure où il désactive toutes les horloges et attend un événement externe pour réveiller le processeur. Reste donc LPM0 à LPM3.
Pour une basse consommation, on doit viser une utilisation maximale de LPM3.
En roue libre, le programme est réveillé par le Watchdog (WDT) toutes les secondes pour mettre l’heure et la date à jour.
WDT peut être piloté par un oscillateur interne au processeur (moyennement précis) ou par un quartz sur XT1 (très précis).
Consommation :
- En recherche de signal : 400µA (100µA avec STM32L4)
- En roue libre (uniquement l'affichage de l'heure) : 40µA avec oscillateur interne (peu précis), 45µA avec le quartz XT1 de 32768Hz (17µA pour STM32L4).
Note 2026 : les moyens de mesure que j'ai utilisé à l'époque ont probablement très surestimé la consommation en roue libre. Mon avis est qu'on doit plutôt être aux alentours de 20µA mais en 2026, je n'avais plus ce montage pour faire de nouvelles mesures.
Du fait de la faible différence entre les deux modes, l’implémentation utilisant XT1 a été retenue moyennant une consommation moyenne supérieure de 5µA.
Le mode basse consommation LPM3 est activé dès que les différentes routines ont terminé leur traitement.
Une journée fait 1440 minutes. Chaque jour, l'horloge fonctionne en roue libre entre 99,3% (elle n'arrive pas à se synchroniser) et 99,9% du temps (elle arrive à se synchroniser en 2 minutes ou moins). La consommation est essentiellement due à l’affichage, à l’entretien de XT1 et au traitement qui doit s’exécuter la plupart du temps en moins d’1ms à 1MHz de fréquence d’horloge.
La documentation du mode LPM3 est un peu imprécise sur certains points mais des recherches sur le forum de Texas Instrument (TI) permettent de lever certaines ambiguïtés.
Ainsi, on apprend que LPM3 n’arrête pas les quartz (c’est heureux) et n’arrête pas SMCLK s’il est utilisé par un périphérique ce qui est le cas du timer A0 qui utilise XT2 (8MHz) et qui est actif lorsque l’horloge recherche le signal DCF77.
Pour le reste, il y a les nécessaires initialisations des différents périphériques pour limiter la consommation. Par défaut, ils sont désactivés. Un problème se pose néanmoins pour les GPIO.
En général, on conseille de configurer les GPIO en entrée avec une résistance de polarisation active (il y a des débats sur le niveau (bas ou haut) d'activation de ces résistances). Sauf que le MSP439F449 ne dispose pas de résistances de polarisation.
J'ai lu quelque part que TI conseillait de configurer les GPIO en sortie. Cela parait logique : sans résistances de polarisation, les entrées sont en l'air et il y a un risque de voir les GPIO commuter en permanence ce qui consomme de l'énergie.
j'ai fait plusieurs essais et pour le moment, les meilleurs résultats ont été obtenus en mettant P1 et P2 en sortie (sauf les GPIO explicitement déclarées en entrées) et les autres ports dans leur configuration par défaut à la mise sous tension sachant que la plupart d'entre-eux sont initialisés par la suite lors de la configuration de l'écran LCD.
Selon Wikipédia, les piles AA Alcalines ont une capacité de l'ordre de 2850mAh.
Si l’on utilise deux piles en série pour obtenir 3V (capacité toujours de 2850mAh), l’autonomie sera de l’ordre de 7 ans pour une consommation moyenne de 45µA.
Avec le processeur piloté uniquement par sa base de temps interne, l’autonomie serait de l’ordre de 8 ans.
STM32L476
La documentation du microcontrôleur fait près de 2000 pages, plus celle de la bibliothèque HAL que j'ai utilisé malgré mes réticences, plus les autres documents, etc. Bref, pour faire un simple programme comme celui-là (quelques centaines de lignes de codes plus celles générées par STM32CubeMX (au demeurant, très puissant), c'est beaucoup de boulot. Pour la première fois, j'ai utilisé une IA (Gemini) dans un développement et cela m'a beaucoup apporté pour trouver les informations dans la documentation ou pour avoir des conseils sur les différents modes de basse consommation.
A un moment, j'ai été bloqué par une fonction de HAL dont un paramètre n'était pas documenté. Je me doutais de son usage (un masque dans la gestion de l'afficheur) mais j'avais un doute sur les valeurs à utiliser. Gemini m'a trouvé la réponse instantanément en me précisant que le paramètre n'était pas documenté dans les documents existants mais qu'il avait analysé le source de l'implémentation de la fonction dans la bibliothèque pour me répondre !
Autant l'implémentation de ce programme m'a paru évidente sur MSP430, autant, j'ai beaucoup galéré sur le STM32L4 à cause de souci avec les horloges et les modes basse consommation. Apparemment, ST a dû jongler avec les particularités de l'architecture ARM pour obtenir un système basse consommation efficace, au prix d'une certaine complexité qu'on ne retrouve pas sur MSP430 :
- En recherche de signal : 100µA (400µA sur MSP430)
- En roue libre (uniquement l'affichage de l'heure) : 17µA stable après une demi-heure de fonctionnement. 14µA "à froid" (45µA sur MSP430).
Note : pour le MSP430, les moyens de mesure que j'ai utilisés en 2023 ont peut être surestimé la consommation en roue libre. Mon avis est qu'on doit plutôt être aux alentours de 20µA mais en 2026, je n'avais plus ce montage pour faire de nouvelles mesures.
Voici un relevé de la consommation du STM32L476 sur quelques programmes de tests. La configuration générale est la suivante :
- Horloges : LSE pour le RTC, LSI (32kHz) pour LPTIM1, HSI à 16MHz pour l'horloge système. Toutes les mesures ont été faites avec la sonde STLINK connectée sauf indication contraire.
- Test minimal avec aucun périphérique, en mode STOP2 : moins de 1µA.
- Ajout de l'horloge RTC : 1,8µA.
- Ajout du calendrier et une interruption par seconde : 2µA.
- Ajout du LPTIM1 avec une interruption chaque seconde : 2,47µA.
- Ajout d'un afficheur LCD (23 broches+4 COM), tous les segments allumés plus configuration de 3GPIO (en l'air) : 11,7µA.
- Idem sauf afficheur LCD passant de l'état "tous les segments éteints" à "tous les segments allumés" toutes les secondes : 8,3µA.
Les courants consommés doivent être légèrement plus faibles lorsque la sonde STLINK est déconnectée et surtout, les GPIO IO et CLK en mode ANALOG.
STM32L152
J'ai cru à un moment avoir cramé mon STM32L4 (je l'ai un peu abimé suite à une fausse manipulation, 2 GPIO hors-service. Puis plus tard, il est resté alimenté plusieurs minutes en 5V. Mais finalement, il fonctionne toujours très bien aux deux GPIO mortes près). Comme je disposais d'une carte de développement Olimex pour STM32L152, j'ai porté, non sans mal, le programme du STM32L476 sur le STM32L152. Non sans mal car le STM32L152 présente pas mal de différences avec le STM32L476 et est beaucoup moins performant.
- En recherche de signal (hors alimentation du module DCF77) : 170µA.
- En roue libre (uniquement l'affichage de l'heure) : 78µA.
Voici un relevé de la consommation du STM32L152 sur quelques programmes de tests. La configuration générale est la suivante :
- Horloges : LSE pour le RTC, LSI (32kHz), HSI à 16MHz pour l'horloge système. sonde STLINK déconnectée. Alimentation sur batterie 3,7V, régulateur LDO actif.
- RTC, Calendrier actif, LCD actif, configuration de 3GPIO (en l'air), une interruption par seconde : 8,6µA
- Idem sauf afficheur LCD passant de l'état "tous les segments éteints" à "tous les segments allumés" toutes les secondes : 39µA.
Au delà des aspects fonctionnels, on voit nettement qu'il y a eu de grosses améliorations d'architecture entre le STM32L4 et le STM32L1 et une amélioration conséquente du contrôleur LCD. Finalement, malgré sa complexité, le STM32L4 se révèle un peu plus simple à utiliser et surtout, je n'ai pas eu certaines des mauvaises surprises que j'ai eu avec le STML152. J'ai passé quelques heures à essayer de comprendre pourquoi ma conversions analogique-numérique ne fonctionnait plus jusqu'à ce que je me rende compte que l'horloge système n'était pas rétablie en sortie du mode STOP (elle l'est sur le STM32L4). Résultat, je fonctionnais sur l'horloge de "redémarrage" à 2MHz qui n'est pas assez rapide pour les convertisseurs analogique-numérique.
Conclusion du match
On peut considérer cette réalisation (horloge DCF77) comme un match entre trois processeurs basse-consommation (MSP430F449 (vieille génération apparue dans les années 1990), STM32L152 (2010), STM32L476 (2015)). Ce match n'est cependant pas tout à fait fair-play dans la mesure où le programme qui tourne sur le MSP430 est proche de la stratégie 1 décrite précédemment et que la stratégie 2 utilisée pour les mesures sur les STM32 est beaucoup plus simple et consomme moins de lignes de code. Néanmoins :
- Le MSP30F449 et ses homologues sont beaucoup plus simples à utiliser que les STM32 et sont "relativement" sans surprises.
- En mode "STOP" (LPM3 sur MSP430, STOP ou SRTOP2 sur STM32), le MSP430F449 fait la course en tête avec le STM32L476. Le STM32L152 est complètement dans les choux à cause de la consommation de son contrôleur LCD).
- En "RUN", les STM32L4 (et même L1) bénéficient d'une puissance et d'une vitesse de traitement qui leur permettent de rester éveillés très peu de temps. Le MSP430 est à la peine et on le voit dans les consommations durant les traitements "lourds" de l'application (qui sont quand même des traitements très simples).
Au final, le MSP430 des années 1990 reste un processeur tout à fait utilisable tant que les traitements restent simples. Pour de nouveaux développements, le L152 est hors course. Par contre, le STM32L476 sort grand vainqueur de ce match au prix cependant de pas mal de sueur à cause d'une documentation, disons, perfectible et d'une faible valeur ajoutée des forums. Si vous commencez à avoir des traitements un peu lourds (mais pas trop quand même sinon, adieu la basse consommation), c'est un très bon choix dans les années 2020.
Chargement du logiciel pour STM32L476 (uniquement Stratégie 2)
Le logiciel a été développé en langage C avec l'environnement STM32CubeIDE et STM32CubeMX.
A VENIR
Août 2023 - Juin 2026




