Le circuit intégré L298 comporte deux ponts de transistors (ponts en H) réalisés avec des transistors à jonctions. L'usage le plus courant de ce type de pont est le pilotage d'un moteur à courant continu de faible puissance au moyen d'une tension PWM (Pulse Width Modulation), c'est-à-dire MLI (Modulation de Largeur d'Impulsion).
Le L298 existe en montage traversant (boitier Multiwatt15) ou en montage de surface (PowerSO20). Il existe de nombreuses cartes prêtes à l'emploi qui comportent un L298. On peut citer la carte d'extension Arduino Motor Shield, qui a l'avantage de s'enficher directement sur une carte Arduino mais dont l'utilisation se limite à une commande de moteur. Nous utiliserons la carte Joy-It MotorDriver2, qui offre les mêmes fonctions pour un coût inférieur et surtout une connexion directe aux ports du L298, ce qui permet d'envisager d'autres applications que la commande de moteur.
Après avoir expliqué sommairement le fonctionnement d'un pont du L298, nous verrons comment le piloter avec un microcontrôleur (carte Arduino).
Nous verrons différents modes d'utilisation du pont. Ce pont est typiquement utilisé pour alimenter un moteur à courant continu, qui est une charge inductive traversée par un courant d'un sens déterminé. Le pont en H permet de changer le sens du courant (ce qui change de sens de rotation du moteur) mais le sens du courant ne change pas à chaque cycle du découpage. Une autre application des ponts à transistor est la conversion DC-AC, où le signe de la tension en sortie du pont change à chaque cycle. Les onduleurs, qu'ils fonctionnement par résonance ou par modulation MLI, peuvent être réalisés avec un pont en H. La page Onduleur monophasé MLI montre la réalisation d'un onduleur MLI que nous avons fréquemment utilisé pour alimenter des bobines, mais celui-ci fonctionne avec un pont à transistors MOSFET, dont la commutation est beaucoup plus rapide que celle d'un transistor à jonctions. Nous verrons dans quelle mesure il est possible d'utiliser un pont à transistor à jonctions pour ce type d'application (à une fréquence de l'ordre de 40 kHz) et comment se fait la commande du pont dans ce cas.
Voici le schéma interne (simplifié) du L298 :
Vss est la tension d'alimentation de la partie logique (max +7 V), c'est-à-dire la commande du pont. Vs est l'alimentation de la charge (max 50 V), dont la puissance doit être adaptée à la charge utilisée. Le courant maximal supporté par un pont en continu est 2 A, ce qui limite son utilisation à des charges de faible puissance. Il faut noter la présence sur ce schéma de résistances RSA et RSB (qui ne font pas partie du L298) qui servent à mesurer le courant mais dont la valeur est si faible que les points 1 et 15 peuvent être considérés comme étant à la masse. Dans la plupart des cas, les bornes 1 et 15 sont simplement reliées à la masse.
On s'intéresse au pont situé à gauche, dont les deux bornes de sortie sont OUT1 et OUT2. Les trois ports de commande de ce pont sont IN1, IN2 et ENA (enable). Chacun des quatre transistors du pont est piloté par la sortie d'une porte ET. Le rond en entrée de deux de ces portes représente une inversion.
Lorsque ENA=0, les sorties des quatre portes ET sont à l'état 0 quels que soient les états de IN1 et IN2. Les transistors sont donc à l'état bloqué (équivalents à des interrupteurs ouverts). Lorsque ENA=1, l'état des transistors dépend de IN1 et IN2. IN1 pilote le demi-pont 1, constitué des deux transistors à gauche. IN2 pilote le demi-pont 2, constitué des deux transistors à droite. Ainsi lorsque IN1=1, le transistor supérieur du demi-pont 1 est à l'état saturé (équivalent à un interrupteur fermé) alors que le transistor du bas est à l'état bloqué (interrupteur ouvert). La fonction de IN2 est similaire pour le demi-pont 2. Si on veut que la tension Vs soit appliquée à la charge, on doit appliquer ENA=1 et IN1=1,IN2=0 ou bien IN1=0,IN2=1 suivant la polarité souhaitée. La figure suivante montre l'état du pont lorsque ENA=1,IN1=1,IN2=0 avec une représentation par le modèle des interrupteurs :
Figure pleine pageLorsque la charge est un moteur, cet état permet de faire passer le courant dans le moteur dans un sens déterminé. Il est d'usage de réguler le courant dans le moteur en appliquant sur ENA un signal PWM (ou MLI) tout en maintenant IN1=1 et IN2=0. Lorsque ENA=1, la tension Vs est appliquée à la charge, lorsque ENA=0, aucune tension n'est appliquée à la charge, c'est-à-dire que la charge est en circuit ouvert donc aucun courant ne la traverse. La tension moyenne appliquée à la charge est égale à Vs mutlipliée par le rapport cyclique du signal appliqué sur ENA. Il faut bien remarquer que lorsque ENA=0, aucune tension n'est appliquée à la charge (l'alimentation est déconnectée).
Pour inverser le sens du courant dans le moteur, il faut utiliser l'état ENA=1,IN1=0,IN2=1 :
Figure pleine pageQue se passe-t-il si on applique IN1=1,IN2=1 ? D'après le schéma simplifié, on devrait obtenir les quatre transistors à l'état saturé, ce qui conduirait à un quasi court-circuit de l'alimentation. En réalité, lorsque IN1=0,IN2=0, on obtient l'état suivant :
Figure pleine pageLa tension appliquée à la charge est donc nulle, c'est-à-dire que ses deux bornes sont court-circuitées. Dans le cas d'un moteur, cet état permet de réaliser un freinage moteur car il permet le développement d'un courant induit dans le moteur. Lorsque IN1=1,IN2=1, on obtient l'état suivant :
Figure pleine pageCet état est équivalent au précédent, mais les deux bornes de la charges sont à présent connectées sur la borne +Vs de l'alimentation. Le premier état est préférable à ce dernier car la consommation de polarisation des transistors y est plus faible.
Il est intéressant de vérifier le fonctionnement du pont (en l'absence de charge) et surtout de mesurer les temps de commutation des transistors. Nous utilisons la carte L298 ci-dessous (Joy-It MotorDriver2) :
Figure pleine pageUne seule alimentation est nécessaire, celle de la charge (tension Vs), car la carte comporte un régulateur 5 V qui fournit la tension Vss de la partie logique. L'entrée ENA est reliée à une borne +5 V au moyen d'un cavalier (ENA=1). Si l'on souhaite appliquer un signal PWM sur l'entrée ENA (afin de moduler le courant dans le moteur), il faudra bien sûr retirer ce cavalier. La tension Vs de l'alimentation peut être choisie de 7,5 V à 50V. Pour le test, nous prenons Vs = 10 V.
Le programme présenté est configuré pour l'Arduino MEGA. La table de correspondance entre les entrées-sorties de l'ATmega2560 et les bornes de la carte est donnée dans ATmega2560-Arduino Pin Mapping. L'entrée IN1 est reliée à la borne 12 de l'Arduino, l'entrée IN2 à la borne 11 et l'entrée ENA à la borne 5. D'après la table de correspondance, ces deux bornes sont reliées aux entrée-sorties PB6 et PB5 du microcontrôleur. Il est bien sûr possible de commander les sorties au moyen de la fonction digitalWrite, mais nous allons plutôt les piloter directement au moyen du registre PORTB, ce qui permettra de faire basculer deux sorties simultanément.
#define IN1 12 // PB6 (Arduino MEGA) #define IN2 11 // PB5 #define ENA 5 void setInput10() { uint8_t portb = PORTB; // copie du registre portb &= ~(1 << PORTB5); // IN2 = 0 portb |= (1 << PORTB6); // IN1 = 1 PORTB = portb; // changement sumultané de IN1 et IN2 } void setInput01() { uint8_t portb = PORTB; portb &= ~(1 << PORTB6); // IN1 = 0 portb |= (1 << PORTB5); // IN2 = 1 PORTB = portb; } void setInput00() { PORTB &= ~((1 << PORTB5) | (1 << PORTB6)); // IN2 = 0 et IN1 = 0 } void setInput11() { PORTB |= (1 << PORTB6) | (1 << PORTB5) ; // IN1 = 1 et IN2 = 1 } void setup() { pinMode(IN1,OUTPUT); pinMode(IN2,OUTPUT); pinMode(ENA,OUTPUT); digitalWrite(ENA,HIGH); setInput00(); } void loop() { setInput10(); delayMicroseconds(100); setInput01(); delayMicroseconds(100); setInput11(); delayMicroseconds(100); setInput00(); delayMicroseconds(100); }
Voici les tensions de OUT1 et OUT2 :
test1.pdfDans les intervalles [0,100], [100,200], [200,300], et [300,400] sont réalisés respectivement les états 11, 00, 10 et 01. Voyons en détail la transition entre l'état 10 et l'état 01 (à 300 ms) :
test1-detail.pdfBien que les fronts, respectivement descendant et montant, appliqués sur IN1 et IN2 soient simultanés, nous constatons que la passage d'un transistor de l'état saturé à l'état bloqué se fait avec un retard, de l'ordre de la microseconde, par rapport au passage de l'autre transistor de l'état bloqué à l'état saturé. Considérons l'enchainement des états 01 et 10, obtenu avec le code suivant :
void loop() { setInput10(); delayMicroseconds(100); setInput01(); delayMicroseconds(100); }
Voici les tensions IN1 et OUT1 :
test1-IN1OUT1.pdfVoici le détail au voisinage d'un front montant :
xlim(195,205)test1-IN1OUT1-detail1.pdf
et d'un front descendant :
xlim(295,305)test1-IN1OUT1-detail2.pdf
On constate que le passage d'un transistor de l'état bloqué à l'état saturé se fait en moins de 1 microseconde alors qu'il faut 2 microsecondes pour passer de l'état saturé à l'état bloqué. Pour vérification de la simultanéité des commandes IN1 et IN2, voici les tensions en IN1 et IN2 :
test1-IN1IN2.pdfLa modification directe du registre PORTB permet bien de modifier simultanément les sorties PB5 et PB6. Il est difficile de savoir d'où viennent le dépassement de tension et la pseudo-oscillation mais il est probable que l'étage d'entrée de l'oscilloscope et le câble de liaison en soit la cause.
Ce mode de fonctionnement est utilisé pour alimenter un moteur. La polarité de OUT2 par rapport à OUT1 est fixée (en fonction du sens de rotation du moteur souhaité). On choisit donc IN1=1,IN2=0 ou bien IN1=0,IN2=1 et on applique un signal PWM sur l'entrée ENA. Lorsque ENA=0, les quatres transistors sont bloqués (interrupteurs ouverts), ce qui fait que le moteur est en circuit ouvert. Il ne pas confondre cet état avec l'état ENA=1,IN1=0,IN2=0, qui réalise un court-circuit du moteur.
Voici la méthode la plus simple pour y parvenir, consistant à utiliser la fonction analogWrite :
#define IN1 12 // PB6 #define IN2 11 // PB5 #define ENA 5 void setup() { pinMode(IN1,OUTPUT); pinMode(IN2,OUTPUT); pinMode(ENA,OUTPUT); digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW); analogWrite(ENA,50); } void loop() {}
La valeur fournie à analogWrite est le rapport cyclique codé sur 8 bits, soit une valeur comprise entre 0 et 255. La fréquence est 490 Hz (elle est de 980 Hz sur les sorties 4 et 13). Si l'on souhaite une fréquence plus élevée (par exemple 10 kHz), if faut programmer directement le Timer, comme expliqué dans la partie suivante.
Pour mesurer les tensions OUT2 et OUT1 et en déduire V12=V(OUT2)-V(OUT1), il faut placer une charge entre OUT2 et OUT1. Le résultat dépend du type de charge. Voici les tensions obtenue pour une résistance R=1 kΩ placée entre OUT2 et OUT1 et le rapport cyclique 50/255 appliqué sur ENA:
test5-pwm50-OUT1OUT2.pdf test5-pwm50-V12.pdfVoici les tensions pour un rapport cyclique 150/255 appliqué sur ENA :
test6-pwm50-OUT1OUT2.pdf test6-pwm50-V12.pdfDans le cas d'une charge résistive, la tension V12 reproduit la forme de la tension de commande (ENA). On constate cependant qu'il y a une chute de tension par rapport à la tension d'alimentation (ici +10 V), d'environ 1,2 volts. Cette chute de tension est due à la tension collecteur-émetteur des transistors à l'état saturé, qui est non négligeable lorsqu'un courant est débité dans la charge (c'est la raison pour laquelle on préfère les ponts MOSFET). Elle augmente avec le courant dans la charge. La documentation donne la tension Vce en fonction du courant collecteur-émetteur (qui est aussi le courant dans la charge) pour un transistor inférieur du pont (L) et un transistor supérieur (H) :
Pour la résistance de 1 kΩ que nous avons utilisée comme charge, le courant ne dépasse pas 10 mA mais la chute de tension totale (deux transitors saturés) atteint tout de même 1,2 volts. Pour un courant de 1 A, elle atteindrait 3,4 V.
Pour l'alimentation d'un moteur, il faudra tenir compte de cette chute de tension en choisissant une tension d'alimentation au dessus de la tension nominale du moteur. Si on souhaite alimenter une résistance en tant que résistance chauffante et contrôler la puissance (un transistor Darlington suffit pour cette application), il faudra prendre garde au fait que la relation entre le rapport cyclique et la puissance moyenne délivrée dépend de la chute de tension, qu'il faudra donc au préalable mesurer pour la résistance utilisée.
Ce mode de fonctionnement consiste à faire alterner la polarité de la tension V12=V(OUT2)-V(OUT1) à une fréquence de découpage de plusieurs kHz. La tension V12 passe alternativement de -Vs et Vs. Pour ce faire, il faut fixer ENA=1 et appliquer deux signaux PWM complémentaires sur IN1 et IN2. Si le rapport cyclique est de 0,5, la tension V12 moyenne est nulle. S'il est supérieur à 0,5, elle est positive. S'il est inférieur à 0,5, elle est négative.
Il y a essentiellement deux applications à ce mode de fonctionnement. La première est l'onduleur à résonance : le rapport cyclique est 0,5 et la tension carrée alternative excite un circuit RLC à sa fréquence de résonance. L'alimentation d'une bobine de chauffage par induction fonctionne de cette manère. La seconde est l'onduleur à modulation de largeur d'impulsation : la fréquence de découpage est élevée (au moins 10 kHz), et le rapport cyclique de V12 est modulé à basse fréquence. La charge inductive (qui a aussi une résistance) réalise un filtrage passe-bas qui élimine pratiquement la fréquence de découpage et laisse apparaître le signal de modulation. Ce principe est mis en œuvre dans les amplificateurs audio de classe D. Un convertisseur DC-DC à découpage fonctionnne selon le même principe mais dans ce cas la modulation n'intervient qu'en cas de changement de la tension de sortie.
Pour générer les signaux complémentaires à envoyer sur IN1 et IN2, nous devons utiliser un Timer. Nous choisissons le Timer 1, qui comporte un compteur 16 bits. Le Timer permet de générer trois signaux PWM synchrones sur les trois sorties OC1A, OC1B et OC1C. Pour notre application, nous utilisons OC1A pour IN1 et OC1B pour IN2. La table de correspondance (ATmega2560-Arduino Pin Mapping) montre que ces deus sorties sont reliées aux bornes 11 et 12 de l'Arduino MEGA.
Le Timer est configuré en mode PWM, Phase and Frequency Correct et le registre ICR1 est utilisé pour déterminer la valeur maximale atteinte par le compteur. Les bits permettant d'effectuer cette configuration sont WGM13=1, WGM12=0, WGM11=0, WGM12=0 (voir tableau page 148 de la doc de l'atmega2560). WGM12 et WGM12 sont dans le registre TCCR1B alors que WGM11 et WGM12 sont dans le registre TCCR1A. Le registre TCNT1 contient la valeur du compteur. Il est incrémenté à la fréquence d'horloge jusqu'à la valeur contenue dans ICR1 puis est décrémenté jusqu'à zéro. La sortie OC1A change d'état lorsque TCNT1 franchit la valeur donnée dans le registre OCR1A (Output Compare Register), aussi bien par valeur croissante que décroissante. Il en est de même pour le registre OCR1B avec la sortie OC1B. Les bits COM1A1 et COM1A0 (situés dans TCCR1A) permettent de préciser comment la sortie est modifiée lorsque TCNT1=OCR1A (page 160 de la doc). Pour la sortie OC1A, nous choisissons : COM1A1=1, COM1A0=0, qui signifie clear OC1A on compare match when up counting, set OC1A on compare match when downcouting. Pour la sortie OC1B, nous choisissons : COM1B1=1, COM1B0=1, qui signifie set OC1B on compare match when up counting, clear OC1B on compare match when downcouting. De cette manière, si OCR1A=OCR1B, les signaux OC1A et OC1B sont exactement complémentaires. La figure suivante montre le fonctionnement du Timer :
Figure pleine pageLe compteur (c.-à-d. le registre TCNT1) est incrémenté ou décrémenté d'une unité à chaque top d'horloge. L'horloge utilisée est l'horloge principale de l'Arduino (16MHz), à laquelle un facteur de division de fréquence est éventuellement appliqué. Le choix de l'horloge se fait sur les bits CS12,CS11,CS10 du registre TCCR1B, comme suit (avec n=1) :
La période T des signaux générés dépend à la fois de la fréquence d'horloge et de la valeur de ICR1 : T = 2*ICR1*Tclock. Plus la fréquence d'horloge est élevée, plus la période peut être définie avec précision. On doit donc choisir le diviseur de fréquence le plus petit qui permette d'avoir une valeur de ICR1 inférieure à 0xFFFF.
Nous voulons générer un signal de 40 KHz, qui est la plus grande fréquence acceptable par le L298 d'après sa documentation. La période est donc T = 25 us. Le choix d'une fréquence d'horloge de 16 MHz s'impose puisqu'il conduit à ICR1 = 200. On note au passage qu'il est possible d'obtenir exactement 40 kHz mais que les deux fréquences voisines sont 39.8 kHz pour ICR1 = 201 et 40.2 kHz pour ICR1 = 199. La précision de fréquence est donc d'environ 0.2 kHz à cette fréquence. Il existe un mode de fonctionnement du timer appelé fast PWM, qui fonctionne avec une pente croissante seulement, ce qui permet de gagner un facteur 2 de précision, mais ce mode ne convient pas ici, car comme nous le verrons plus loin, nous avons besoin d'un compteur ayant une rampe croissante et une rampe décroissante.
Le programme suivant permet de générer un nombre déterminé de cycles. L'interruption Overflow Interrupt est configurée pour le Timer 1 : lorsque TCNT1 atteint la valeur donnée dans ICR1, l'interruption est déclenchée. Dans le gestionnaire d'interruption (fonctionn ISR(TIMER1_OVF_vect)), on compte les cycles afin de stopper l'émission des sorties lorsque le nombre de cycles voulu est atteint.
#define IN1 11 // PB5 (OC1A) #define IN2 12 // PB6 (OC1B) #define ENA 5 volatile uint32_t count; uint32_t max_count; uint16_t diviseur[6] = {0,1,8,64,256,1024}; uint32_t icr; uint8_t tccr1a,tccr1b; uint16_t ocr1a,ocr1b; bool inter; void config_impulsions(float period, int32_t nombre, float ra, float rb) { /* periode : T en microsecondes nombre : nombre de cyles (nombre de cycles illimité si nombre==0) ra : rapport cyclique de OC1A rb : rapport cyclique de OC1B */ count = 0; if (nombre >0) { max_count = nombre+1; inter = true; } else inter = false; tccr1a = 0; tccr1b = 0; //phase and frequency correct PWM mode, top = ICR1 WGM3:0 = 1,0,0,0 tccr1b |= (1 << WGM13); // COM1A1 = 1, COM1A0 = 0 : clear OC1A on compare match when up counting // COM1B1 = 1, COM1B0 = 1 : set OC1B on compare match when up counting tccr1a |= (1 << COM1A1) | (1 << COM1B1) | (1 << COM1B0); icr = (F_CPU/1000000*period/2); int d = 1; while ((icr>0xFFFF)&&(d<5)) { d++; icr = (F_CPU/1000000*period/2/diviseur[d]); } tccr1b |= d; ocr1a = icr*ra; ocr1b = icr*(1.0-rb); } void start_impulsions() { cli(); count = 0; TCCR1A = tccr1a; TCCR1B = tccr1b; TCNT1 = 0; ICR1 = icr; OCR1A = ocr1a; OCR1B = ocr1b; if (inter) TIMSK1 = 1 << TOIE1; // overflow interrupt enable sei(); } ISR(TIMER1_OVF_vect) { count++; if (count==max_count) { TCCR1A = 0; PORTB &= ~((1 << PORTB5) | (1 << PORTB6)); // PB5 et PB6 LOW } } void setup() { pinMode(IN1,OUTPUT); pinMode(IN2,OUTPUT); PORTB &= ~(1 << PORTB5); PORTB &= ~(1 << PORTB6); pinMode(ENA,OUTPUT); digitalWrite(ENA,HIGH); config_impulsions(25,10,0.5,0.5); } void loop() { delay(100); start_impulsions(); }
Voici les signaux IN1,IN2 et les tensions OUT1,OUT2
test2-IN1IN2-OUT1OUT2.pdfet voici la différence V12=V(OUT2)-V(OUT1), qui est la tension appliquée à la charge :
test2-V12.pdfComme nous l'avions déjà constaté, le basculement de OUT1 de 0 à +10 V se fait avec un retard par rapport au front montant de IN1 et le basculement de +10 V à 0 se fait avec un retard encore plus grand par rapport au front descendant de IN1. Le même constat vaut évidemment pour OUT2 et IN2. En conséquence, le rapport cyclique de OUT1 (et de OUT2) est trop grand. La différence V12 s'annule sur un intervalle de temps beaucoup trop grand. Pour corriger cela, il suffit d'abaisser le rapport cyclique des signaux de commande. En effet, l'utilisation d'un mode de Timer à double rampe (une rampe croissante et une décroissante) fait qu'un changement de OCR1A et OCR1B ne change pas la position du point correspondant à TCBT1=ICR1, c'est-à-dire le point milieu de chaque demi-cycle. Il faut abaisser les rapports cycliques de IN1 et IN2 suffisamment pour que le front montant de OUT1 se fasse en même temps que le front descendant de OUT2, afin que la tension V12 ne s'annule que sur un intervalle de temps négligeable. Après plusieurs essais, nous avons opté pour le choix suivant :
config_train_impulsions(25,5,0.44,0.44);test3-IN1IN2-OUT1OUT2.pdf test3-V12.pdf
En corrigeant le rapport cyclique des tensions de commande IN1,IN2, sous sommes donc parvenu à obtenir une tension V12 carrée de rapport cyclique 0.5. Avec une tension d'alimentation de 40 V, on produit ainsi une tension carrée alternant entre -40 et 40 volts. Cette tension peut servir à exciter un circuit résonant à cette fréquence ou bien un transducteur piézoélectrique.
Il faut remarquer que les tensions atteintes par V12 ne présentent pas de chute de tension par rapport à la tension d'alimentation (+10 V) car la mesure est faite sans charge. Comme nous l'avons vu plus haut, la présence d'une charge même traversée par un faible courant suffit à donner une chute de tension variant de 1 à 3 volts en fonction du courant. La mesure de la tension V12 peut être réalisée sans charge car cette différence de potentiel est toujours fixée par le pont. En revanche, l'étude de la tension en commande monopolaire (signal PWM sur ENA) nécessite la présence d'une charge (voir paragraphe 4).
Est-il possible de générer une tension V12 ayant un rapport cyclique quelconque, dans le but de faire de la modulation de largeur d'impulsion ? C'est en principe possible, à condition de déterminer, pour un rapport cyclique R souhaité, quels rapports cycliques r1 et r2 il faut appliquer aux signaux de commande IN1 et IN2.
Notons τu le retard entre un front montant de IN1 (ou IN2) et le front montant de OUT1 (ou OUT2). Notons τd le retard pour un front descendant. D'après les courbes obtenues plus haut, τu vaut environ 0,7 microsecondes alors que τd vaut 2 microsecondes. La tension de commande est au niveau haut pendant r1T, où T est la période. La tension OUT correspondante reste au niveau haut pendant r1T+τd-τr. Le rapport cyclique de OUT1 est donc :
et celui de OUT2 :
Le rapport cyclique de V12 est égal à celui de OUT2, soit R2 et on doit avoir R1+R2=1. On obtient donc :
Voici comment se fait la configuration de la commande :
float R=0.3; float r2=R-6e-2; float r1=1-R-6e-2; config_train_impulsions(25,5,r1,r2);
Voici un exemple avec R=0.3 :
test4-V12.pdfLe rapport cyclique minimal qui peut être obtenu est 0,06 et le maximal est 0,94. La plage de rapports cycliques est tout à fait convenable. Il est donc possible de faire de la modulation de largeur d'impulsion avec un L298 à 40 kHz. Il s'agit d'ailleurs de la fréquence maximale donnée dans la documentation du circuit, mais rien n'empêche d'utiliser une fréquence un peu plus grande. Plus la fréquence est grande, plus la plage de rapports cycliques accessibles est faible. Par exemple pour 80 kHz, on aurait r2=R-12e-2 et le rapport cyclique ne pourrait être ajusté que de 0,12 à 0,88. Un autre problème qui se pose lorsqu'on augmente la fréquence est la dissipation dans les transistors. En effet, celle-ci intervient pendant les phases de commutation. Si ces phases durent trop longtemps par rapport à la période, l'évacuation thermique se fait moins bien. Bien sûr, le niveau d'échauffement dépend de la charge utilisée. Il n'y a pas vraiment de risque à dépasser la fréquence de 40 kHz car le circuit comporte une protection interne contre une élévation trop grande de température. Si l'on est soucieux d'efficacité énergétique, il est cependant préférable de se tourner vers un pont un transistors MOSFET.