TI中文支持网
TI专业的中文技术问题搜集分享网站

28335编程时遇到的一些问题,求助各位大神。

以下是程序,程序运行后,发现GPIO32口,每1us翻转一次,翻转40次,然后10us执行update_compare程序。

程序目的,每50us改变一次PWM输出(全桥逆变移相控制100kHZ)。

疑惑的是:1,为什么每1us翻转,这相当于2个周期采样一次吧?哪里设置了?从ADCSOC.c 改官方程序修改。

2,全桥逆变后面接的是RLC串联电路,谐振运行,R上得到最大电压。通过移相PWM调整电流恒定。但示波器检测出来的R上的电压波形来计算电流值,会发现明明想要比较的是电流有效值,但是出来的是幅值和设定值一样。

#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "math.h"

typedef struct
{
volatile struct EPWM_REGS *EPwmRegHandle;

}EPWM_INFO;

#define ADC_usDELAY 5000L

// Prototype statements for functions found within this file.
void InitEPwm1Example(void);

void Gpio_select(void);
void update_compare(EPWM_INFO*);
void InitEPwm1Gpio(void);
interrupt void adc_isr(void);

// General System nets – Useful for debug

EPWM_INFO epwm1_info;

// Configure the period for each timer
#define EPWM1_TIMER_TBPRD 750 // Period register
#define EPWM1_CMPA 0

// To keep track of which way the compare value is moving
#define EPWM_CMP_UP 1
#define EPWM_CMP_DOWN 0

// ADC start parameters
#define CPU_FRQ_150MHZ 1
// #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
// #define ADC_CKPS 0x0 // ADC module clock = HSPCLK/1 = 25.5MHz/(1) = 25.0 MHz
// #define ADC_SHCLK 0x1 // S/H width in ADC module periods = 2 ADC cycle
float a=0;
float kp=30;
float kiT=25;

Uint16 EPwmMaxCMPA;
Uint16 LoopCount;
Uint16 ConversionCount;
float current0[10];

float current_math[10];
float max_current;
float u[2];
float e[2];
float u_change;
float N=10;

void main(void)
{
Uint16 i;

InitSysCtrl();
Gpio_select();

EALLOW;
// Default – 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
EDIS;

EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK;
EDIS;

InitEPwm1Gpio();

DINT;

InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

InitPieVectTable();

EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

InitAdc();

// Enable ADCINT in PIE
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM

LoopCount = 0;
ConversionCount = 0;
e[0]=0;
e[1]=0;
u[0]=0;
u[1]=0;
max_current=0;
GpioDataRegs.GPBSET.all =0x00000000;
GpioDataRegs.GPBCLEAR.all =0x00000001;

// For this example, only initialize the ePWM
// Step 5. User specific code, enable interrupts:
for (i=0; i<N; i++)
{
current0[i] =0;

}

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm1Example();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;

// Configure ADC
AdcRegs.ADCMAXCONV.all = 0x0000; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA0 as 1st SEQ1 conv.

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

// Assumes ePWM2 clock is already enabled in InitSysCtrl();
EPwm2Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm2Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount
EPwm2Regs.ETPS.bit.SOCAPRD = 3; // Generate pulse on 1st event
EPwm2Regs.CMPA.half.CMPA = 10; // Set compare A value
EPwm2Regs.TBPRD =25; // Set period for ePWM1
EPwm2Regs.TBCTL.bit.CTRMODE =0; // count up and start

// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
asm(" NOP");
}

}

interrupt void adc_isr(void)
{

current0[ConversionCount] = AdcRegs.ADCRESULT0 >>4;
GpioDataRegs.GPBTOGGLE.all =0x00000001;

// If 40 conversions have been logged, start over
if(ConversionCount ==N-1 )
{
ConversionCount = 0;
LoopCount++;
}
else ConversionCount++;

if (LoopCount==4)
{update_compare(&epwm1_info);}

// Reinitialize for next ADC sequence
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE

// return;
}

void InitEPwm1Example()
{

// Setup TBCLK
EPwm1Regs.TBPRD =750;
//EPwm1Regs.TBPRD=EPWM1_TIMER_TBPRD; // Set timer period 801 TBCLKs
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter

// Set Compare values
EPwm1Regs.CMPA.half.CMPA =40;
// EPwm1Regs.CMPA.half.CMPA =EPWM1_CMPA; // Set compare A value
EPwm1Regs.CMPB =710;
//EPwm1Regs.CMPB =EPWM1_TIMER_TBPRD-EPWM1_CMPA; // Set Compare B value

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Phase loading disabled
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

// Setup shadowing
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;

// Information this example uses to keep track
// of the direction the CMPA/CMPB values are
// moving, the min and max allowed values and
// a pointer to the correct ePWM registers

epwm1_info.EPwmRegHandle = &EPwm1Regs; // Set the pointer to the ePWM module

}

void update_compare(EPWM_INFO *epwm_info)
{

int i;
max_current=0;

for (i=0; i<N; i++)
{ current_math[i]= (current0[i]-2274)/4096*3/0.2;  

//  用0.01欧姆采样电流,放大20倍,输出电压共模信号1.655V,调整后可得到检测的电流值

//  放大器400KHZ的时候会-3dB,但是信号不是100KHz,每周期采样10个么?没有影响啊。
max_current=max_current+fabs(current_math[i]);    //  10个电流值的绝对值进行求和

}
max_current=1.1107*max_current/N;        //  求平均,然后乘以一个系数,将其转化为有效值。大约为1.1107倍。

e[1]=1-max_current;  

//   转化的有效值进行求差,后面的是增量式PI算法。  目的是得到有效值为1A的电流,但是检测出来的波形为1A幅值的电流。1.1107这个系

//  数算了很多遍,没错啊。正弦波的绝对值的平均值为幅值的0.6366倍,正弦波的有效值为0.7071倍幅值,那么有效值就是1.1107倍平均值啊。  

u_change=kp*(e[1]-e[0])+kiT*e[1];
u[1]=u[0]+u_change/180*750;
if (u[1]>738) { u[1]=738;}
if (u[1]<12) { u[1]=12; }
EPwmMaxCMPA=u[1]/2;
epwm_info->EPwmRegHandle->CMPA.half.CMPA=EPwmMaxCMPA;
epwm_info->EPwmRegHandle->CMPB=750-EPwmMaxCMPA;
u[0]=u[1];
e[0]=e[1];
max_current=0;
LoopCount=0;
// return;
}

void Gpio_select(void)
{

EALLOW;
GpioCtrlRegs.GPBMUX1.all = 0x00000000; // All GPIO
GpioCtrlRegs.GPBMUX2.all = 0x00000000; // All GPIO
GpioCtrlRegs.GPBDIR.all = 0x0000000F; // All outputs
EDIS;

}

//===========================================================================
// No more.
//===========================================================================

赞(0)
未经允许不得转载:TI中文支持网 » 28335编程时遇到的一些问题,求助各位大神。
分享到: 更多 (0)