Boite à outils pour électronique avec le stm32

Introduction

Initialement prévu pour tester des fonctions du microprocesseur STM32F103 en utilisant le module Maple Mini clone, ce projet est vite devenu inexploitable parce que la dernière application finissait par occulter les autres réalisées auparavant. Pour y remédier et parce que toutes les applications ne peuvent pas fonctionner en même temps, il a fallu réorganiser le code en fonctions indépendantes et sélectable par l'utilisateur.

Les fonctions USART1 et CDCACM sont installées par defaut. Il est possible de sélectionner les fonctions suivantes:

Ce document présente les diiférentes fonctions réalisées.

Le module utilisé pour ce projet est le Maple Mini clone, mais le module Bluepill peut faire la même chose en adaptant certaines entrées sorties. Par contre pour passer sur une autre plateforme ce sera plus compliqué, car une grande partie du code sert à initialiser les périphériques du microprocesseur.

Noter que les entrées sorties sont imposées par le périphérique utilisé.

Pour comprendre le code, Il est bien sûr conseillé d'avoir la documentation du constructeur RM0008 Reference manual.

Fonctions générales

Le programme implémente un interpréteur de commandes permettant d'accéder aux fonctions générales, que l'on retrouvera d'une application à l'autre :

La commande C prend comme paramètre l'index de la fonction dans la table des fonctions. Par exemple, pour démarrer l'affichage de l'heure, exécuter :

C0

Affichage de l'heure

Lorsque l'on ne sait pas quelle fonction utiliser, on peut toujours afficher l'heure, la date et la température si on a un ds18b20 sous la main.

 *  C0A   -> p = A    display  to console
 *  C0B   -> p = B    display  to lcd
 *  C0G   -> p = G    temperature display  to lcd
 *  C0O   -> p = O    send to cdcacm

Utilisation de l'adc

La fonction readadc peut être utilisée en 2 modes: un mode lent pour lire une tension d'un circuit ou d'un capteur analogique sur un ou plusieurs canaux et un mode rapide où adc1 et adc2 échantillonne simultanément chacun un canal.

le mode lent

La fonction est cadencée par l'interruption à 100 Hz générée par le systick handler qui décrémente un compteur rdadc_rate initialisé par la valeur introduite par la commande T multiplié par 100.

 * C5AC0C17T20    -> p = AC0C17T20 -> channel 0 + channel 17 Vref every 20s

Il est possible, par la commnde N, de spécifier le nombre d'échantillons composant la mesure, qui par défaut est 16, afin d'effectuer une moyenne.

le mode rapide

Dans le mode rapide, le cadencement est effectué par le timer 3 qui produit le signal TRGO qui va déclencher la conversion ADC sur ADC1 et ADC2. L'ADC est configuré pour que son signal EOC de fin de conversion déclenche le dma 1 channel 1 qui va transféré le contenu du registre ADC1_DR vers un buffer en mémoire. Le dma provoque 2 interruptions, une lorsque le buffer est à moitié plein et l'autre quand il est complètement plein. Le code dans l'interruption transfère les données du demi buffer vers l'USB cdcacm et qui sont accessibles, sur une machine hôte, sur le port /dev/ttyACM0. Noter que ADC1_DR contient en fin de conversion le résultat de ADC1 et ADC2.

 * C5BC0C1F8000    -> p = BC0F8000  -> channel 0 + channel 1 triggered by
    timer TIM3_TRGO at 8kHz

Fonction Générateur de fréquences

Pour tester un fréquencemètre, quoi de mieux que de se créer un générateur en utilisant, par exemple, le timer 3 sur le port PA7 signal TIM3_CH2.

Le timer 3 est utilisé en timer et défini dans gentim3.c. Il compte les impulsions de l'oscillateur interne divisées par le prescaler et le diviseur (le compteur lui même), qui pilote l'output compare, fonctionnant en mode PWM1 et pilotant le port PA7 signal TIM3_CH2.

La sélection de fréquence se fait par une des commandes suivantes:

C3F100   -> p = F100         => sélection fréquence 100 Hz
ou
C3P35D19 -> p = P35D39       => prescaler 35 et diviseur 39 sélection  => fréquence 50 kHz

