Re: The  ADC conversion

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

Re: The  ADC conversion

1,288 次查看
pratibhasurabhi
Contributor V

hello, I am using S12ZVML128 controller.

I am not getting ADC conversion result in result register.I have initialized ADC as following.I am calling GetADCValue(E_ADC_CHANNEL_NUMBER leAdcChanNo) function in main by passing channel number.

I am not getting what i have missed in this code to get the conversion value.

Please help me for that? 

 

volatile UINT8 ADC0CommandList[1][4] = {{0xC0,0x00,0x00,0x00}};

volatile UINT8 ADC1CommandList[1][4] = {{0xC0,0x00,0x00,0x00}};
volatile unsigned short ADC0ResultList[1] = {0};
volatile unsigned short ADC1ResultList[1] = {0};

 

typedef enum
{
ADC_CHANNEL_NO_TOTAL_PHASE_CURRENT=0x10, //AN0_0
ADC_CHANNEL_NO_W_PHASE_VOLTAGE=0x50, //AN1_0
ADC_CHANNEL_NO_V_PHASE_VOLTAGE=0x14, //AN0_4
ADC_CHANNEL_NO_U_PHASE_VOLTAGE=0x13, //AN0_3
ADC_CHANNEL_NO_TEMPERATURE_SENSOR=0x51, //AN1_1
ADC_CHANNEL_NO_BATTERY_VOLTAGE=0x52 //AN1_2
}E_ADC_CHANNEL_NUMBER;

 

void InitADC(void)
{

 

//ADC0
ADC0CTL_0 = 0x09; // single access mode-data bus,Trigger mode
//ADC0CTL_0_STR_SEQA = 1; // Store result at abort/restart
ADC0CTL_1=0x10;
ADC0STS=0x00;
ADC0FMT_DJM = 1; // left justified result data
ADC0FMT_SRES = 4; // 12-bit result
ADC0TIM=0; // clock: clk = fbus / (2x(reg.value + 1)) [0.25 - 8MHz]
ADC0CBP = ADC0CommandList;
ADC0RBP = ADC0ResultList;
ADC0CTL_0_ADC_EN = 1;
//ADC1
ADC1CTL_0 = 0x09; // single access mode-data bus,Trigger mode
//ADC1CTL_0_STR_SEQA = 1; // Store result at abort/restart
ADC1CTL_1=0x10;
ADC1STS=0x00;
ADC1FMT_DJM = 1; // left justified result data
ADC1FMT_SRES = 4; // 12-bit result
ADC1TIM=0; // clock: clk = fbus / (2x(reg.value + 1)) [0.25 - 8MHz]
ADC1CBP = ADC1CommandList;
ADC1RBP = ADC1ResultList;
ADC1CTL_0_ADC_EN = 1;

}

UINT16 GetADCValue(E_ADC_CHANNEL_NUMBER leAdcChanNo)
{
   UINT16 lu16AdcConvResult = 0;
   UINT8 lu8cmdListVar=0;
   UINT8 var=0;
if((leAdcChanNo>>6)==1)      //for ADC 1 channel
{
var=(leAdcChanNo & 0x3F)+0xC0;
ADC1CommandList[0][1]=var;
ADC1FLWCTL_RSTA = 1;
while(!ADC1CONIF)
{

}
ADC1CONIF=ADC1CONIF;
return(ADC1ResultList[0]);
}
else if((leAdcChanNo>>6)!=1)   //for ADC 0 channel
{
var=(leAdcChanNo & 0x3F)+0xC0;
ADC0CommandList[0][1]=var;
ADC0FLWCTL_RSTA = 1;
while(!ADC1CONIF)
{

}
ADC0CONIF=ADC0CONIF;
return(ADC0ResultList[0]);
}
else
{

}

}

标签 (1)
0 项奖励
5 回复数

638 次查看
RadekS
NXP Employee
NXP Employee

Hi PRATIBHA,

