Hi all,
I wish to use the PWM port (not HRPWM) as a DAC with 10 MHz conversion rate. So I set the time-based period of ePWM 6 to 14 (The CPU frequency is set to 150MHz) to generate a 10MHz PWM signal. And the CPU timer 0 with 0.1us (10MHz) isr is set to change the duty cycle of the PWM. The detail program is shown as following. But when I run this program and check the output waveform using DSO. The frequency of the EPWM signal is right, but the duty cycle changes every 4 PWM duration (0.25 us) rather than every PWM duration (0.1us). Is anything wrong? thanks in advance for your help.
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#define EPwm6_TIMER_TBPRD 14
#define Epwm_Interpt 0
#define CPU_Int 1
interrupt void Epwm6_isr(void);
interrupt void cpu_timer0_isr(void);
Uint16 Sine_Table[2]={1,7};
Uint16 Bcnt;
void InitEPwm6();
void main(void)
{
Bcnt=0;
InitSysCtrl();
// Step 2. Initalize 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
// For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
// These functions are in the DSP2833x_EPwm.c file
InitEPwm6Gpio();
// 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();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
InitEPwm6();
asm(" EALLOW"); // Enable EALLOW protected register access
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // HSPCLK to ePWM modules enabled
asm(" EDIS"); // Disable EALLOW protected register access
EALLOW; // This is needed to write to EALLOW protected registers
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
ConfigCpuTimer(&CpuTimer0, 150, 0.1);
CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
// Enable CPU INT1 which is connected to CPU-Timer 0:
IER |= M_INT1;
// Enable TINT0 in the PIE: Group 1 interrupt 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
asm(" NOP");
}
}
interrupt void cpu_timer0_isr(void)
{
EPwm6Regs.CMPB =Sine_Table[Bcnt];
Bcnt++;
Bcnt &= 0x01;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void InitEPwm6()
{
// Proceed with the register configurations
EPwm6Regs.TBCTL.all = 0xC003; // Configure timer control register
// bit 15-14 11: FREE/SOFT, 11 = ignore emulation suspend
// bit 13 0: PHSDIR, 0 = count down after sync event
// bit 12-10 000: CLKDIV, 000 => TBCLK = HSPCLK/1
// bit 9-7 000: HSPCLKDIV, 000 => HSPCLK = SYSCLKOUT/1
// bit 6 0: SWFSYNC, 0 = no software sync produced
// bit 5-4 00: SYNCOSEL, 11 = sync-out disabled
// bit 3 0: PRDLD, 0 = reload PRD on counter=0
// bit 2 0: PHSEN, 0 = phase control disabled
// bit 1-0 11: CTRMODE, 11 = timer stopped (disabled)
EPwm6Regs.TBCTR = 0x0000; // Clear timer counter
EPwm6Regs.TBPRD = EPwm6_TIMER_TBPRD; // Set timer period
EPwm6Regs.TBPHS.all= 0x0000L; // Set timer phase
EPwm6Regs.CMPCTL.all = 0x0000; // Compare control register
EPwm6Regs.CMPCTL.bit.LOADBMODE = 1; // Compare control register
// bit 15-10 0's: reserved
// bit 9 0: SHDWBFULL, read-only
// bit 8 0: SHDWAFULL, read-only
// bit 7 0: reserved
// bit 6 0: SHDWBMODE, 0 = shadow mode, 1 = immediate mode
// bit 5 0: reserved
// bit 4 0: SHDWAMODE, 0 = shadow mode, 1 = immediate mode
// bit 3-2 00: LOADBMODE, don't care
// bit 1-0 01: LOADAMODE, 01 = load on CNT=PRD
// Set actions
EPwm6Regs.AQCTLB.all = 0x0102;
// bit 15-12 0000: reserved
// bit 11-10 00: CBD --
// bit 9-8 00: CBU \ 00 = do nothing
// bit 7-6 00: CAD \______ 01 = clear
// bit 5-4 10: CAU | 10 = set
// bit 3-2 00: PRD |
// bit 1-0 01: ZRO --
EPwm6Regs.AQSFRC.all = 0x0000; // Action-qualifier s/w force register
// bit 15-8 0's: reserved
// bit 7-6 00: RLDCSF, 00 = reload AQCTLx on zero
// bit 5 0: OTSFB, 0 = do not initiate a s/w forced event on output B
// bit 4-3 00: ACTSFB, don't care
// bit 2 0: OTSFA, 0 = do not initiate a s/w forced event on output A
// bit 1-0 00: ACTSFA, don't care
EPwm6Regs.AQCSFRC.all = 0x0000; // Action-qualifier continuous s/w force register
// bit 15-4 0's: reserved
// bit 3-2 00: CSFB, 00 = forcing disabled
// bit 1-0 00: CSFA, 00 = forcing disabled
// Configure the Deadband and Trip Zone modules
// EPwm6Regs.DBCTL.bit.IN_MODE = 0; // Deadband disabled
// EPwm6Regs.DBCTL.bit.OUT_MODE = 0; // Deadband disabled
// EPwm6Regs.PCCTL.bit.CHPEN = 0; // PWM chopper unit disabled
// EPwm6Regs.TZCTL.bit.TZA = 0x3; // Trip action disabled for output A
// EPwm6Regs.TZCTL.bit.TZB = 0x3; // Trip action disabled for output B
EPwm6Regs.CMPB=7;
EPwm6Regs.TBCTL.bit.CTRMODE = 0x0; // Enable the timer in count-up mode
InitEPwm6Gpio();
}
Regard,
Morris