Stromversorgung

Implementierung eines digitalen Schaltreglers

22. Februar 2013, 13:51 Uhr | Von Dr. Ali Shirsavar
Diesen Artikel anhören

Fortsetzung des Artikels von Teil 4

Quellcode für CSL von Biricha Digital Power

/******************************************************************************
* (c) Copyright 2011 Biricha Digital Power Limited
* DATEI : main.c
* AUTOR : Dr. A. Shirsavar / Dr. C. Hossack
* PROJEKT : Piccolo A DPCM
* Zielsystem : MCU C2802x
* ERSTELLUNGSDATUM : 14.11.2011
* COPYRIGHT : Copyright Biricha Digital Power Limited 2011
* Alle Rechte vorbehalten. Eine vollständige oder teilweise Vervielfältigung
* ist untersagt, sofern keine ausdrückliche schriftliche
* Genehmigung des Inhabers der Urheberrechte vorliegt.
* BESCHREIBUNG :
*
* In diesem Projekt wird die spitzenstromgeführte Regelung eines BDP-105-Abwärtswandler-Boards
* mit einem Mikrocontroller Piccolo A von Texas Instruments vorgeführt.
*
* Auf der MCU wird ein 2p2z-Controller (2 Pole, 2 Nullstellen) ausgeführt und es wird ein Anstiegsausgleich
* zur Beseitigung von subharmonischen Schwingungen realisiert. Der Komparator 2 der Piccolo-MCU wird zur Erkennung
* des Spitzenstrom-Sollwerts verwendet.
*
* Die Phasen- und Verstärkungsreserve der digitalen Stromversorgungseinheit wurden mit einem
* Frequenzantwort-Analysator gemessen:
*
* Phasenreserve = 65°
* Durchtrittsfrequenz = 10 kHz
* Schaltfrequenz = 200 kHz
*
* WICHTIG: Das Board BDP-105 sollte an Port 1 der Tochterkarte angeschlossen werden.
* Der Schaltstrom IL muss an den nicht-invertierenden Pin des Komparators
* der Piccolo-MCU angeschlossen werden. Diese Verbindung ist auf der Tochterkarte nicht implementiert.
* Daher muss eine Verbindungsleitung vom IL-Pin der Tochterkarte
* (d. h. A/D-Wandler-Pin B0) zum nicht-invertierenden Pin des Komparators 2 (d. h. A/D-Wandler-Pin A4) verlegt werden.
* Fragen Sie einen Referenten nach einer Verbindungsleitung und richten Sie die Verbindung ein.
*
* LINKS
* file:///C:/tidcs/c28/CSL_C2802x/v100/doc/CSL_C2802x.pdf
******************************************************************************/

/****************************** ABSCHNITT MIT #include-DIREKTIVEN *****************************/

typedef unsigned int Uint16;
typedef unsigned long Uint32;
#include "DSP2802x_Comp.h"
#include "DSP2802x_EPwm.h"
#include "csl.h"

/**************************** ABSCHNITT MIT DEKLARATIONEN ***************************/

/* Einrichten der Koeffizienten für den 2p2z-Controller des Abwärtswandlers BDP-105
* mit einer Schaltfrequenz von 200 kHz und einer Durchtrittsfrequenz von 10 kHz
*/

#define K (54.3563)
#define REF (_IQ15toF(2048))
#define MIN_DUTY 0
#define MAX_DUTY 65535
#define A1 +1.8069498069
#define A2 -0.8069498069
#define B0 +1.1409584360
#define B1 +0.0695049698
#define B2 -1.0714534663

#define PERIOD_NS 5000 /*Unsere Periodendauer in ns für fs = 200kHz*/

/************************** ABSCHNITT NACH DEKLARATIONEN ************************/

/* Datenabgleich mit Speicher vor Instanziierung eines 2p2z-Controllers. */
#pragma DATA_ALIGN ( MyCntrl , 64 );

/* Dadurch wird ein 2p2z-Controller namens MyCntrl deklariert*/
CNTRL_2p2zData MyCntrl;

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// GLOBAL VARIABLES
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
uint16_t slope;

