3 Adc Dac
3 Adc Dac
3 Adc Dac
Connecteurs
"Arduino"
Sur les cartes NUCLEO la tension de référence de l'ADC (VREF+) est par défaut connectée à AVDD, qui elle
même est par défaut connectée à VDD=3,3v
Attention, VDD est produit par un régulateur avec une tolérance de +/- 2%.
Le temps de conversion est au maximum de 0,87uS sur 12bits pour un STM32 sur carte NUCLEO
a) Après conversion, exprimer le nombre N dans le registre DATA en fonction de VREF+, et du nombre de
bits de l'ADC
b) Expliquer le rôle de
- CH_SEL[18:0]
- ADC_IN[15:0]
- TRG0 à TRG7
- EOC
- CPU IRQ
- DMA
- START
Mise en œuvre
Câbler un potentiomètre (1KΩ à 100KΩ), extrémités 3,3v et 0v , curseur connecté sur A0 (AN0)
#include "mbed.h"
#define VREF 3.3
int main(void)
{
while (1)
{
if(adin > 0.3) maled = 1;
else maled = 0;
pc.printf("valeur en %% de VREF+ : %3.3f\n", adin.read()*100.0);
pc.printf("valeur brute 0x%04X \n", adin.read_u16());
pc.printf("tension : %f \n",adin.read()*VREF);
wait(0.5);
}
}
AnalogIn adin(A0); création d'une instance de la classe AnalogIn, le paramètre représente le nom de
la broche utilisée
read(); méthode de la classe AnalogIn retournant un nombre réel 0.0 pour une tension de 0v et 1.0 pour
une tension égale à VREF+
Cette méthode est appelée par défaut.
read_u16()); méthode de la classe AnalogIn retournant un nombre entier sur 16bits (0x0000 pour 0v et
0xFFFF pour VREF+). Cette méthode utilise le sur-échantillonnage et la décimation matériel permettant de
passer d'un résultat sur 12bits à un résultat sur 16bits.
1.1 Exercice
Tracer N(16) = f(Vin), nombre sur 1-bits en fonction de la tension d'entrée.
Calculer le quantum.
La tension de sortie du capteur de température change linéairement avec la température. Le capteur n'est
pas calibré (jusqu'à 45 ° C d'une puce à l'autre). Pour améliorer l'exactitude de la mesure des valeurs
d'étalonnage (TS_CAL1 et TS_CAL2) sont stockées dans la mémoire du microcontrôleur pendant la
production.
const uint16_t TS_CAL1 = *(uint16_t *)(0x1FFF75A8);
const uint16_t TS_CAL2 = *(uint16_t *)(0x1FFF75CA);
A partir de ce programme
#include "mbed.h"
int main()
{
printf("\nSTM32 temperature interne\n");
while(1) {
printf("ADC Temp = %f\n", adc_temp.read());
printf("\033[1A"); // controle sur terminal ASCII
wait(1.0);
}
}
Afficher la valeur de la température interne exacte en introduisant une correction avec les valeurs de
calibration.
#include "mbed.h"
#if !DEVICE_ANALOGOUT
#error Ce uC ne dispose pas de DAC
#else
AnalogOut dac_out(PA_4);
#endif
int main()
{
printf("Sawtooth example\n");
while(1) {
for (int i = 0; i < 0xFFFF; i += 5) {
dac_out.write_u16(i);
wait_us(10);
}
dac_out.write_u16(0xFFFF);
wait_us(100);
dac_out.write_u16(0);
}
}
#ifndef FIRFILTER_H_
#define FIRFILTER_H_
class FirFilter
{
public:
FirFilter();
void put(double value) ;
double get() ;
private:
double history[nbcoeffs];
int current_index_;
};
#endif
filtre.cpp
#include "filtre.h"
#include "coefficients.h"
FirFilter::FirFilter()
{
current_index_=0;
for(int i = 0; i < nbcoeffs; ++i) history[i] = 0.0;
}
double FirFilter::get()
{
double output = 0.0;
int index = current_index_;
for(int i = 0; i < nbcoeffs; ++i)
{
if(index != 0) --index;
else index = nbcoeffs - 1;
output += history[index] * coeffs[i];
}
return output;
}
#ifndef COEFFS_H_
#define COEFFS_H_
double coeffs[] = {
#endif
Dans main.cpp
#include "mbed.h"
#include "filtre.h" // http://t-filter.engineerjs.com/
AnalogOut sortie(PA_4);
AnalogIn entree(A0);
DigitalOut led(LED1);
Serial pc(USBTX,USBRX);
FirFilter monfiltre;
int main() {
double e,s;
while(1)
{
// temps de calcul mesure 150uS
e=entree.read();
monfiltre.put(e);
s=monfiltre.get();
sortie.write(s);
led=0;
wait_us(350); // fe#2000Hz
led=1;
}
}
b) Dessiner l'algorigramme de main.cpp, ainsi que des méthodes put et get de la classe FirFilter.
c) Commenter chaque ligne du programme