MC56F847 ADC16 configuration problem

cancel
Showing results for 
Search instead for 
Did you mean: 

MC56F847 ADC16 configuration problem

Jump to solution
408 Views
dhanaraj_shanmu
Contributor II

I am first time using CW. I am having trouble making ADC16 work.

I have four new analog inputs connected to MCU(ANC16,17,18 and 19). ANC16 and 19 are single end inputs whereas ANC17 and 18 are differential inputs(RTD).

Some other questions:

1. How to select VDDa and VSSa as reference source for ADC16? From datasheet, its mentioned that internally its routed to reference pins. Is it correct?

I followed below steps to modify my existing project.

1. Enable peripheral in PE_low_level_init(). 

/* GPIOA_PER: PE11=1,PE10=1,PE9=1,PE8=1,PE3=1,PE2=1,PE1=1,PE0=1 */
setReg16Bits(GPIOA_PER, 0x0F0FU);

 2. Initialize ADC16 in 12 bit mode:

void AD2_Init(void)
{
/* INTC_IPR2: ADC_COCO=2 */
clrSetReg16Bits(INTC_IPR2, 0x4000U, 0x8000U);
/* ADC16_SC1A: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COCO=0,AIEN=1,??=0,ADCH=0x1F */
setReg32(ADC16_SC1A,0x1F); /* Disable the module */
/* ADC16_SC2: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,ADACT=0,ADTRG=0,ACFE=0,ACFGT=0,ACREN=0,DMAEN=0,REFSEL=0 */
setReg32(ADC16_SC2,0x00); /* Disable HW trigger and autocompare and select the voltage reference */
/* ADC16_SC3: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CAL=0,CALF=0,??=0,ASSITRGEN=0,ADCO=0,AVGE=0,AVGS=0 */
setReg32(ADC16_SC3,0x00); /* Disable HW average and continous conversion */

AD2_OutFlg = FALSE; /* No measured value */
AD2_ModeFlg = IDLE; /* Device isn't running */
/* ADC16_CFG1: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,ADLPC=0,ADIV=2,ADLSMP=0,MODE=1,ADICLK=2 */
setReg32(ADC16_CFG1,0x04); /* Configure clock settings and power and resolution mode */
/* ADC16_CFG2: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,ADACKEN=0,ADHSC=0,ADLSTS=0 */
setReg32(ADC16_CFG2,0x00); /* Configure asynchroclock and high speed conversion and sample time longitude */

}

3. Copy data in interrupt handler

void AD2_Interrupt(void)
{
AD2_OutV[SumChan] = (UINT16)(getReg32(ADC16_RA)); /* Save measured value */
SumChan++; /* Increase counter of measured channels*/
if (SumChan == 4U) { /* Is number of measured channels equal to the number of channels used in the component? */
SumChan = 0U; /* If yes then set the counter of measured channels to 0 */
AD2_OutFlg = TRUE; /* Measured values are available */
AD2_GetValue16(ADC.ADC_Results); /* If yes then invoke user event */
AD2_ModeFlg = IDLE; /* Set the device to the stop mode */
return; /* Return from interrupt */
}
setReg32(ADC16_SC1A,Channels[SumChan]); /* Start measurement of next channel */
}

I can see the interrupt handler is called after conversion completed. ADC output looks like, for Input 1=255, Input 2=0, Input 3=0, Input 4=0/500.

Not sure what I am missing here. Any input is appreciated.

0 Kudos
1 Solution
270 Views
dhanaraj_shanmu
Contributor II

Hi Rong,

Thanks for your code. It helped me to verify my code works. Your project exactly reads the same counts as mine.

View solution in original post

0 Kudos
4 Replies
271 Views
dhanaraj_shanmu
Contributor II

Hi Rong,

Thanks for your code. It helped me to verify my code works. Your project exactly reads the same counts as mine.

View solution in original post

0 Kudos
270 Views
mohammad_kamil
NXP Employee
NXP Employee

have you change conversion complete vector location name as AD2_Interrupt? your code is coming to interrupt? who is triggering ADC? can you try to read each channel in separate variable 

0 Kudos
270 Views
dhanaraj_shanmu
Contributor II

ISR is served every time there is a conversion completed. ADC is software triggered. 

void AD2_HWEnDi(void)
{
if (AD2_ModeFlg) { /* Start or stop measurement? */
AD2_OutFlg = FALSE; /* Output values aren't available */
SumChan = 0U; /* Set the counter of measured channels to 0 */
ClrSumV(); /* Clear measured values */
setReg32(ADC16_SC1A,Channels[SumChan]); /* If yes then start the conversion */
}
}

static const byte Channels[4] = {0x50U,0x51U,0x52U,0x53U}; /* Contents for the device control register */

In the ISR, channel number is handled.

#pragma interrupt alignsp saveall
void AD2_Interrupt(void)
{
AD2_OutV[SumChan] = (UINT16)(getReg32(ADC16_RA)); /* Save measured value */
SumChan++; /* Increase counter of measured channels*/
if (SumChan == 4U)
{ /* Is number of measured channels equal to the number of channels used in the component? */
SumChan = 0U; /* If yes then set the counter of measured channels to 0 */
AD2_OutFlg = TRUE; /* Measured values are available */
AD2_GetValue16(ADC.ADC_Results); /* If yes then invoke user event */
AD2_ModeFlg = IDLE; /* Set the device to the stop mode */
return; /* Return from interrupt */
}
setReg32(ADC16_SC1A,Channels[SumChan]); /* Start measurement of next channel */
}


 

0 Kudos
270 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Shanmugam,

I have developed an ADC16 example, it use software trigger mode to sample ANC16 pin(GPIOA8 pin), it works fine.

Hope it can help you

BR

XiangJun Rong