CH32V003 : protocole 1‑wire et DS18B20

Ce que nous allons faire - Prérequis

Nous allons voir dans ce cours comment utiliser la documentation d'un composant pour créer le code permettant de communiquer avec lorsque notre micro-contrôleur ne dispose pas d'un périphérique de communication adapté - ce qu'on appelle le bit banging.

Les prérequis de ce cours sont :

  • Avoir suivi le cours CH32V003 : GPIO et interruptions.

  • Disposer d'un capteur de température DS18B20 tel que recommandé dans les pré-requis, ainsi que d'une résistance de 4.7 kΩ.

Bit banging

Il arrive occasionnellement qu'on ait besoin de communiquer avec un composant mais que le micro-contrôleur utilisé ne dispose pas d'un périphérique pour le faire. A titre d'exemple, le STC15W104 ne dispose pas d'UART, ce qui est gênant pour communiquer avec un PC. Dans un tel cas, la seule solution est de gérer la communication par programme en utilisant des lignes de GPIO. Cette technique s'appelle en anglais le bit banging.

Rassurez-vous, le STC15W104 est un vieux micro-contrôleur de la famille du 8051, donc vous n'aurez pas à l'utiliser. Cependant, la pertinence du bit banging demeure car vous pouvez être contraint, pour des questions de coût, de disponibilité ou de compatibilité, d'utiliser un micro-contrôleur auquel il manque un ou plusieurs périphériques (UART, I2C, SPI...) pour l'application envisagée.

Avantages Inconvénients
  • Permet de communiquer avec des dispositifs pour lesquels le micro-contrôleur utilisé ne dispose pas de périphérique.

  • Permet de palier aux lacunes du micro-contrôleur utilisé lorsqu'on ne peut pas en choisir un plus adapté.

  • Accapare des ressources (flash, RAM, puissance de calcul) qui ne sont plus disponibles pour l'application.

  • Ne permet pas de bénéficier de mécanismes comme le DMA ou les interruptions.

  • Accroît la complexité du code et le risque qu'il contienne des bugs.

  • Plus lent qu'un périphérique intégré au micro-contrôleur.

Dans le cadre de ce cours, nous utiliserons le capteur de température DS18B20, qui utilise un protocole de communication appelé 1‑wire ("one wire" - prononcer ouanouailleur) qui n'est disponible sur aucun micro-contrôleur, ce qui vous obligera à le développer. :)

Le protocole 1‑wire

Le protocole 1‑wire a été développé au siècle dernier par Dallas Semiconductor (maintenant intégré à Analog Devices), qui l'a utilisé dans une série restreinte de composants. C'est un protocole série qui ne nécessite que 2 fils, mais qui est tellement lent et laborieux qu'il n'a jamais connu le succès, contrairement à I2C, qui n'utilise qu'un fil de plus.

Au départ, Dallas avait créé 1‑wire pour une ligne de dispositifs de contrôle d'accès appelés "iButton", mais les tokens NFC se sont par la suite imposés dans cette application. De nos jours, le seul composant 1‑wire qui soit encore largement utilisé est le DS18B20, notamment en domotique. Les autres sont tellement chers, en plus d'être malcommodes, qu'on leur préfère des composants plus récents utilisant SPI ou I2C.

Le protocole 1‑wire est décrit de manière détaillée dans la data sheet du DS18B20, de la page 8 à la page 16. Je ne donnerai ici que des informations de haut niveau pour que vous ayez une bonne vue d'ensemble et je vous invite à vous reporter à la data sheet pour aller dans le détail.

Sur le plan électrique, un composant 1‑wire comporte au minimum 3 broches : VCC, GND et DQ (bus 1‑wire proprement dit). Toutes les broches connectées à la ligne DQ fonctionnent en mode open drain, ce qui signifie qu'il doit y avoir une résistance pull-up sur la ligne. Le composant peut être connecté au micro-contrôleur par 2 ou 3 fils selon la manière dont on souhaite l'alimenter. La version 3 fils est la plus simple et c'est elle que nous utiliserons avec notre DS18B20 :

Dans la version 2 fils, la broche VCC est reliée à GND et le composant est alimenté en mode "parasite" en stockant de l'énergie dans un condensateur interne quand la ligne DQ est à l'état haut, ce au prix de complications matérielles et logicielles supplémentaires. Vous trouverez plus de détails à ce sujet pages 4 et 5 de la data sheet.

