K32L2B21: ADC0 reading 3 channels

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K32L2B21: ADC0 reading 3 channels

Jump to solution
2,853 Views
nre
Contributor II

Hi, I'm using K32L2B21VFT0A. Is it possible and how can I read sequentially three ADC0 channels, associated with ports: SE6b, SE11 and SE9?
Are these valid configurations or I have to set another group to the third ADC channel, different from 0 (as shown on the attachment)?

Currently I can read only first two channels, associated by 2 groups:
for(int i=0; i<2; i++) {
result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, i);
}
but how to read the three ADC0 channels?

0 Kudos
Reply
1 Solution
2,811 Views
jch
NXP Employee
NXP Employee

Hi nre,
If you just want to measure 3 ADC channels by SW trigger, let the Conversion control group to be 0 for all channels (Conversion control groups are useful in case of HW trigger, please see the tool tip for the Conversion control group item in component, to see it you have to move mouse over values in the table not the name of the item).

ADC0_channelsConfig[] is the array generated by component with measured channel settings.

There are two options:
1) polling mode:
/* for cycle through selected channels see ADC0_channelsConfig[] array */
for(int i=0; i<3; i++) {
  /* Initialize channel - in case of SW trigger start measure immediatelly */
  ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[i]);
  while (ADC16_GetChannelStatusFlags(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP) != kADC16_ChannelConversionDoneFlag) {}
  result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
}
2) interrupt mode:
step 1) create global or static variable uint8_t i = 0; // hold the index to the ADC0_channelsConfig[] array

step 2) In ADC component please select Conversion complete interrupt for all channels and Initialize channel in the first channel, it leads to start measurement right at the end of initialization, then the rest of code is in the interrupt subroutine:

{
  result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
  i++;
  i = i % 3;
  ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[i]);
}
this code will run through the all 3 channels endlessly.
If you want to run only one loop:
{
  result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
  i++;
  if (i < 3) {
    ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[i]);
  }
}

View solution in original post

4 Replies
2,672 Views
nre
Contributor II

Thank you for the solution

0 Kudos
Reply
2,822 Views
nre
Contributor II

Ok, but is it possible to read the third ADC channel as well (forcing by HW or by reading the adc channel in a loop in a predefined amount of time)?

for(int i=0; i<2; i++)
{
uint32_t status = ADC16_GetChannelStatusFlags(ADC0_PERIPHERAL, i);
if(status == kADC16_ChannelConversionDoneFlag)
    result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, i);
}

Currently by using the above code, i am able to read only first two channels SC1A and SC1B (corresponding to ports SE6b and SE11). But how to read the content of third port SE9? Is there another API to select or switch to another set of registers or channels? In spec it's written i am able to switch between 12 channels. How to do that switching when ADC16_GetChannelConversionValue uses second argument for switching between only 2 registers? I need C-code representation as the examples above if available. thank you

 

0 Kudos
Reply
2,812 Views
jch
NXP Employee
NXP Employee

Hi nre,
If you just want to measure 3 ADC channels by SW trigger, let the Conversion control group to be 0 for all channels (Conversion control groups are useful in case of HW trigger, please see the tool tip for the Conversion control group item in component, to see it you have to move mouse over values in the table not the name of the item).

ADC0_channelsConfig[] is the array generated by component with measured channel settings.

There are two options:
1) polling mode:
/* for cycle through selected channels see ADC0_channelsConfig[] array */
for(int i=0; i<3; i++) {
  /* Initialize channel - in case of SW trigger start measure immediatelly */
  ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[i]);
  while (ADC16_GetChannelStatusFlags(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP) != kADC16_ChannelConversionDoneFlag) {}
  result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
}
2) interrupt mode:
step 1) create global or static variable uint8_t i = 0; // hold the index to the ADC0_channelsConfig[] array

step 2) In ADC component please select Conversion complete interrupt for all channels and Initialize channel in the first channel, it leads to start measurement right at the end of initialization, then the rest of code is in the interrupt subroutine:

{
  result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
  i++;
  i = i % 3;
  ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[i]);
}
this code will run through the all 3 channels endlessly.
If you want to run only one loop:
{
  result_values[i] = ADC16_GetChannelConversionValue(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP);
  i++;
  if (i < 3) {
    ADC16_SetChannelConfig(ADC0_PERIPHERAL, ADC0_CH0_CONTROL_GROUP, &ADC0_channelsConfig[i]);
  }
}

2,838 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @nre ,

K32L2B ADC has two Status and Control Registers, SC1A and SC1B. That's why there is two group. I see you have enabled interrupt. When any of the ADC trig signal come, it will start ADC and then generate interrupt when ADC convert finish. Please check your trig source. SC1B can't be used for software trigger operation and therefore writes to the SC1B registers do not initiate a new conversion.

Please read 23.4.1 in reference manual.

 

Regards,

Jing

0 Kudos
Reply