• AVR Freaks

Output Compare Syncronisation with ADC interrupt

Author
RonGer
Starting Member
  • Total Posts : 51
  • Reward points : 0
  • Joined: 2018/11/27 08:43:34
  • Location: 0
  • Status: offline
2020/01/22 04:20:47 (permalink)
0

Output Compare Syncronisation with ADC interrupt

Dear all,
 
I'm currently trying to measure a sine signal which is generated by the Output compare macro of the DSPIC33EV256GM104.
For this purpose ADC and Output compare need to be in phase, so that the ADC is measuring always on the same points of the sine wave.
 
My initialisation routine for OC looks as follows:
 
void oc1_init(uint16_t period)
{
 // Initialise Output compare unit
 OC1CON1 = 0x0000;
 OC1CON2 = 0x0000;
 // peripheral clock as source
 OC1CON1bits.OCTSEL = 0x07;
 // sync counter on ADC1
 OC1CON2bits.SYNCSEL = 0x1b;
 /*! \todo Check if the mechanism works. Otherwise correct the implementation. */
 if (period != 0u) {
  // frequency: use defined value.
  // duty cycle: ~50%
  OC1RS = period - 1;
  OC1R = period / 2;
 } else {
  /* Abschalten scheint nicht zu gehen. Jetzt einfach mal HF probieren ...*/
  OC1RS = 23u;
  OC1R = 12u;
 }
 OC1TMR = 0x0000;
 
 IFS0bits.OC1IF = 0;
 IEC0bits.OC1IE = 1;
 // enable OC1 in edge-aligned PWM mode
 OC1CON1bits.OCM = 6;
}
 
My initialisation routine for the adc looks as follows:
/* ADC and DMA0 intialization */
void adc_init(uint8_t prescaler, uint8_t sampling_time, uint8_t samples)
{
 // 12bit mode, integer right-justified; automatic sampling
 //AD1CON1 = 0x04e4;
#if 0
 // 12bit mode, signed fractional; automatic sampling
 AD1CON1 = 0x07e4;
#else
 // 12 bit mode, signed integer, automatic sampling
 AD1CON1 = 0x05e4;
 //AD1CON1 = 0x07e4;
#endif
 AD1CON2 = 0;
 // Clock from system clock
 AD1CON3 = 0;
 AD1CON3bits.SAMC = sampling_time;
 AD1CON3bits.ADCS = prescaler - 1;
 // Use DMA for transfer of results
 AD1CON4 = 0x100;
 // Input AN0
 AD1CHS0 = 0;
 AD1CHS123 = 0;
 AD1CSSH = 0;
 AD1CSSL = 0;
 // configure DMA
 DMA0CONbits.AMODE = 0;
 DMA0CONbits.MODE = 2;
 DMA0PAD = (uint16_t) & ADC1BUF0;
 DMA0CNT = samples - 1;
 DMA0REQ = 13;
 //DMA0REQ = 0x0D;
 DMA0STAL = (uint16_t) BufferA;
 DMA0STAH = 0;
 DMA0STBL = (uint16_t) BufferB;
 DMA0STBH = 0;
 IFS0bits.DMA0IF = 0;
 IEC0bits.DMA0IE = 1;
 DMA0CONbits.CHEN = 1;
 IFS0bits.AD1IF = 0;
 IEC0bits.AD1IE = 0;
 // enable ADC
 AD1CON1bits.ADON = 1;
 /* Clear the ADCValsMeasured flag*/
 //ADCValsMeasured = 0u;
 NewSeqReady_Decrement(1);
 /* Note on the following instruction: The DSP unit of the system shall
  be configured in a way that conversions from ACCA or ACCB to a W-reg
  are made as "saturating" conversions, i.e. if the value of the ACCn
  register does exceed the capabilities of the result register, the
  W0 result from the function call is either 0x7FFF or 0x8000 indicating
  an overflow. Expection is that the system keeps the value. */
 CORCONbits.SATDW = 1u;
 return;
}
 
 
Unfortunately I wasn't able to eliminate a little shift in the measurements between two subsequent measuring cycles.
For this reason I would like to ask wheather someone has an idea, what goes wrong.
 
#1

0 Replies Related Threads

    Jump to:
    © 2020 APG vNext Commercial Version 4.5