Part Number: TMS320F280049
Tool/software: Code Composer Studio
Hello everyone,
i'm just programming a simple EPWM which triggers the ADC when CMPA is reached.
The code bases on the driverlib ADC example.
The sample and hold time is only one zyklus for testing.
When the interrupt occures the register TBPRD has the number 5050 instead of 5000 or 300 instead of 250. The SYSCLK is 100MHz.
I hope you will understand my problem. Thanks.
#include "driverlib.h"
#include "device.h"
#include "main.h"
//
// Defines
//
#define EPWM1_TIMER_TBPRD 10000U
#define EPWM1_CMPA 5000U
#define EPWM_CMP_UP 1U
#define EPWM_CMP_DOWN 0U
//Define Outputs
#define DEVICE_GPIO_PIN_DRIVER1 10U
#define DEVICE_GPIO_PIN_DRIVER2 11U
#define DEVICE_GPIO_PIN_ANALOGCONT 12U
#define DEVICE_GPIO_PIN_COMPROGDIS 13U
#define DEVICE_GPIO_PIN_COMPSHUNTDIS 17U
//Define Inputs
#define DEVICE_GPIO_PIN_PWMCONTSHUNT 16U
#define DEVICE_GPIO_PIN_PWMCONTROG 6U
//
// Defines
//
#define RESULTS_BUFFER_SIZE 256
//
// Globals
//
uint16_t adcAResults[RESULTS_BUFFER_SIZE]; // Buffer for results
uint16_t index; // Index into result buffer
volatile uint16_t bufferFull; // Flag to indicate buffer is full
void initEPWM1(void);
void initADC(void);
void initADCSOC(void);
__interrupt void adcA1ISR(void);
void main(void)
{
// Initialize device clock and peripherals
Device_init();
// Initialize GPIO and configure the GPIO pin as a push-pull output
Device_initGPIO();
GPIO_setPadConfig(24U, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(24U, GPIO_DIR_MODE_OUT);
//Initialize PWM
GPIO_setPadConfig(0U, GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_0_EPWM1A);
//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
Interrupt_register(INT_ADCA1, &adcA1ISR);
//init ADC and power it up; init EPWM
initADC();
//
// Disable sync(Freeze clock to PWM as well)
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
initEPWM1();
//
// Enable sync and clock to PWM
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
initADCSOC();
for(index = 0; index < RESULTS_BUFFER_SIZE; index++)
{
adcAResults[index] = 0;
}
index = 0;
bufferFull = 0;
//
// Enable ADC interrupt
//
Interrupt_enable(INT_ADCA1);
EINT;
ERTM;
// Loop Forever
for(;;)
{
EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
//EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_B);
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
}
}
void initEPWM1()
{
//
// Disable SOCA
//
EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
//
// Configure the SOC to occur on the first up-count event
//
EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1);
//
// Set-up TBCLK
//
EPWM_setTimeBasePeriod(EPWM1_BASE, EPWM1_TIMER_TBPRD);
EPWM_setTimeBaseCounter(EPWM1_BASE, 0U);
//
// Set Compare values
//
EPWM_setCounterCompareValue(EPWM1_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM1_CMPA);
//
// Set up counter mode
//
EPWM_setClockPrescaler(EPWM1_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
//
// Set up shadowing
//
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
//
// Set actions
//
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
}
void initADC()
{
//
// Setup VREF as internal
//
ADC_setVREF(ADCA_BASE, ADC_REFERENCE_EXTERNAL, ADC_REFERENCE_3_3V);
//
// Set ADCCLK divider to /4
//
ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_2_0); //50Mhz Clock (100Mhz/2)
//
// Set pulse positions to late
//
ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
//
// Power up the ADC and then delay for 1 ms
//
ADC_enableConverter(ADCA_BASE);
DEVICE_DELAY_US(1000);
}
void initADCSOC(void)
{
//
// Configure SOC0 of ADCA to convert pin A0 with a sample window of 11
// SYSCLK cycles. The EPWM1SOCA signal will be the trigger.
//
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA,
ADC_CH_ADCIN0, 1);
//
// Set SOC0 to set the interrupt 1 flag. Enable the interrupt and make
// sure its flag is cleared.
//
ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
}
__interrupt void adcA1ISR(void)
{
//
// Add the latest result to the buffer
//
GPIO_togglePin(24U);
// adcAResults[index++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
//
// Set the bufferFull flag if the buffer is full
//
if(RESULTS_BUFFER_SIZE <= index)
{
index = 0;
bufferFull = 1;
}
//
// Clear the interrupt flag
//
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
//
// Check if overflow has occurred
//
if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1))
{
ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
}
//
// Acknowledge the interrupt
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
Green PWM
BLUE TOGGLE PIN inside of ISR