Dans la première commande C3 est le sélecteur de fonction gentim3 et F100 La sélection de fréquence à 100 Hz. Dans la deuxième on trouve le sélecteur C3 un prescaler de 35 et un diviseur de 39. Ce qui donne une fréquence de 72 Mhz / 36 / 40 = 50 kHz. Noter que les registres prescaler (PSC) et diviseur (ARR) doivent contenir la valeur - 1 pour diviser par la valeur.

Les timers 1, 2 et 4, dans gentim1.c, gentim2.c et gentim4.c, fournissent la même fonctionnalité respectivement sur les ports PA8 signal TIM1_CH1, PA1 signal TIM2_CH2 et PB6 signal TIM4_CH1

C1F100   -> p = F100         => sélection timer 1 fréquence 100 Hz
C2F100   -> p = F100         => sélection timer 2 fréquence 100 Hz
C4F100   -> p = F100         => sélection timer 4 fréquence 100 Hz

Lecture d'une mémoire i2c at24cxx

Les mémoires eeprom du type at24cxx utilisent le bus I2C pour les opérations d'accès lecture et écriture. Elles peuvent servir pour, par exemple, stocker une configuration qui lue au démarrage remplacerait la ligne de commande.

La connexion de ces mémoires au microprocesseur nécessite une interface dont voici le schéma:

schéma de raccordement de l'eeprom at24cxx
schéma de raccordement de l'eeprom

La commande suivante initialise la fonction et definit la taille de la mémoire à 0x8000 octets.

 * C6A8000 -> p = A8000

Les sous commandes suivantes permettent de lire et d'écrire la mémoire

 * :R                read from address 0, len = memory size
 * :r<addr>_<len>    read from address addr, len = len, ex:  :r10_100
 * :W        write string at address 0, ex: Wil fait beau
 * :w<addr>_<string>   write string to address addr, ex:  :r10_il fait beau

Fonction lecture température avec DS18B20

Cette fonction permet de lire la temperature avec un circuit DS18B20. La position du capteur est définie dans le Makefile et utilise, actuellement, le port PB10 pour le bus onewire et PB11 pour l'alimentation du capteur.

Par défaut la période de mesure est de 10 s, elle peut être ajustée avec la commande C7A20 pour, par exemple, 20 secondes.

C7                         # mesure toutes les 10 s

C7A60                      # mesure toutes les minutes

Fonction fréquencemètre

La fonction fréquencemètre consiste par définition à compter le nombre de cycles du signal d'entrée pendant l'unité de temps, la seconde.

Pour cela, on utilise le timer 2 comme compteur connecté à l'entrée PA0 et utilisant le signal TIM2_CH1_ETR. Le timer 2 est controlé par le timer 1 qui produit un créneau calibré OC1 de 10 s, 1 s, 0.1 s, suivant la gamme choisie. Le timer 2 ne compte que lorsque le créneau OC1 est à 1. La transition 1 à 0 du créneau est la fin de la mesure on peut alors afficher la fréquence mesurée.

Le timer 1 est utilisé en timer, il divise l'horloge interne 72 MHz. On utilise l'Output Compare OC1 pour produire le créneau calibré qui peut être visible sur le port PA0 signal TIM1_CH1. Ce signal est routé en interne vers le timer 2 par configuration.

L'activation du fréquencemètre se fait par une des commandes suivantes:

C8A  ou C8B ou C8C         => pour le choix de la gamme
ou
C8AF100                    => lance en plus gentim3 à la fréquence 100 Hz

Fonction périodemètre

La fonction périodemètre consiste, par définition, à mesurer la durée d'un cycle du signal d'entrée et l'unité de temps est la seconde.

L'entrée se fait sur le port PA1 signal TIM2_CH2 du timer 2, qui va compter les cycles d'une horloge à 1 MHz dérivée de l'oscillateur interne.

On utilise 2 canaux d'input compare ic1 et ic2, tous deux connectés au port d'entrée, l'un, ic2, déclenchant sur le front montant et l'autre, ic1, sur le front descendant. De plus le timer est programmé en mode esclave de façon que le front ic2 reset le compteur, ce qui provoque un évènement update. L'update intervient aussi à chaque débordement du compteur, il faut alors ajouter 65536 au compteur totalisateur. Voir le mode Input PWM dans la doc RM0008 de ST.

Le premier compteur totalise entre 2 fronts montants, ce qui donne la période et le deuxième entre le premier front montant et le front descendant, ce qui permet de calculer un rapport cyclique.

La sélection du périodemeètre se fait par une des commandes suivantes:

