Im Aufsatz „Digitale stromgeführte Spitzenwertreglung von DC/DC-Wandlern“ wurden die Grundlagen digitaler Regelkreise in Stromversorgungen behandelt. Darauf aufbauend wird der digitale Regler nun programmiert und implementiert.
In den Bildern 8, 9 und 10 sind die Programmablaufpläne für die stromgeführte Spitzenwertreglung eines DC/DC-Wandlers dargestellt. Im Folgenden wird der Programmcode der Hauptfunktion „main()“ (Bild 9) analysiert. Zuerst müssen der Mikroprozessor und die Peripheriebausteine initialisiert werden, damit sie verwendet werden können.
/* Initialisieren des µC und des ADU*/
SYS_init();
ADC_init();
Das PWM-Modul wird für eine Schaltfrequenz von 200 kHz konfiguriert. Kanal A steuert über ein Treiber-IC die Leistungs-MOSFETs des Abwärtswandlers an. Die Einschaltdauer in Kanal A ist auf 100 % gesetzt, da bei einer stromgeführten Spitzenwertreglung die effektive Einschaltdauer begrenzt wird, sobald die Stromstärke durch den Leistungs-MOSFET einen Schwellwert übersteigt. An diesem Punkt wird das PWM-Signal auf Low-Pegel geschaltet und folglich sperrt der Leistungs-MOSFET. Das Zurücksetzen des Zählerregisters wird dazu verwendet, das Abtasten und Digitalisieren der Ausgangsspannung auszulösen. Am Ende des Digitalisierens wird automatisch ein ADU-Interrupt ausgelöst und der Regelalgorithmus gestartet.
Die Initialisierung innerhalb der Funktion main() lautet:
Listing1
/* Setzen von PWM_MOD_1 auf fs = 200 kHz. PWM1-Kanal A wird für das Schalten
* des MOSFETs verwendet.
*/
PWM_config( PWM_MOD_1, PWM_nsToTicks(PERIOD_NS), PWM_COUNT_UP );
PWM_pin( PWM_MOD_1, PWM_CH_A, GPIO_NON_INVERT );
PWM_pin( PWM_MOD_1, PWM_CH_B, GPIO_NON_INVERT );
/* Setzen der maximalen Last auf 100 %. Die Auslösebereiche (später konfiguriert)
* beenden den High-Pegel des PWM, wenn der Strom
* den Anstiegspegel erreicht.
*/
PWM_setDutyA( PWM_MOD_1, PWM_nsToTicks(PERIOD_NS) );
/* Legt PWM1-Kanal B so fest, dass die Berechnungen
* genau vor der ansteigenden Flanke von PWM A abgeschlossen sind.
*/
PWM_setDutyB( PWM_MOD_1, PWM_nsToTicks( PERIOD_NS-2450+0 ) );
/* Legt „PWM Mod1“ so fest, dass die A/D-Umsetzung immer dann beginnt,
* wenn der Zähler von PWM1-Kanal B mit dem Tastverhältnis von Kanal B übereinstimmt.
*/
PWM_setAdcSoc( PWM_MOD_1, PWM_CH_B, PWM_INT_CMPB_UP );
/* Legt „PWM Mod1“ so fest, dass ein Interrupt für jeden PWM-
* Zyklus erzeugt wird, sobald der Zähler den Wert 0 erreicht.
*/
PWM_setCallback( PWM_MOD_1, 0, PWM_INT_ZERO, PWM_INT_PRD_1 );
Mit den folgenden Funktionen wird das zyklusweise, vom Komparator-Ausgang abhängige, Abschalten des PWM-Ausgangs realisiert. Die Funktion PWM_configBlanking() nutzt das digitale Komparator-Submodul und verbindet den Komparator-Ausgang mit dem Pulsweitenmodulator.
Die Dauer des Austastfensters wird im Komparator-Submodul festgelegt. Als Auslöser dient das digitale Komparatorergebnis, die Auslösebereiche werden im PWM-Modul konfiguriert.
Mit den folgenden Funktionen wird das zyklusweise, vom Komparator-Ausgang abhängige, Abschalten des PWM-Ausgangs realisiert. Die Funktion PWM_configBlanking() nutzt das digitale Komparator-Submodul und verbindet den Komparator-Ausgang mit dem Pulsweitenmodulator. Die Dauer des Austastfensters wird im Komparator-Submodul festgelegt. Als Auslöser dient das digitale Komparatorergebnis, die Auslösebereiche werden im PWM-Modul konfiguriert.
/* Speist das Ausgangssignal von Komparator Mod2 in
* PWM-Modul 1 und aktiviert das Austasten durch Setzen des digitalen
* Compare-Ereignisses PWM_DCEVT zum richtigen Zeitpunkt.
*/
PWM_configBlanking( PWM_MOD_1, PWM_CMP_COMP2, GPIO_NON_INVERT,
true );
/* Setzt die Dauer des Austastfensters auf 420 ns. */
PWM_setBlankingWindow( PWM_MOD_1, PWM_nsToTicks(420) );
/* Setzt die relevanten Auslösebereiche: d.h. wenn PWM_DCEVT eintritt,
* wird PWM1-Kanal A zyklisch gelöscht, aber ohne Auswirkungen auf
* PWM1-Kanal B.
*/
PWM_setTripZone( PWM_MOD_1, PWM_DCEVT, PWM_TPZ_CYCLE_BY_CYCLE );
PWM_setTripState( PWM_MOD_1, PWM_CH_A, GPIO_CLR );
PWM_setTripState( PWM_MOD_1, PWM_CH_B, GPIO_NO_ACTION );
Das A/D-Umsetzer-Modul 1 ist so konfiguriert, dass es die Ausgangsspannung von Kanal B2 digitalisiert. Die Digitalisierung wird von einem Startsignal des PWM-Modul 1 ausgelöst. Wenn die A/D-Umsetzung abgeschlossen ist, wird ein Interrupt ausgelöst und es wird die Interrupt-Serviceroutine IsrAdc() gestartet. Den Programmcode der Interrupt-Serviceroutine finden Sie im Anhang.
/* Konfiguriert den A/D-Umsetzer für das Abtasten von UA zur fallenden Flanke von Kanal B des PWM-Moduls 1.
*/
ADC_config( ADC_MOD_1, ADC_SH_WIDTH_7, ADC_CH_B2, ADC_TRIG_EPWM1_SOCB );
/* Wenn Digitalisierung abgeschlossen, Interrupt aufrufen und zu „IsrAdc“ wechseln.
*/
ADC_setCallback( ADC_MOD_1, IsrAdc, ADC_INT_1 );
Der Regler wird mit den Werten initialisiert, die bei der bilinearen Transformation der Übertragungsfunktion des Kompensationsnetzwerkes bestimmt wurden. Es kann auch ein Sanftanlauf konfiguriert werden.
/* Initialisieren des Reglers 2. Ordnung (2 Pole, 2 Nullstellen)*/
CNTRL_2p2zInit(&MyCntrl
,_IQ15(REF)
,_IQ26(A1),_IQ26(A2)
,_IQ26(B0),_IQ26(B1),_IQ26(B2)
,_IQ23(K),MIN_DUTY,MAX_DUTY
);
/* Einrichten eines 500-ms-Sanftanlaufs */
CNTRL_2p2zSoftStartConfig(&MyCntrl, 500, PERIOD_NS );
Der Komparator wird wie folgt konfiguriert: asynchroner Modus, nicht-invertierender Ausgang, der invertierende Eingang des Komparators ist mit dem internen D/A-Umsetzer verbunden und den Wert des D/A-Umsetzers legt der Regelalgorithmus fest.
/* Konfigurieren des Komparators Mod2 */
CMP_config( CMP_MOD_2, CMP_ASYNC, GPIO_NON_INVERT, CMP_DAC );
Die Stromanstiegskompensation wird über das Rampen-Submodul des Komparators realisiert. Zuerst muss das Submodul über CMP_rampConfig() mit der PWM-Periode synchronisiert werden. Die erforderliche Höhe der Rampe muss in einen digitalen Wert konvertiert werden, bevor sie als Argument an CMP_setRampDec() übergeben werden kann.
CMP_rampConfig( CMP_MOD_2, PWM_MOD_1 );
decval = CMP_calcRampDec( CMP_mVtoRampValue(124), PWM_freqToTicks(200000) );
CMP_setRampDec( CMP_MOD_2, decval );
Bevor Interrupts verwendet werden können, müssen diese zunächst allgemein zugelassen werden. Danach wartet die Ausführung in einer Leerlaufschleife, bis ein Ereignis für einen Interrupt auftritt.
/* Allgemeines aktivieren von Interrupts und Warten in Leerlaufschleife */
INT_enableGlobal(true);
while(1) {}
Den vollständigen Programmcode, einschließlich der Interrupt-Funktionen, finden Sie im Anhang (siehe Quellcodes).