I am using a PWM signal with 200us period(5kHz). The duty cycle is updated using the timer1 interrupt to generate a sine wave when connected to an H-bridge and an LC-Filter. I do 100 Updates (100 sine values). Also I am using ADC to read the voltage from the pin, which is triggered with PWM1 Primary time base. The ADC and PWM should have the same frequency but the ADC is working faster than needed. In other words, it is reading 2 periods instead of only one. I did not know what to change in the configuration to be able to read only one complete Sine wave instead of two. The attached image will explain the problem more:
ADC PWM Configuration:
void PWM_Initialize (void)
{
// PCLKDIV 1;
PTCON2 = 0x00;
// PTPER 12160;
PTPER = 0x2F80;
// SEVTCMP 0;
SEVTCMP = 0x00;
// MDC 12160;
MDC = 0x2F80;
// CHOPCLK 0; CHPCLKEN disabled;
CHOP = 0x00;
// PWMKEY 0;
PWMKEY = 0x00;
// MDCS Primary; FLTIEN disabled; CAM Edge Aligned; DTC Positive dead time for all Output modes; TRGIEN disabled; XPRES disabled; ITB Master; IUE disabled; CLIEN disabled; DTCP disabled;
PWMCON1 = 0x00;
// MDCS Primary; FLTIEN disabled; CAM Edge Aligned; DTC Positive dead time for all Output modes; TRGIEN disabled; XPRES disabled; ITB Master; IUE disabled; CLIEN disabled; DTCP disabled;
PWMCON2 = 0x00;
// MDCS Primary; FLTIEN disabled; CAM Edge Aligned; DTC Positive dead time for all Output modes; TRGIEN disabled; XPRES disabled; ITB Master; IUE disabled; CLIEN disabled; DTCP disabled;
PWMCON3 = 0x00;
//FLTDAT PWM1L Low, PWM1H Low; SWAP disabled; OVRENH disabled; PENL enabled; PMOD Complementary Output Mode; OVRENL disabled; OSYNC disabled; POLL disabled; PENH enabled; CLDAT PWM1L Low, PWM1H Low; OVRDAT PWM1L Low, PWM1H Low; POLH disabled;
__builtin_write_PWMSFR(&IOCON1, 0xC000, &PWMKEY);
//FLTDAT PWM2L Low, PWM2H Low; SWAP disabled; OVRENH disabled; PENL enabled; PMOD Complementary Output Mode; OVRENL disabled; OSYNC disabled; POLL disabled; PENH enabled; CLDAT PWM2L Low, PWM2H Low; OVRDAT PWM2L Low, PWM2H Low; POLH disabled;
__builtin_write_PWMSFR(&IOCON2, 0xC000, &PWMKEY);
//FLTDAT PWM3L Low, PWM3H Low; SWAP disabled; OVRENH disabled; PENL enabled; PMOD Complementary Output Mode; OVRENL disabled; OSYNC disabled; POLL disabled; PENH enabled; CLDAT PWM3L Low, PWM3H Low; OVRDAT PWM3L Low, PWM3H Low; POLH disabled;
__builtin_write_PWMSFR(&IOCON3, 0xC000, &PWMKEY);
//FLTPOL disabled; CLPOL disabled; CLSRC FLT1; CLMOD disabled; FLTMOD PWM1H, PWM1L pins to FLTDAT values- Latched; IFLTMOD disabled; FLTSRC FLT32;
__builtin_write_PWMSFR(&FCLCON1, 0x3, &PWMKEY);
//FLTPOL disabled; CLPOL disabled; CLSRC FLT1; CLMOD disabled; FLTMOD PWM2H, PWM2L pins to FLTDAT values- Latched; IFLTMOD disabled; FLTSRC FLT32;
__builtin_write_PWMSFR(&FCLCON2, 0x3, &PWMKEY);
//FLTPOL disabled; CLPOL disabled; CLSRC FLT1; CLMOD disabled; FLTMOD PWM3H, PWM3L pins to FLTDAT values- Latched; IFLTMOD disabled; FLTSRC FLT32;
__builtin_write_PWMSFR(&FCLCON3, 0x3, &PWMKEY);
// PDC1 256;
PDC1 = 0x100;
// PDC2 96;
PDC2 = 0x60;
// PDC3 32;
PDC3 = 0x20;
// PHASE1 0;
PHASE1 = 0x00;
// PHASE2 0;
PHASE2 = 0x00;
// PHASE3 0;
PHASE3 = 0x00;
// DTR1 0;
DTR1 = 0x00;
// DTR2 0;
DTR2 = 0x00;
// DTR3 0;
DTR3 = 0x00;
// ALTDTR1 0;
ALTDTR1 = 0x00;
// ALTDTR2 0;
ALTDTR2 = 0x00;
// ALTDTR3 0;
ALTDTR3 = 0x00;
// TRGCMP 0;
TRIG1 = 0x00;
// TRGCMP 0;
TRIG2 = 0x00;
// TRGCMP 0;
TRIG3 = 0x00;
// TRGDIV 1; TRGSTRT 0;
TRGCON1 = 0x00;
// TRGDIV 1; TRGSTRT 0;
TRGCON2 = 0x00;
// TRGDIV 1; TRGSTRT 0;
TRGCON3 = 0x00;
// PWMCAP 0;
PWMCAP1 = 0x00;
// PWMCAP 0;
PWMCAP2 = 0x00;
// PWMCAP 0;
PWMCAP3 = 0x00;
// BPLL disabled; BPHH disabled; BPLH disabled; BCH disabled; FLTLEBEN disabled; PLR disabled; CLLEBEN disabled; BCL disabled; PLF disabled; PHR disabled; BPHL disabled; PHF disabled;
LEBCON1 = 0x00;
// BPLL disabled; BPHH disabled; BPLH disabled; BCH disabled; FLTLEBEN disabled; PLR disabled; CLLEBEN disabled; BCL disabled; PLF disabled; PHR disabled; BPHL disabled; PHF disabled;
LEBCON2 = 0x00;
// BPLL disabled; BPHH disabled; BPLH disabled; BCH disabled; FLTLEBEN disabled; PLR disabled; CLLEBEN disabled; BCL disabled; PLF disabled; PHR disabled; BPHL disabled; PHF disabled;
LEBCON3 = 0x00;
// LEB 0;
LEBDLY1 = 0x00;
// LEB 0;
LEBDLY2 = 0x00;
// LEB 0;
LEBDLY3 = 0x00;
// CHOPLEN disabled; CHOPHEN disabled; BLANKSEL No state blanking; CHOPSEL No state blanking;
AUXCON1 = 0x00;
// CHOPLEN disabled; CHOPHEN disabled; BLANKSEL No state blanking; CHOPSEL No state blanking;
AUXCON2 = 0x00;
// CHOPLEN disabled; CHOPHEN disabled; BLANKSEL No state blanking; CHOPSEL No state blanking;
AUXCON3 = 0x00;
// SYNCOEN disabled; SEIEN disabled; SESTAT disabled; SEVTPS 1; SYNCSRC SYNCI1; SYNCEN disabled; PTSIDL disabled; PTEN enabled; EIPU disabled; SYNCPOL disabled;
PTCON = 0x8000;
}
ADC Configuration and Interrupt ISR:
void ADC1_Initialize (void)
{
// ASAM enabled; ADDMABM disabled; ADSIDL disabled; DONE disabled; SIMSAM Simultaneous; FORM Absolute decimal result, unsigned, right-justified; SAMP disabled; SSRC PWM1 Primary Trigger; AD12B 10-bit; ADON enabled; SSRCG enabled;
AD1CON1 = 0x801C;
// CSCNA disabled; VCFG0 AVDD; VCFG1 AVSS; ALTS enabled; BUFM disabled; SMPI Generates interrupt after completion of every 2nd sample/conversion operation; CHPS 4 Channel;
AD1CON2 = 0x205;
// SAMC 31; ADRC FOSC/2; ADCS 49;
AD1CON3 = 0x1F31;
// CH0SA OA5/AN25; CH0SB AN32; CH0NB VREFL; CH0NA VREFL;
AD1CHS0 = 0x2019;
// CSS26 disabled; CSS25 disabled; CSS24 disabled; CSS27 disabled;
AD1CSSH = 0x00;
// CSS2 disabled; CSS1 disabled; CSS0 disabled; CSS5 disabled; CSS4 disabled; CSS3 disabled;
AD1CSSL = 0x00;
// DMABL Allocates 1 word of buffer to each analog input; ADDMAEN disabled;
AD1CON4 = 0x00;
// CH123SA2 CH1=OA2/AN0,CH2=AN1,CH3=AN2; CH123SB2 CH1=OA1/AN3,CH2=AN4,CH3=AN5; CH123NA CH1=VREF-,CH2=VREF-,CH3=VREF-; CH123NB CH1=VREF-,CH2=VREF-,CH3=VREF-;
AD1CHS123 = 0x100;
//Assign Default Callbacks
ADC1_SetInterruptHandler(&ADC1_CallBack);
// Enabling ADC1 interrupt.
IEC0bits.AD1IE = 1;
}
void __attribute__ ((weak)) ADC1_CallBack(void)
{
}
void ADC1_SetInterruptHandler(void* handler)
{
ADC1_DefaultInterruptHandler = handler;
}
void __attribute__ ( ( __interrupt__ , auto_psv, weak ) ) _AD1Interrupt ( void )
{
if(IFS0bits.AD1IF)
{
if (count < BUFFER_SIZE)
{
V_A[count] = ADC1BUF1;
V_B[count] = ADC1BUF2;
V_C[count] = ADC1BUF3;
I_A[count] = ADC1BUF5;
I_B[count] = ADC1BUF6;
I_C[count] = ADC1BUF7;
count++;
}
if (count == BUFFER_SIZE){
count = 0;
}
/*
if(ADC1_DefaultInterruptHandler)
{
ADC1_DefaultInterruptHandler();
}
*/
// clear the ADC interrupt flag
IFS0bits.AD1IF = false;
}
}