C9A  ou C9B                   => sélection de la gamme
ou
C9AF100                       => lance en plus gentim3 à la fréquence 100 Hz

Analyseur logique

L'analyse logique consiste à échantillonner un port à une fréquence au moins 2 fois plus rapide que la fréquence des signaux à observer.

La fréquence d'échantillonnage est fournie par le timer 2 qui va, régulièrement, déclencher le dma 1 channel 2 qui lit le port et transfère la valeur dans un buffer en mémoire. Une interruption est émise lorsque le buffer est plein à moitié et complétement, ce qui permet de transférer, à chaque fois, le contenu du demi buffer vers USB cdcacm. Un programme, sur le host, doit lire les données transmises sur le port USB /dev/ttyACM0 et les stocker dans un fichier pour traitement ultérieur.

Le démarrage du timer 2 est fait, par défaut, par l'ouverture du port /dev/ttyACM0 sur le host. On peut choisir d'utiliser le port PA8 pour démarrer ou arrêter le timer.

La sélection de l'analyseur se fait par une des commandes suivantes:

C10AF1000000                   => sélection de la fréquence, trigger sur USB
ou
C10CF100000                    => sélection de la fréquence, trigger sur PA8

Fonction lecture d'une mémoire flash série

Cette fonction permet de la lecture d'une mémoire flash série avec le bus SPI.

 * C11

C11
6 id 0xEF14
4 mf 0xEF id 0x4015

Cette fonction est incomplète, elle permet simplement de lire l'identificateur de la mémoire en utilisant le bus SPI. Pour une mémoire Winbond W25Q16DV, le manufacturer id est 0xEF14 et le jedec id est 0xEF 0x4015. Pour un fonctionnalité compléte, un transfert de données entre un host et la carte doit être implémenté.

raccordement flash série
raccordement flash série
photo de l'interface flash série
photo de l'interface flash série

Fonction test rtc ds1302

Cette fonction permet le test du circuit d'horloge RTC ds1302. L'heure du stm32 doit être initialisé au préalable.

C12
raccordement de l'horloge RTC ds1302
raccordement de l'horloge RTC ds1302

Avant d'effectuer un test, le ds1302 doit être initialisé, c'est à dire mis à l'heure, ce qui initialise les registres internes. On enregistre, en même temps, dans la ram sauvegardée le time_t de la date courante. Ceci se fait par la sous commande U. Le ':' introduit la sous commande.

:U

Au bout d'un certain temps, on peut relire l'heure et la comparer à l'heure actuelle. Comme on a sauvegardé la date de départ, on peut calculer la dérive sur une certaine durée.

:R
diff time -4493 s in 14195307 s

14195307 s equivaut à 164d 7h 8m 27s

Ici, le ds1302 a pris 4493 secondes d'avance sur l'heure actuelle en 164d 7h 8m 27s. Ce n'est pas très bon !.

Deux autres sous commandes permettent de lire et écrire une chaine de caractères à l'adresse 8 dans la mémoire sauvegardée du ds1302.

:wC8AF10000

:r
ds1302 string C8AF10000

Ici la commande enregistrée permet de lancer, au démarrage, le fréquencemètre et le générateur timer 3 à 10 kHz si la variable maple_cfg a pour valeur 2 (voir les cavaliers de configuration).

Fonction générateur de fréquence par différence F0 - F1

Les générateurs, présentés précédemment, ne peuvent pas fournir toutes les fréquences, mais il est possible d'en élargir le nombre en utilisant une modulation d'une porteuse F0 par une fréquence F1 à l'aide d'un montage annexe composé de 2 bascules D et d'une porte ou exclusif, dont voici le schéma:

schéma du générateur de fréquence par différence
schéma de raccordement du générateur de fréquence par différence

Pour ce faire, on doit disposer d'une fréquence 2F0 fournie par le timer 2 et d'une fréquence F1 fournie par le timer 3. On recupère sur la sortie Q en 9 une fréquence FD = F0 - F1.

La sélection du générateur de fréquence par différence se fait par une des commandes suivantes:

C13F200000f22500
ou
:F100000                  => sélection de la fréquence 2F0
:f100000                  => sélection de la fréquence F1

Fonction générateur de signal DCF77

Il s'agit ici de générer un signal compatible avec celui de l'émetteur DCF77, permettant de piloter en local une horloge radiopilotée du type WC8708 ou WT87, en cas de non réception dcf.

