Hi, I'm working with a Kl02 and I'm trying to read an ADC channel but always I read random values. I've been working with different codes and ways but the mistake continues and I can't figure out the problem.
The uC is the MKL02Z32VFG4. QFN 16
I'm trying to read values from the port PTB0 -> ADC0 Channel 6 [ PIN 8 ]
To verify the correct configuration of the ADC peripheral I'm reading form other channel in this case I'm usign the port PTB5 -> ADC0 Channel 1 [PIN 13] . This channel works perfectly and I can read right values.
This is my schematic. In the PIN labeled as TRIGGER_3.3 I can read perfectly the ADC value. But the PIN labeled as MA give me always random values.
Code to configure the ADC:
I'm working with Kinetis Desing Studio 3.1.0 and KSDK 1.3.0
int Interface_Adc_Init( t_Interface_Adc_Handle *adc_handle,
t_Interface_Adc_Device adc )
{
adc16_chn_config_t adcCalibrationChnConfig;
if( adcList[adc].installed == Interface_Adc_Free_Device )
{
ADC16_DRV_StructInitUserConfigDefault( &adc_handle->adc_config_info );
adc_handle->adc_config_info.lowPowerEnable = false;
adc_handle->adc_config_info.resolution = kAdc16ResolutionBitOfSingleEndAs12;
adc_handle->adc_config_info.asyncClkEnable = false;
adc_handle->adc_config_info.clkSrc = kAdc16ClkSrcOfBusClk;
adc_handle->adc_config_info.clkDividerMode = kAdc16ClkDividerOf2;
adc_handle->adc_config_info.longSampleTimeEnable = false; //true;
adc_handle->adc_config_info.longSampleCycleMode = kAdc16LongSampleCycleOf16;
if ( kStatus_ADC16_Success != ADC16_DRV_Init( adc_handle->device, &adc_handle->adc_config_info ) )
{
while(1); // only for test use
}
adc_handle->adc_average_cfg.hwAverageEnable = false;//true;
adc_handle->adc_average_cfg.hwAverageCountMode = kAdc16HwAverageCountOf16;
if( kStatus_ADC16_Success != ADC16_DRV_ConfigHwAverage( adc_handle->device, &adc_handle->adc_average_cfg ) )
{
while(1); // only for test use
}
adcCalibrationChnConfig.chnIdx = kAdc16Chn31;
adcCalibrationChnConfig.convCompletedIntEnable = false;
// Configure channel0
ADC16_DRV_ConfigConvChn(adc_handle->device, 0U, &adcCalibrationChnConfig);
// Auto calibration.
ADC16_DRV_GetAutoCalibrationParam( adc_handle->device, &adc_handle->adc_calib_param );
ADC16_DRV_SetCalibrationParam( adc_handle->device, &adc_handle->adc_calib_param );
}
return( 0 );
}
/* END */
Code to start and read a conversion
int Interface_Adc_Start_Measure( t_Interface_Adc_Handle *adc_handle, t_Adc_Channels channel, bool intEnable )
{
adc16_chn_config_t adc_channel_cfg;
adc_channel_cfg.chnIdx = (adc16_chn_t)channel;
adc_channel_cfg.convCompletedIntEnable = intEnable;
ADC16_DRV_ConfigConvChn( adc_handle->device, 0, &adc_channel_cfg );
return( 0 );
}
int Interface_Adc_Stop_Conversion( t_Interface_Adc_Handle *adc_handle )
{
ADC16_DRV_PauseConv( adc_handle->device, 0 );
return(0);
}
int Interface_Adc_Read_Measure( t_Interface_Adc_Handle *adc_handle )
{
ADC16_DRV_WaitConvDone( adc_handle->device, 0 );
return ( ADC16_DRV_GetConvValueRAW( adc_handle->device, 0 ) );
}
Main
static t_Interface_Adc_Handle adc0;
int main(void)
{
static float adc;
static float adc_Convertion;
// Configure board specific pin muxing
hardware_init();
Api_System_Tick_Init( 100, Util_Clock_Base_Update ); //100uS 0.1ms.
Api_System_Tick_Start( );
Util_Periodic_Timer_Init( &systemTick1000, 10000 ); //1000ms
Interface_Adc_Init( &adc0, Interface_Adc0 );
/* Synchronous tasks */
while(1)
{
if( Util_Periodic_Timer_Execute( &systemTick1000 ) ) //1000ms.
{
Interface_Adc_Start_Measure( &adc0, Interface_Adc_Channel6, false );
adc =Interface_Adc_Read_Measure( &adc0 ); <- This channel fail.
Interface_Adc_Stop_Conversion( &adc0 );
Interface_Adc_Start_Measure( &adc0, Interface_Adc_Channel1, false );
adc =Interface_Adc_Read_Measure( &adc0 ); <- This channel works fine.
Interface_Adc_Stop_Conversion( &adc0 );
}
}//while(1)
}
Any idea to fix the problem?
Thanks in advance and sorry for the code without colors.
Thank you for your reply, I've created a new thread: Possible Mask error in MKL02Z32VFG4 QFN 16 en Kinetis Microcontrollers
with new clues about this problem.
best regards.
Hi, Antoni,
As JingJing said, the ADC0_SE6(PTB0) corresponds AD9, ADCH should be 9 instead of 6, I have tested on my FRDM-KL02Z board, I can get correct result with the code by testing the PTB0 pin(pin6 of J7 on FRDM-KL02Z board):
BR
XiangJun Rong
static int i = 0;
unsigned short sample;
int main(void)
{
/* Write your code here */
ADCInit();
/* This for loop should be replaced. By default this loop allows a single stepping. */
for (;;) {
i++;
// ADC0_CFG2&=~(0x10); //select channel a
ADC0_CFG2&=(0x10); //select channel a
ADC0_SC1A=0x09;
while(!(ADC0_SC1A&0x80)) {}
sample=ADC0_RA;
__asm("nop");
}
/* Never leave main */
return 0;
}
Ok XiangJun,
I've checked Jingjing reply, thank for your support.
Hi, Antonio,
I have tested the PTB0/ADC0_SE6 on my FRDM-KL02Z board, i get the same phenomenon, the ADC sample does not change no matter I test 3.3V or GND.
I will investigate the case next week.
sorry.
Xiangjun rong