MC56F847 ADC16 configuration problem

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

MC56F847 ADC16 configuration problem

跳至解决方案
1,883 次查看
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 项奖励
回复
1 解答
1,746 次查看
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.

在原帖中查看解决方案

0 项奖励
回复
4 回复数
1,747 次查看
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.

0 项奖励
回复
1,746 次查看
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 项奖励
回复
1,746 次查看
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 项奖励
回复
1,746 次查看
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