La génération de la porteuse DCF 77.5 kHz se fait à l'aide de la fonction freqdiff. Le timer 2 génère la fréquence 2F0 = 200 kHz, le timer 3 génère la fréquence F1 = 22500 Hz et l'adaptateur freqdiff la fréquence FD 77.5 kHz.

Le timer 1 et son output compare est utilisé pour générer la modulation accessible sur le port PA8. Il est piloté par le timer 4 utilisé en prescaler qui fournit la fréquence 1000 Hz, car il n'est pas possible d'utiliser le prescaler du timer 1 dans le mode esclave.

A chaque minute, Les bits de modulation sont calculés à partir de l'heure locale theTime ou du RTC et servent à mettre à jour le registre TIM1_CCR1 et l'état souhaité de la sortie PA8 à chaque compare match qui est atteint lorsque le compteur, qui est activé en permanece, égale la valeur du registre TIM1_CCR1. L'état de a sortie PA8 est alors remis à jour par le timer.

Les signaux de porteuse et de modulation sont alors combiner dans un modulateur dont voici le schéma:

schéma du modulateur dcf
schéma du modulateur dcf

Le générateur de fréquence par différence et le modulateur sont cablés sur le même circuit.

photo du générateur de fréquence par différence et du modulateur dcf
photo du modulateur dcf

Un simple fil connecté sur la prise ANT et entourant l'horloge permet la synchronisation, sans perturber les voisins !.

La sélection du générateur de signal DCF77 se fait par la commande suivante:

C14        => pas de paramètre

Fonction générateur du signal de téléinformation compteur EDF

Le signal de téléinformation EDF est le signal émis en permanence par le compteur d'électricité. Pour en savoir plus, voir cette page et les documents en références.

Un générateur peut être utile pour tester un récepteur sans avoir à se brancher sur le compteur.

Le générateur consiste en un oscillateur à 50 kHz modulé en ASK (Amplitude Shift Keying) par le signal transmis, qui est une suite de 0 et 1. Lorsque le signal est à 0, le 50 kHz est transmis et lorsqu'il est à 1, le 50 KHz n'est pas transmis.

En fait, le signal est une suite de trames contenant des mots de 10 bits (1 start, 7 bits de donnée, 1 bit de parité paire sur la donnée, 1 bit de stop). Le tout est transmis à la vitesse de 1200 bits/s.

Le timer 2 est utilisé en oscillateur et fournit sa sortie sur le port PA1 signal TIM2_CH2. Il est controlé par le signal OC1 de l'output compare du timer 1 et qui peut être visible (bien que non utilisée) sur le port PA8 signal TIM1_CH1. Le timer 2 n'émet que lorsque OC1 est à 1.

Le timer 1 est piloté à 1.2 MHz par son prescaler, il faut donc 1000 impulsions à son entrée pour générer un temps bit. Pour chaque bit du mot à transmettre, on calcule la valeur à mettre dans le registre CCR1 pour qu'un évènement Output Compare se produise et provoque le changement d'état du signal OC1. On recommence pour les 10 bits, puis on passe au mot suivant.

Une trame est générée en début de séquence et est stockée dans un buffer à la disposition du timer 1. Elle contient les informations statiques similaires à celles fournies par le compteur et des informations qui changent à chaque trame, comme la puissane consommée et la valeurs des compteurs.

On peut observer la trame en bande de base sur le port PA8 signal TIM1_CH1, qui est inversé par rapport à OC1, en y branchant un uart à 1200 bit/s, 7 bits + parité paire. Si la parité gêne, on peut positionner la variable strip_parity à 1.

Pour être conforme au signal en sortie du compteur, il faudrait une adaptation de niveau pour attaquer le récepteur. Mais comme il ne s'agit que de simulation pour essais, on peut aussi strapper l'étage d'entrée du récepteur et avoir le même effet.

Si la fonction est sélectionnée dans le Makefile, l'activation du générateur de téléinformation se fait par la commande suivante:

C15         => pas de paramètre

Fonction test d'accès à une carte SD avec fatFs

Cette fonction est une fonction de test du module FatFs permettant d'accéder à un filesystem FAT sur une carte SD/MMC et dérivée du paquet http://elm-chan.org/fsw/ff/ffsample.zip, les modifications consistant à s'adapter au contexte de mymaple. Ce n'est donc pas une apllication en soi, mais un code permttant de s'exercer aux fonctions de FatFs avant de réaliser une application.

