Part Number:TMS320F28335
Tool/software: Code Composer Studio
Dear Sir,
I want to read data from ADC using epwm1a interrupt and log the data in VG and IG variables. Later I want to use this data in the CPU timer interrupt for every 50us. Problem is without connecting anything to my DSP, I am getting some random data in both the channels. The first channel is giving some consistent values but the second channel is giving sinusoidally varying random data. Please tell me whether is it the problem with the ADCs in my DSP or am I doing anything wrong. One more doubt is I have written the program for hysteresis control please check whether I am doing right or wrong and please suggest me if I am doing wrong. Please find the code attached.
//###########################################################################
//
// FILE: Example_2833xAdcSoc.c
//
// TITLE: ADC Start of Conversion Example
//
//! \addtogroup f2833x_example_list
//! <h1> ADC Start of Conversion (adc_soc)</h1>
//!
//! This ADC example uses ePWM1 to generate a periodic ADC SOC on SEQ1.
//! Two channels are converted, ADCINA3 and ADCINA2.
//!
//! \b Watch \b Variables \n
//! - Voltage1[10] - Last 10 ADCRESULT0 values
//! - Voltage2[10] - Last 10 ADCRESULT1 values
//! - ConversionCount - Current result number 0-9
//! - LoopCount - Idle loop counter
//
//###########################################################################
// $TI Release: F2833x Support Library v2.00.00.00 $
// $Release Date: Tue Jun 26 03:14:14 CDT 2018 $
// $Copyright:
// Copyright (C) 2009-2018 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################
//
// Included Files
//
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include<IQmathLib.h>
#include<math.h>
//
// Function Prototypes
//
__interrupt void adc_isr(void);
__interrupt void cpu_timer0_isr(void);
void InitEPwm1Example(void);
void Gpio_setup1(void);
DCL_PI piVdc=PI_DEFAULTS;
float32_t PI=2.0f*3.141592f;
float32_t input1, sin_out1,input2, sin_out2;
long GlobalQ=GLOBAL_Q;
float32_t a1,b1,c1,a2,b2,c2;float theta=0.0f;//float deltheta=0.31415926f;
//float deltheta=(float)(1.8f*PI/180);
//float deltheta=0.031415f; \\for 10khz
float32_t deltheta=0.015707f;float32_t phase=0.0f;float32_t m=1.0f;
int prestate=0;int postate=0;int count=0;int v1[400];
int offset=1837;
float32_t dqgain=0.666667f;
float32_t ggain=0.5f;
float32_t Vm=12.0f;//Vmax 10 Volts
float32_t offtrim=1.4434f;
float32_t ft=0.0025f;//ft=(frequency)/(Switching frequency);
float32_t ramp;
float32_t vg,ig;
float32_t Iaref,VDref,VQref,VZref, VgD,VgQ,VgZ;
float32_t ukD,ukQ,ukZ,ukIg;
float32_t error1,error2,error3;
float32_t Vavg,Iavg;float32_t Vsum,Isum;
//
// Globals
//
Uint16 LoopCount;
Uint16 ConversionCount;float32_t Vdcact;
int VG[400],IG[400],Vdc[400];
float32_t igact,Vdcact;float32_t ILref;float32_t vsum=0.0f;float32_t vavg;
float32_t Vdcref=50.0f;float32_t eps;float32_t h1=0.1f,h2=0.1f;
float32_t a[400];Uint16 duty[400];int swap,swan,swbp,swbn;
int sw;
//
// Main
//
void main(void)
{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
//
InitSysCtrl();
EALLOW;
#if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT
//
// HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
//
#define ADC_MODCLK 0x5
#endif
#if (CPU_FRQ_100MHZ)
//
// HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
//
#define ADC_MODCLK 0x2
#endif
EDIS;
//
// Define ADCCLK clock frequency ( less than or equal to 25 MHz )
// Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz
//
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK;
EDIS;
//
// Step 2. Initialize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
//
// InitGpio(); // Skipped for this example
//
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
//
DINT;
//
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
//
InitPieCtrl();
//
// Disable CPU interrupts and clear all CPU interrupt flags:
//
IER = 0x0000;
IFR = 0x0000;
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
//
InitPieVectTable();
//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.ADCINT = &adc_isr;
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
InitCpuTimers(); // For this example, only initialize the Cpu Timers
#if (CPU_FRQ_150MHZ)
//
// Configure CPU-Timer 0 to interrupt every 500 milliseconds:
// 150MHz CPU Freq, 50 millisecond Period (in uSeconds)
//
ConfigCpuTimer(&CpuTimer0, 150, 50);
#endif
#if (CPU_FRQ_100MHZ)
//
// Configure CPU-Timer 0 to interrupt every 500 milliseconds:
// 100MHz CPU Freq, 50 millisecond Period (in uSeconds)
//
ConfigCpuTimer(&CpuTimer0, 100, 500000);
#endif
CpuTimer0Regs.TCR.all = 0x4000;
//
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
//
// InitPeripherals(); // Not required for this example
InitAdc(); // For this example, init the ADC
Gpio_setup1();
InitEPwm1Example();
//
// Step 5. User specific code, enable interrupts:
//
//
// Enable ADCINT in PIE
//
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
LoopCount = 0;
ConversionCount = 0;
//
// Configure ADC
//
AdcRegs.ADCMAXCONV.all = 0x0002; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // Setup ADCINA3 as 1st SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // Setup ADCINA2 as 2nd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x1;
//
// Enable SOCA from ePWM to start SEQ1
//
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
for(;;)
{
LoopCount++;
}
}
//
// adc_isr -
//
__interrupt void adc_isr(void)
{
VG[ConversionCount] = (AdcRegs.ADCRESULT0 >>4);
//VG[ConversionCount] = (AdcRegs.ADCRESULT1 >>4);
IG[ConversionCount]=(AdcRegs.ADCRESULT1 >>4);
a[ConversionCount]=(float32_t)(VG[ConversionCount]*0.000732600f);
//Vdcact=(float)(((float)(Vdc[ConversionCount])*(0.000732600f))-1.5093f)*169.0f;
igact=(float32_t)(IG[ConversionCount]*(0.000732600f));
vsum=vsum+a[ConversionCount];
if(ConversionCount == 400)
{
ConversionCount = 0;
vavg=vsum*0.0025f;
vsum=0.0f;
}
else
{
ConversionCount++;
}
//
// 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;
}
__interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
postate=GpioDataRegs.GPADAT.bit.GPIO24;
if (postate>prestate){
theta=0.0f;
GpioDataRegs.GPATOGGLE.bit.GPIO30 = 1;
}
prestate=postate;
ramp=count*ft;
theta=ramp*PI;
eps=(float32_t)(m*a[ConversionCount]-igact);
if (eps>=h1){
swap=1;swan=0;
swbp=0;swbn=1;
}
else if(eps<-h2){
swap=0;swan=1;
swbp=1;swbn=0;
}
GpioDataRegs.GPADAT.bit.GPIO11=swap;
GpioDataRegs.GPADAT.bit.GPIO12=swan;
GpioDataRegs.GPADAT.bit.GPIO13=swbp;
GpioDataRegs.GPADAT.bit.GPIO14=swbn;
// sw=8*swbn+4*swbp+2*swan+1*swap;
// GpioDataRegs.GPBDAT.all=sw;
count=count+1;
theta=theta+deltheta;
if (count==400){
count=0;
}
//
// Acknowledge this interrupt to receive more interrupts from group 1
//
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void Gpio_setup1(void){
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pullup on GPIO0
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // Enable pullup on GPIO1
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0 = PWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // GPIO1 = PWM1B
GpioCtrlRegs.GPADIR.bit.GPIO24=0; // For synchronous pulse read
GpioCtrlRegs.GPAMUX2.bit.GPIO24=0;
GpioCtrlRegs.GPAPUD.bit.GPIO24=0;
GpioCtrlRegs.GPAQSEL2.bit.GPIO24=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO11=0;
GpioCtrlRegs.GPADIR.bit.GPIO11=1;
GpioDataRegs.GPADAT.bit.GPIO11=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
GpioCtrlRegs.GPADIR.bit.GPIO12=1;
GpioDataRegs.GPADAT.bit.GPIO12=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO13=0;
GpioCtrlRegs.GPADIR.bit.GPIO13=1;
GpioDataRegs.GPADAT.bit.GPIO13=0;
GpioCtrlRegs.GPAMUX1.bit.GPIO14=0;
GpioCtrlRegs.GPADIR.bit.GPIO14=1;
GpioDataRegs.GPADAT.bit.GPIO14=0;
GpioCtrlRegs.GPAMUX2.bit.GPIO30=0;// C group pin for zero crossing detection
GpioCtrlRegs.GPADIR.bit.GPIO30=0;
EDIS;
}
void InitEPwm1Example(void)
{
//
// Setup TBCLK
//
//EPWM1 A and B are GPIO 0 and 1
EPwm1Regs.TBCTL.bit.CTRMODE = 2; // Count up down
EPwm1Regs.TBPRD = 1875; // Set timer period
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 001; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = 000;
EPwm1Regs.TBCTL.bit.SYNCOSEL=1;
EPwm1Regs.CMPA.half.CMPA =937; // Set compare A value
EPwm1Regs.CMPB = 937; // Set Compare B value
EPwm1Regs.DBCTL.bit.OUT_MODE=3;
EPwm1Regs.DBCTL.bit.POLSEL=2;
EPwm1Regs.DBCTL.bit.IN_MODE=0;
EPwm1Regs.DBRED=20;
EPwm1Regs.DBFED=20;
EPwm1Regs.AQCTLA.bit.CAU=2; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAD=1;
EPwm1Regs.AQCTLB.bit.CBU=2;
EPwm1Regs.AQCTLB.bit.CBD=1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
}
//
// End of File
//