Exercices du chapitre "Microcontrôleur et periphériques"
Inverser l’état d’une LED
Exercice 1
Écrivez un programme
en C++ qui inverse l’état d’une LED connectée à la broche PE_0
lorsqu’un
bouton connecté sur la broche PA_0
est appuyé. Notez que la LED est
allumée lorsqu’on écrit un 0
dans la broche et éteinte lorsqu’on écrit un
1
. On aimerait qu’elle soit éteinte au démarrage. Notez aussi que le
bouton a besoin d’une résistance de pull-down pour fonctionner. Faites
attention à ne pas utiliser de “Magic numbers” dans votre code et définissez vos
constantes avec des static constexpr
.
Solution
#include "mbed.h"
constexpr int kLedOn = 0;
constexpr int kLedOff = 1;
constexpr int buttonReleased = 0;
constexpr int buttonPressed = 1;
int main()
{
DigitalOut led(PE_0, kLedOff);
DigitalIn button(PA_0, PullDown);
int prevState = button;
while (true) {
int state = button;
if (prevState == buttonReleased && state == buttonPressed) {
led = !led;
}
prevState = state;
}
}
Parité UART
Exercice 2
À quoi sert la “parité” dans les paramètres de communication avec un UART ?
Solution
La communication série n’est pas toujours très fiable et il arrive parfois que des bits soient mal reçus. La parité permet de détecter si un bit a été modifié pendant la transmission.
Périphériques I2C
Exercice 3
Cherchez sur Internet d’autres périphériques qui utilisent l’I2C
Solution
En plus des thermomètres et des mémoires EEPROM, on trouve encore
- Des I/O supplémentaires (https://www.ti.com/product/PCF8575)
- Des “Real time clocks” (https://datasheets.maximintegrated.com/en/ds/DS1307.pdf)
- Des accéléromètres (https://www.nxp.com/docs/en/data-sheet/MMA8452Q.pdf)
- Des écrans OLED (https://www.adafruit.com/product/326#technical-details)
Débit sur un bus SPI
Exercice 4
Avec un SPI rapide (50MHz), combien de temps faut-il pour lire complètement une carte SD de 16GiB ?
Solution
\(16\,\mathsf{GiB} = 16 \cdot 8 \cdot 2^{30}\,\mathsf{bit}\). Il faut donc \((128 \cdot 2^{30}) \div (50 \cdot 10^{6}) = 2748\,\mathsf{secondes})\) ou environ \(45\,\mathsf{minutes}\).
Si vous n’avez pas de calculatrice, vous pouvez utiliser l’approximation \(2^{30} \approx 10^{9}\) et ça donne donc \((128 \cdot 10^{9}) \div (50 \cdot 10^{6}) = 2560\,\mathsf{secondes} \approx 42\,\mathsf{minutes}\).
Inversion d’une LED basée sur un état
Exercice Exercices du chapitre “Microcontrôleur et periphériques”/5
Implémentez la classe MyDevice
pour que la LED soit inversée à chaque deuxième pression du bouton.
Solution
class MyDevice {
public:
MyDevice(PinName led) : led_(led, kLedOff), counter_{0} {};
void handler()
{
counter_++;
if (counter_ >= 2) {
led_ = !led_;
counter_ = 0;
}
}
private:
DigitalOut led_;
int counter_;
};
Suffixe C++ pour les unités de temps
Exercice 6
Quel(s) mécanismes(s) de C++ permet(tent) de simplement ajouter un suffixe ms
à une durée pour un temps en millisecondes ?
Solution
- La surcharge de l’opérateur
""ms
(User defined literals) - La classe
std::chrono::duration
utilise aussi le concept des Templates, pour la représentation interne de la durée, mais ce n’est pas directement lié à la question du suffixe.
Utilisation des unités de temps
Soit le code :
timer_measure_kernel.cpp | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
La ligne 5 interroge le temps actuel du noyau (en millisecondes et sur 64 bits), la ligne 6 attend 100 millisecondes, puis la ligne 7 lit le nouveau temps actuel du noyau. Le temps écoulé est la différence entre les deux temps.
Exercice 7
Quel est le défaut de cette solution ?
Solution
Le nom de la méthode indique bien que nous mesurons des millisecondes, mais aucune unité n’est attachée au résultat.
Clignotement asymétrique d’une LED
Exercice 8
Soit le code
timer_blink.cpp | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Solution
#include "mbed.h"
constexpr int kLedOn = 0;
constexpr int kLedOff = 1;
class MyDevice {
public:
MyDevice(PinName led) : led_(led, kLedOff), counter_{0} {};
void handler()
{
if (counter_ == 0) {
led_ = kLedOn;
} else if (counter_ == 1) {
led_ = kLedOff;
}
if (counter_ >= 3) {
counter_ = 0;
} else {
counter_++;
}
}
private:
DigitalOut led_;
int counter_;
};
int main()
{
MyDevice device(PE_0);
Ticker flipper;
flipper.attach(callback(&device, &MyDevice::handler), 250ms);
while (true) {
asm("nop");
}
}
Consommation d’énergie et autonomie
Exercice Exercices du chapitre “Microcontrôleur et periphériques”/9
Nous souhaitons alimenter une station météo construite avec un microcontrôleur STM32F412 avec deux piles en série de type AA de \(1.5\,V\) et \(2800\,mAh\) chacune. En mode de veille, le microcontrôleur (avec une tension de \(3V\)) consomme \(12\,\mu{}A\). Pour faire la mesure et l’envoyer, le microcontrôleur à besoin de \(3\) secondes pendant lesquelles il consomme \(112\,\mu{}A\) par \(Mhz\) et il tourne à \(100\,Mhz\). Pendant ces 3 secondes, il faut aussi activer le module LoRa qui consomme \(100\,mA\) pendant \(100\, mS\). En travail, le circuit est aussi alimenté en \(3V\).
Avec quelle période pouvons nous faire des mesures pour que le système puisse fonctionner pendant \(5\) ans avec les mêmes piles ?
Solution
Le système doit fonctionner pendant 5 ans avec \(2800\,mAh\). Sa consommation moyenne doit donc être au maximum de \(\frac{2.8 [Ah]}{5 \cdot 356 \cdot 24 [h]}\) soit environ \(63.9\,\mu{}A\). En veille, il consomme \(12\,\mu{}A\), donc la réalisation est possible.
Pendant une période de \(p\) secondes, la moyenne de la consommation est de
Et cette moyenne ne dois pas dépasser \(63.9\,\mu{}A\). Nous pouvons résoudre l’équation suivante par rapport à \(p\):
On prend un peu de marge et on choisit une période d’au moins 15 minutes.