I shortly checked your code and currently I cannot see any obvious issue except the potential issue with command and result list alignment.

Please use:

volatile UINT8 ADC0CommandList[1][4] __attribute__ ((aligned (4))) = {{0xC0,0x00,0x00,0x00}};

volatile UINT8 ADC1CommandList[1][4] __attribute__ ((aligned (4))) = {{0xC0,0x00,0x00,0x00}};

volatile unsigned short ADC0ResultList[1] __attribute__ ((aligned (4))) = {0};

volatile unsigned short ADC1ResultList[1] __attribute__ ((aligned (4))) = {0};

 

These lists must be aligned to 4byte boundary due to internal DMA transfer mechanism.

I hope it helps you.

Have a great day,
Radek

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

638 次查看
pratibhasurabhi
Contributor V

Hi,I want to calculate the conversion time for that GetADCValue(E_ADC_CHANNEL_NUMBER leAdcChanNo) function.Could you please tell me,how much time it will take to execute? I am using clock settings as follows,

crystal frequency=20Mhz

#define _EXTERNAL_CLOCK

void InitClock(void)
{
while (GDUF_GLVLSF)
GDUF_GLVLSF = 1;

CPMUREFDIV_REFDIV = 3;
CPMUREFDIV_REFFRQ = 1;
CPMUSYNR_SYNDIV = 4;
CPMUSYNR_VCOFRQ = 1;
CPMUPOSTDIV_POSTDIV = 1;
#if 1
// Oscillator clock monitor reset is enabled
CPMUOSC2_OMRE = 1;
#endif
#ifdef _EXTERNAL_CLOCK
CPMUOSC_OSCE = 1;
while (CPMUIFLG_UPOSC == 0) {}; // Wait for oscillator to start up (UPOSC=1) and PLL to lock (LOCK=1)
#endif

while (CPMUIFLG_LOCK == 0) {};
CPMURFLG = 0x60; //Clear PORF and LVRF
}

0 项奖励

638 次查看
RadekS
NXP Employee
NXP Employee

Hi PRATIBHA,

 

When #ifdef _EXTERNAL_CLOCK

fREF = fOSC/(REFDIV + 1) = 20MHz/(3+1) = 5MHz

fVCO = 2 * fREF * (SYNDIV + 1) = 2*5MHz*(4+1)=50MHz

fPLL = fVCO/(POSTDIV + 1) = 50MHz/(1+1) = 25MHz

fBUS = fPLL/2 = 25MHz/2 = 12.5MHz

else

fREF = fIRC1M = 1MHz  //incorrect REFFRQ value

fVCO = 2 * fREF * (SYNDIV + 1) = 2*1MHz*(4+1)=10MHz //invalid fVCO, it has to be at least 32MHz

fPLL = fVCO/(POSTDIV + 1) = 10MHz/(1+1) = 5MHz

fBUS = fPLL/2 = 5MHz/2 = 2.5MHz

 

So, the #ifdef _EXTERNAL_CLOCK condition may be dangerous in your code. I would like to recommend add #else with PLL parameters for internal IRC clock as source.

 

Now, I let’s assume that you have fBUS = 12.5MHz.

Maximum fATDCLK is 8.33MHz

The ADC prescaler value is zero at your code (ADC0TIM=0;).

So, fATDCLK= fbus / (2x(reg.value + 1)) = 6.25MHz

Per your commands, the sample time is 4 ADC clocks

The ADC Conversion Period for 12bit is 19~39 ADC clocks, where we will calculate with 19 due to shortest sample time.

ADC Conversion Period = 19/fATDCLK = 3.04us.

I hope it helps you.

 

Have a great day,
Radek

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励

638 次查看
pratibhasurabhi
Contributor V

I have calculated the GetADCValue function execution time, its taking 9us to execute and inner while loop is taking 5us.

I want to reduce this conversion time.Please suggest me for that.

0 项奖励

638 次查看
pratibhasurabhi
Contributor V

Than you very much,now my code is working.

0 项奖励