La taille du code étant importante, cette fonction n'est pas incluse par défaut.

La fonction est initialisée par la commande suivante. Les sous fonctions peuvent être accédée directement ou préfixée par ':'. La commande '?' liste les commandes disponibles que l'on peut retrouver dans la table HelpMsg du fichier mmcuser.c.

C16         => pas de paramètre

mW           # pour voir si ça répond
STM32F103 test monitor
LFN Disabled, Code page: 437

mp 1         # turn power on

mi 0         # Initialize disk
rc=0

ms 0         # Show disk status
Drive size: 1000448 sectors
Block size: 128 sectors

fi 0         # Force initialized the volume
rc=0 FR_OK

fs           #  Show volume status
FAT type = FAT16
Bytes/Cluster = 8192
Number of FATs = 2
Root DIR entries = 512
Sectors/FAT = 256
Number of clusters = 62486
Volume start (lba) = 105
FAT start (lba) = 121
DIR start (lba,clustor) = 633
Data start (lba) = 665

Volume name is DLOGGER
Volume S/N is 9464-BA2E
...14 files, 51984643 bytes.
0 folders.
499888 KiB total disk space.
449072 KiB available.

fl                 # Show a directory
----A 2019/03/10 07:34   1737799  10-BE_~1.MP3
----A 2019/03/10 07:35   1651158  DSCF4090.JPG
----A 2019/03/10 07:35   1630462  DSCF4091.JPG
----A 2019/03/10 07:35   1637264  DSCF4100.JPG
----A 2019/03/10 07:35    908288  KIF_4421.JPG
----A 2019/03/10 07:35    903680  KIF_4427.JPG
----A 2019/03/10 07:35    638464  KIF_4428.JPG
----A 2019/03/10 07:35    937984  KIF_4430.JPG
----A 2019/03/10 07:35    915129  KIF_4431.JPG
----A 2019/03/10 07:35    935936  KIF_4432.JPG
----A 2019/03/10 07:35    744960  KIF_4435.JPG
----A 2019/03/10 07:35    916480  KIF_4436.JPG
----A 2006/03/01 12:00        19  INDEX
----A 2019/03/10 07:50  38427020  AUDIO_15.WAV
  14 File(s),  51984643 bytes total
   0 Dir(s),  459849728 bytes free
...

L'interface utilise le port PB2 / BOOT1, ce qui rend impossible le chargement du programme en flash sans déconnecter l'interface.

raccordement SD, microsd - cliquer pour agrandir
raccordement SD, microsd

Le montage utilise un adaptateur SD/MICROSD vers USB du commerce qui a succombé assez rapidement et est donc réutilisé en support de carte. La carte MICROSD se monte sur l'autre face.

photo du lecteur de carte SD microsd
photo du modulateur dcf

Schéma de raccordement

Le schéma proposé ici est un essai de raccordement de différentes fonctions au module maple-mini: carte sd, ds18b20, lm4040, lm35, spi, i2c, usart1, usart3 ...

schéma de raccordement - cliquer pour agrandir
schéma électrique

Photo du montage

photo du montage  du circuit Maple Mini

Compiler mymaple

Mymaple dépend de la librairie opencm3 qui doit donc être installée au préalable. Après avoir téléchargé les sources de mymaple, extraire les sources et compiler avec le compilateur précédemment installé:

tar Jxvf mymaple-20yy.mm.dd.xz
cd mymaple-20yy.mm.dd
make            # maple-mini-clone

BLUEPILL=1 make # bluepill

make flash      # pour telecharger le programme

Il est possible de ne pas embarquer certaines fonctions, cela se passe dans le Makefile.

Références

  1. Programmation du processeur stm32f103 par liaison série.
  2. usbdfu : Device Firmware Upgrade par USB.
  3. Développement sur stm32.
  4. fonctions communes pour stm32.
  5. Utilisation du circuit stm32 appelé bluepill.
  6. Utilisation du circuit Maple Mini clone.
  7. Interface de connexion de la liaison téléinfo du compteur électrique.
  8. RM0008 Reference manual STM32F103xx.

License

The mymaple software is licensed under the terms of the GNU General Public License as published by the Free Software Foundation. See the file COPYING in the archive.

Download