Bonjour à tourtes et à tous,
Peut-être que je suis en train de réinventer la roue, mais bon, je présente.
Il me faut un générateur de tension continue avec une résolution supérieure à 8 bits (attention, je n'ai pas dit précision). Pour cela, j'utilise le timer 2 associé aux sorties D3 et D11.
La sortie D3 va me générer un PWM sur les 8 bits de poids forts et la sortie D11, un PWM sur les N bits de poids faibles. N allant de 1 à 8 pour une résolution allant de 9 à 16 bits.
Comme le montre ce schéma

le courant généré vers l'ampli Op est la somme de ce qui passe dans R, connecté à D3 et ce qui passe dans kBitR connecté à D11. Le courant max dans kBitR valant 1 LSB de celui passant dans R.
Il y a deux manières de procéder :
-
soit sur D11 on utilise l'excursion max (0 à 256) et à ce moment, kBit vaut 256,
-
soit sur D11 on utilise une excursion limitée à 2^N LSB, auquel cas, kBit vaut 2^N.
Pour voir la forme des PWM sur chaque sortie, le sketch est le suivant :
#define frequencePWMde31372hz 0b00000001
#define frequencePWMde3921hz 0b00000010
#define frequencePWMde980hz 0b00000011
#define frequencePWMde490hz 0b00000100
#define frequencePWMde245hz 0b00000101
#define frequencePWMde122hz 0b00000110
#define frequencePWMde30hz 0b00000111
// Nota : ces fréquences sont celles obtenues avec un µC fonctionnant sur un quartz de 16MHz, tout en laissant le Prescaler sur "1" (pas de division de fréquence globale, donc)
int mode;
int NbBit = 16;
uint32_t kBit;
void setup()
{
// mode = 1; // Excursion partielle
mode = 2; // Excursion totale
kBit = pow(2, NbBit-8);
// Déclaration de la broche d'E/S D3 en sortie
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
analogReference(DEFAULT); // Référence de 5 volts
Serial.begin(9600);
// Sélection du rapport de division de fréquence du timer 2
TCCR2B &= 0b11111000; // <===== à ne pas toucher
TCCR2B |= frequencePWMde31372hz; // <===== à changer, selon la fréquence que vous souhaitez en sortie
// Nota 1 : l'opérateur "&=" constitue un "ET logique". Il applique le masque "0b11111000", afin de mettre à 0 les 3 derniers bits du registre TCCR2B, tout en laissant les autres bits intacts
// Nota 2 : la fonction "|=" constitue un "OU logique". Il applique notre valeur à 8 bits, comme définie tout en haut, afin de modifier les 3 derniers bits du registre TCCR2B, précédemment mis à zéro
bitClear(TCCR2B, WGM02); // Mise de WGM02 à 0
bitSet(TCCR2A, WGM01); // Mise de WGM01 à 1
bitSet(TCCR2A, WGM00); // Mise de WGM00 à 1
}
void loop() {
switch(mode) {
case 1: // Excursion partielle. La résistance vaut kBit*R
for (uint32_t i = 112*kBit; i < 144*kBit; i++) {
if (i%kBit == 0)
analogWrite(3, i/kBit);
analogWrite(11, i%kBit);
delay(1024/kBit);
}
break;
case 2: // Excursion totale. Ici la résistance vaut toujours 256*R
for (uint32_t i = 112*kBit; i < 144*kBit; i++) {
if (i%kBit == 0)
analogWrite(3, i/kBit);
analogWrite(11, (256/kBit)*(i%kBit));
delay(1024/kBit);
}
break;
}
}
Bon amusement pour ceux qui ont un oscilloscope.
Cordialement.
Pierre.