/******************************************************************************
* FUNKTION : IsrAdc
* BESCHREIBUNG :
* Dieser Interrupt wird aufgerufen, wenn die Ablaufsteuerung des A/D-Wandlers das Abtasten beendet hat.
******************************************************************************/
interrupt void IsrAdc( void )
{

/* Setzen des GPIO-Pins 12, der mit Testpin TZ auf der Hardware verbunden ist*/
GPIO_set( GPIO_12);

/* Bestätigen der Gruppe und des Interrupts ADC SEQ. Reaktivierung der A/D-Wandler-Interrupts -Int1*/
ADC_ackInt( ADC_INT_1 );

/* Mit diesen drei Zeilen wird der A/D-Wandler gelesen, der 2p2z-Controller aufgerufen und dann
* der Lastzyklus entsprechend aktualisiert.
*/
MyCntrl.Fdbk.m_Int = ADC_getValue(ADC_MOD_1);
CNTRL_2p2z(&MyCntrl);

/* Speist den „anfänglichen" geforderten Stromwert (vom 2p2z-Controller)
* in den D/A-Wandler des Komparators, d. h. den geforderten Strom, bevor
* der Anstiegsausgleich am invertierenden Pin des auf dem Board integrierten
* Komparators 2 anliegt. Der Anfangswert des D/A-Wandlers wird später vom Zähler des Anstiegsausgleichs-Algorithmus
* des D/A-Wandlers aktualisiert.
*/
CMP_setRampMax( CMP_MOD_2, MyCntrl.Out.m_Int );

/* Löschen von GPIO-Pin 12*/
GPIO_clr( GPIO_12);

/* Einrichten des Softstarts*/
CNTRL_2p2zSoftStartUpdate(&MyCntrl);
}

/******************************************************************************
* FUNKTION : main
* BESCHREIBUNG :
*
******************************************************************************/
void main( void )
{
/* Initialisieren von MCU, A/D-Wandler und GPIO12*/
SYS_init();
ADC_init();
GPIO_config( GPIO_12, GPIO_DIR_OUT, false );

/* Setzen von PWM_MOD_1 auf fs = 200 kHz. „PWM1 Ch A" wird für das Schalten
* des Wandlers verwendet. „PWM1 Ch B" wird für Timing-Zwecke verwendet. Später mehr
* dazu.
*/
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 );

/* Für eine digitale, stromgeführte Regelung wird die Last von PWM-Kanal A typischerweise auf 100 % gesetzt.
* Anschließend wird die zyklische Auslösefunktion dazu verwendet, den PWM-Pin auf Low-Pegel zu setzen,
* sobald der Strom den geforderten Spitzenwert erreicht. Aus Sicherheitsgründen haben wir hier allerdings
* die maximale Last auf 60 % gesetzt, d. h. wenn Ihr Regelalgorithmus fehlschlägt, wird der PWM
* nach 60 % zurückgesetzt, statt 100 % zu halten.
*/
PWM_setDutyA(PWM_MOD_1, PWM_nsToTicks(PERIOD_NS)*0.6 );

/* PWM1-Kanal A wird für die PWM-Ansteuerung des MOSFETs verwendet. Daher müssen
* die Abtastung, die Umwandlung, die A/D-Wandler-Interrupt-Eingabe, der 2p2z-Controller, der Verstärkungswert, der D/A-Wandler und
* der Komparator noch eingerichtet werden, bevor PWM1-Kanal A in den High-Pegel wechselt. Somit wird also
* der PWM1-Kanal B für das Starten des Abtastvorgangs verwendet. Die fallende Flanke
* von PWM1-Kanal B wird für das Starten des Abtastvorgangs verwendet.
* Danach folgen alle relevanten Berechnungen. Daher sollte die Last von Kanal B so gesetzt werden, dass
* alle Abtastvorgänge und Berechnungen abgeschlossen werden, noch bevor der PWM1-Kanal A in den High-Pegel wechselt.
* Hierfür wurden mit dem Oszilloskop 2,45 µs gemessen.
*
* <---PERIOD_NS-->
* ___ ___
* PWM A: _______| |___________| |___________|
*
* PERIOD_NS-2450
* ________<-----> ________
* PWM B: _______| |______| |______|
* ^ ^
* Hier löst PWM B den ADC SOC aus^ ^ Hier startet PWM B den CLA-Anstiegsausgleich
* Diese fallende Flanke muss so für den nächsten
* angepasst werden, Zyklus
* dass alle Berechnungen abgeschlossen sind,
* bevor der nächste Zyklus beginnt
* (d. h. vor der nächsten ansteigenden Flanke).
*/

/* Mit dieser Funktion wird der PWM1-Kanal B so eingerichtet, dass Berechnungen
* genau vor der Anstiegsflanke PWM B abgeschlossen sind. PERIOD_NS ist die Periodendauer
* und hier auf 5000 ns gesetzt. Daher setzen wir die Impulsbreite hier auf (5000–2450) ns.
*/
PWM_setDutyB(PWM_MOD_1, PWM_nsToTicks( PERIOD_NS-2500 ) );