Sur le plan logiciel, une partie du protocole est commune à tous les composants 1‑wire et une autre partie dépend de la fonction du composant considéré. Cela signifie que notre code sera organisé en 2 modules, un module pour la partie 1‑wire générique et un autre module spécifique à notre DS18B20, qui utilisera les fonctionnalités du premier pour la communication. C'est une application directe de l'approche utilisée dans le cours CH32V003 : I2C et afficheur LCD.

Le micro-contrôleur est toujours le maître du bus 1‑wire et les composants connectés au bus sont les esclaves. Le principe de la communication est que le maître alloue des "time slots" sur le bus pour les différentes opérations - reset, lecture et écriture. Un time slot est un intervalle de temps pendant lequel le maître commence par mettre le bus à l'état bas pour une durée qui dépend du type de slot puis il la ramène à l'état haut. On a les cas de figure suivants :

  • Reset : toute communication commence par un reset. Le maître met DQ à l'état bas pendant au minimum 480μs puis relâche la ligne et laisse une nouvelle période d'au minimum 480μs aux esclaves pour signaler leur présence. L'esclave attend entre 15 et 60μs après que le maître ait relâché le bus puis met à son tour la ligne DQ à l'état bas pendant 60 à 240μs pour indiquer sa présence. Si la ligne reste à l'état haut pendant tout ce temps, cela signifie qu'aucun esclave n'est connecté au bus.

  • Écriture d'un "0" : le maître met le bus à l'état bas pendant 60μs puis le relâche pendant au moins 1μs.

  • Écriture d'un "1" : le maître met le bus à l'état bas pendant 1μs puis le relâche pendant au moins 59μs.

  • Lecture d'un bit : le maître met le bus à l'état bas pendant 1μs puis le relâche. L'esclave met alors le bus à l'état désiré pendant 59μs puis le relâche. Le maître doit lire l'état de la ligne de bus endéans les 15 premières μs du time slot puis doit attendre au moins 1μs après que l'esclave ait relâché le bus avant de démarrer le slot suivant.

En clair, ça signifie que pour lire ou écrire un octet, vous aurez besoin de 8 time slots de lecture ou d'écriture, soit une durée totale de 8 x 61μs = 488μs. Notez au passage qu'on peut avoir besoin de lire un bit isolé, notamment pour attendre la fin d'exécution d'une commande.

Reportez-vous aux figures 13 et 14, pages 14 et 15 de la data sheet pour les chronogrammes.

Enfin, notez que, chaque esclave 1‑wire ayant un identifiant unique appelé "ROM code", il est nécessaire de récupérer ces codes à l'initialisation du système, puis de sélectionner l'esclave auquel on veut s'adresser avant de pouvoir utiliser ses fonctionnalités. Les commandes nécessaires sont décrites page 9 de la data sheet sous le titre "ROM COMMANDS". Du fait que nous n'avons qu'un seul esclave de connecté au bus, notre travail en sera grandement simplifié.

Si par la suite vous aviez plusieurs esclaves différents, par exemple un DS18B20 et un DS2438, sachez que le premier octet du ROM code est un code famille permettant de savoir de quel composant il s'agit. Le code famille du DS18B20 est 0x28. Vous trouverez une liste des codes famille sur cette page.

A vous de jouer !

Pour résumer, votre travail va consister à écrire une application lisant toutes les 10 secondes la température fournie par le DS18B20, avec affichage du résultat sur la console. Les séquences de commandes à utiliser seront :

  • A l'initialisation : reset puis read rom pour lire l'identifiant du DS18B20 ; reset puis match rom puis write scratchpad pour choisir une résolution de 12 bits.

  • A chaque lecture de température : reset puis match rom puis convertT pour démarrer la conversion ; attente de la fin de l'opération ; reset puis match rom puis read scratchpad pour récupérer la valeur de la température.

Pour aller plus loin

Une fois que votre code fonctionne, reprenez le projet radar à ultrasons que vous avez réalisé précédemment et ajoutez une lecture de la température toutes les minutes pour calculer avec précision la vitesse du son, et donc la distance.

Une autre possibilité, si vous avez acheté plusieurs DS18B20, est d'utiliser la commande search ROM pour les lister tous et les lire successivement pour afficher leur température. Vous en réchaufferez un entre vos doigts pour vérifier que la lecture est correcte. Si vous vous lancez dans cette aventure, vous voudrez lire les pages 58 à 61 de ce document (section C.3. Search ROM Command).

Ce que nous avons appris

Vous savez maintenant :

  • Ce qu'est le protocole 1‑wire et à quoi il sert.

  • Comment utiliser le capteur de température DS18B20.

  • Comment faire pour communiquer avec un composant pour lequel votre micro-contrôleur ne dispose pas de périphérique.


Copyright (c) 2025 Vincent DEFERT - Tous droits réservés