/* Legt „PWM Mod1" so fest, dass die A/D-Wandlung immer dann beginnt,
* wenn der Timebase-Zähler von PWM1-Kanal B mit der Last von Kanal B übereinstimmt, d. h. wenn die fallende Flanke
* von PWM-Kanal B ADC SoC auslöst, wie oben beschrieben.
*/
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 Timebase-Zähler = 0. Die „0" anstelle einer ISR-Funktion bedeutet,
* dass ein Interrupt erzeugt wird, aber nicht zur ISR-Funktion gewechselt wird.
* Der CLA erkennt diesen Interrupt und führt stattdessen den CLA-Code aus. Zu guter Letzt
* gibt PWM_INT_PRD_1 an, dass ein Interrupt in jedem Zyklus erzeugt werden soll
* statt in jedem zweiten Zyklus.
*/
PWM_setCallback(PWM_MOD_1, 0, PWM_INT_ZERO, PWM_INT_PRD_1 );

/* Speist das Ausgangssignal von Komparator Mod2 in PWM Mod1
* und aktiviert das Austasten durch Setzen des digitalen Compare-Ereignisses
* PWM_DCEVT zum richtigen Zeitpunkt. Hier wird PWM_DCEVT später zum Auslösen von
* PWM verwendet.
* Der Eingang zum Austastblock ist nicht-invertierend und mit „true" ist sichergestellt,
* dass der Ausgang nicht mit dem Timebase-Takt des PWM
* synchronisiert wird.
*/
PWM_configBlanking( PWM_MOD_1, PWM_CMP_COMP2, GPIO_NON_INVERT, true );

/* Setzen der Dauer des Austastfensters auf 420 ns*/
PWM_setBlankingWindow( PWM_MOD_1, PWM_nsToTicks(420) );

/* setzt die relevanten Auslösezonen: D. h. wenn PWM_DCEVT eintritt,
* wird PWM1-Kanal A zyklisch gelöscht, aber es gibt keine Auswirkungen auf PWM1-Kanal B.
* PWM_DCEVT wurde in PWM_configBlanking() eingerichtet.
*/
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 );

/* Konfigurieren des A/D-Wandlers für das Abtasten von Vo, wenn dieser von der fallenden Flanke von PWM1-Kanal B ausgelöst wird
*/
ADC_config( ADC_MOD_1, ADC_SH_WIDTH_7, ADC_CH_B2, ADC_TRIG_EPWM1_SOCB );

/* Wenn Umwandlung abgeschlossen, Interrupt aufrufen und zu „IsrAdc" wechseln.*/
ADC_setCallback( ADC_MOD_1, IsrAdc, ADC_INT_1 );

/* Initialisieren der 2p2z-Regelstruktur (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
);

/* Konfigurieren des Komparators Mod2 ohne Qualifizierungsfenster,
* d. h. asynchron. Der Komparatorausgang ist nicht-invertierend und der invertierende
* Eingang des Komparators ist an den internen D/A-Wandler angebunden.
*/
CMP_config( CMP_MOD_2, CMP_ASYNC, GPIO_NON_INVERT, CMP_DAC );

/* Zähler-Submodul des D/A-Wandlers wird konfiguriert
* Dadurch wird ein Anstieg auf dem Stromreferenzsignal anhand einer
* digitalen Treppenkurve erzeugt.
*/
CMP_rampConfig( CMP_MOD_2, PWM_MOD_1 );
decval = CMP_calcRampDec( CMP_mVtoRampValue(124), PWM_freqToTicks(200000) );
CMP_setRampDec( CMP_MOD_2, decval );

/* Einrichten eines 500-ms-Softstarts*/
CNTRL_2p2zSoftStartConfig(&MyCntrl, 500, PERIOD_NS );

/* Aktivieren globaler Interrupts und Warten in Leerlaufschleife*/
INT_enableGlobal(true);

while(1)
{

}
}

Anbieter zum Thema

zu Matchmaker+

  1. Implementierung eines digitalen Schaltreglers
  2. Verstärkungsfaktor bestimmen
  3. Literatur
  4. Quellcode für ControlSuite von Texas Instruments
  5. Quellcode für CSL von Biricha Digital Power

Lesen Sie mehr zum Thema


Das könnte Sie auch interessieren

Jetzt kostenfreie Newsletter bestellen!

Weitere Artikel zu DC/DC-Wandler