Jump to content
Sign in to follow this  
ahgan84

About DMA on ADC12.

Recommended Posts

Hi guys,

 

These days I've been studying some sample coding from TI on DMA for my ADC12. For your information I'm using MSP430F5325 and I have the below coding:

//******************************************************************************
//  MSP430F532x Demo - DMA0, Single transfer using ADC12 triggered by TimerB
//
//  Description: This software uses TBCCR1 as a sample and convert input into
//  the A0 of ADC12. ADC12IFG is used to trigger a DMA transfer and DMA
//  interrupt triggers when DMA transfer is done. TB1 is set as an output and
//  P1.0 is toggled when DMA ISR is serviced.
//  ACLK = REFO = 32kHz, MCLK = SMCLK = default DCO 1048576Hz
//
//                 MSP430F532x
//             -----------------
//         /|\|              XIN|-
//          | |                 | 32kHz
//          --|RST          XOUT|-
//            |                 |
//            |             P1.0|-->LED
//            |             P5.7|-->TB1 output
//            |                 |
//            |             P6.0|<--A0
//
//   Bhargavi Nisarga
//   Texas Instruments Inc.
//   April 2009
//   Built with CCSv4 and IAR Embedded Workbench Version: 4.21
//******************************************************************************

#include 

unsigned int DMA_DST;                        // ADC conversion result is stored in this variable

void main(void)
{
 WDTCTL = WDTPW+WDTHOLD;                   // Hold WDT

 P1OUT &= ~BIT0;                           // P1.0 clear
 P1DIR |= BIT0;                            // P1.0 output
 P5SEL |= BIT7;                            // P5.7/TB1 option select
 P5DIR |= BIT7;                            // Output direction
 P6SEL |= BIT0;                            // Enable A/D channel A0 

 //Setup Timer B0
 TBCCR0 = 0xFFFE;
 TBCCR1 = 0x8000;
 TBCCTL1 = OUTMOD_3;                       // CCR1 set/reset mode
 TBCTL = TBSSEL_2+MC_1+TBCLR;              // SMCLK, Up-Mode

 // Setup ADC12
 ADC12CTL0 = ADC12SHT0_15+ADC12MSC+ADC12ON;// Sampling time, MSC, ADC12 on
 ADC12CTL1 = ADC12SHS_3+ADC12CONSEQ_2;     // Use sampling timer; ADC12MEM0
                                           // Sample-and-hold source = CCI0B =
                                           // TBCCR1 output
                                           // Repeated-single-channel
 ADC12MCTL0 = ADC12SREF_0+ADC12INCH_0;     // V+=AVcc V-=AVss, A0 channel
 ADC12CTL0 |= ADC12ENC;

 // Setup DMA0
 DMACTL0 = DMA0TSEL_24;                    // ADC12IFGx triggered
 DMACTL4 = DMARMWDIS;                      // Read-modify-write disable
 DMA0CTL &= ~DMAIFG;
 DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_3+DMAIE; // Rpt single tranfer, inc dst, Int
 DMA0SZ = 1;                               // DMA0 size = 1

 __data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0);
                                           // Source block address
 __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST);
                                           // Destination single address   
 __bis_SR_register(LPM0_bits + GIE);       // LPM0 w/ interrupts
 __no_operation();                         // used for debugging
}

//------------------------------------------------------------------------------
// DMA Interrupt Service Routine
//------------------------------------------------------------------------------
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
 switch(__even_in_range(DMAIV,16))
 {
   case 0: break;
   case 2:                                 // DMA0IFG = DMA Channel 0
     P1OUT ^= BIT0;                        // Toggle P1.0 - PLACE BREAKPOINT HERE AND CHECK DMA_DST VARIABLE
     break;
   case 4: break;                          // DMA1IFG = DMA Channel 1
   case 6: break;                          // DMA2IFG = DMA Channel 2
   case 8: break;                          // DMA3IFG = DMA Channel 3
   case 10: break;                         // DMA4IFG = DMA Channel 4
   case 12: break;                         // DMA5IFG = DMA Channel 5
   case 14: break;                         // DMA6IFG = DMA Channel 6
   case 16: break;                         // DMA7IFG = DMA Channel 7
   default: break;
 }
}

 

Lets's discuss this coding for this topic. I already have a few question here.

 

1. The description says it uses TBCCR1 as a sample, I don't understand. What is the timer_B for?

 

2. From the datasheet, there is DMACTL0 to DMACTL3. Why is it each DMACTLx has two DMA trigger select for example DMACTL0 has DMA1TSELx and DMA0TSELx?

 

3. How do we choose the DMA trigger select as this coding is using DMACTL0 = DMA0TSEL_24? Why 24?

Share this post


Link to post
Share on other sites

Hello ahgan84, I've found the DMA can make using the peripherals together a bit easier.

 

1. Timer_B is being used to trigger the ADC12 transfer. You can also use Timer_A or a software trigger.

 

2. DMAx...x selects the dma channel and dma trigger source. As an example, you can select DMA0TSEL_24 for ADC12 transfers on channel 0 and DMA1TSEL_18 for UCB0 Receive transfers on channel 1. Both can then use the DMA 'simultaneously' without interference.

 

3. 24 is selected, as that's the trigger for the ADC12. For the MSP430F5529, you can use DMA0TSEL_24 or DMA0TSEL__ADC12IFG for a more descriptive way to do the same thing. Both will select ADC12 triggers on DMA channel 0.

Share this post


Link to post
Share on other sites
Hello ahgan84, I've found the DMA can make using the peripherals together a bit easier.

3. 24 is selected, as that's the trigger for the ADC12. For the MSP430F5529, you can use DMA0TSEL_24 or DMA0TSEL__ADC12IFG for a more descriptive way to do the same thing. Both will select ADC12 triggers on DMA channel 0.

 

I see. So, can I say DMA0TSEL_24 is fixed for ADC12? Does that means other DMA0TSEL_xx is for other purposes / function?

 

I got a few questions again regarding the above coding:

1.

Timer_B is being used to trigger the ADC12 transfer. You can also use Timer_A or a software trigger.
I thought it uses the DMA0IFG to trigger the ADC12 transfer? Why is it Timer_B is used and why is it there is two value for TBCCR (TBCCR0 = 0xFFFE;TBCCR1 = 0x8000)? Is it that we must always use a timer to trigger ADC12 transfer?

2. How do we know what is the source address DMA0SA and destination address DMA0DA for this coding? Is it default address that start from 0?

3. Does __data16_write_addr function stand for write a specific data from a specific address? I don't get what this two lines means

__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0); __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST);

. Does it mean by writing like this, we can transfer the data from ADC12MEM0 to DMA_DST? Can't we just declare DMA_DST = ADC12MEM0? That will be more easier for me to understand...

4. What is the relationship of the channels for DMA and channels for ADC12? I mean, does DMA Channel 0 uses to transfer ADC12 Channel 0 only? What if I want to use DMA to transfer all 14 Channels from ADC12?

Share this post


Link to post
Share on other sites

Hello Ahgan84. Yes DMA0TSEL_24 is fixed to the ADC12. But so is DMA1TSEL_24 and DMA2TSEL_24... those just use different DMA channels for the device. It's what allows the simultaneous DMA transfers of multiple peripherals. Again, so you can use channel 0 for adc, channel 1 for uart, channel 2 for... and so on.

 

1. I guess saying that TimerB is the trigger is the incorrect way to say it. Yes, the DMA0IFG is the trigger but TimerB is the sample and hold source timer. No, you don't need to use TimerB. You can use TimerA or your own software routines.

 

2,3. You are determining the source and destination addresses. Obviously in this case, ADC12MEM0 goes to the DMA0SA source address and your destination address is the variable you want the data stored to. As far as declaring DMA_DST=ADC12MEM0, I don't think that will work as you're not also declaring a source address. If you're just wanting to make a statement moving the ADC12MEM0 to a variable, why would you bother with the DMA?

 

4. See first statement. And if you want all 14 channels to transfer via DMA, you just configure the ADC12 to multisample and select which adc channels you want sampled. Then configure the DMA for the number of block conversions and setup the destination address to autoincrement.

 

Here's an example of how I call the ADC12:

while (1)
{
	while (ADC12CTL1 & BUSY);			// wait for adc12 to be ready
	ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_0; // sample channel 0
	ADC12CTL0 |= ADC12ENC + ADC12SC;	// start sampling and conversion

	LPM0;
}

These are the different init functions:

void ADC12_init(void)
{
ADC12CTL0 &= ~ADC12ENC;											// stop adc12 to change settings
ADC12CTL0 = ADC12MSC + ADC12SHT0_3 + ADC12ON;		// multi sample; 32 cycles; enable adc12
ADC12CTL1 = ADC12SHS_1 + ADC12DIV_0 + ADC12CONSEQ_2 + ADC12SSEL_3;	// ta0 trigger; /1; repeat-seq; smclk
ADC12CTL2 = ADC12RES_1;										// 10 bit
ADC12CTL0 |= ADC12ENC;
//ADC12IE |= 0x01;

// start is controlled in main loop; stop is done with dma isr
}

void adc_DMA_init(void)
{
DMACTL0 = DMA0TSEL__ADC12IFG;						// select adc12 trigger
__data16_write_addr( (unsigned short)&DMA0SA, (unsigned long)&ADC12MEM0 );	// dma single source address
__data16_write_addr( (unsigned short)&DMA0DA, (unsigned long)&ADCdata[0] );	// destination array

DMA0SZ = 64;				// 64 conversions each channel, channels selected in main routine after isr exit

// repeat; increment dest address; enable dma; enable interrupt; high level
DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN + DMAIE + DMALEVEL;

}

void Timer0A0_init(void)
{	
//P1DIR |= BIT1 + BIT2;
//P1SEL |= BIT1 + BIT2;

   TA0CCTL1 = OUTMOD_4;
   TA0CCR0 = 6001;
   TA0CTL = TASSEL_2 + MC_1 + TACLR;	// smclk; up mode; clear
}

// dma isr; dma0 on adc trigger
#pragma vector=DMA_VECTOR
__interrupt void dma_isr(void)
{
switch(__even_in_range(DMAIV,DMAIV_DMA2IFG))
{
   case  DMAIV_NONE: break;                          // No interrupt
   case  DMAIV_DMA0IFG: 								 // DMA0IFG

   //triggered by adc conversions
   P8OUT ^= BIT2;				// led indicator
   ADC12CTL0 &= ~ADC12ENC;		// disable adc12 to re-select channel after exit
LPM0_EXIT;

break;                                 

   case  DMAIV_DMA1IFG: break;                          // DMA1IFG
   case  DMAIV_DMA2IFG: break;                          // DMA2IFG

   default: break; 
 }   
}

Share this post


Link to post
Share on other sites
1. I guess saying that TimerB is the trigger is the incorrect way to say it. Yes, the DMA0IFG is the trigger but TimerB is the sample and hold source timer. No, you don't need to use TimerB. You can use TimerA or your own software routines.

 

But I thought I got the ADC12SHT0_15 to control my sample and hold time and by default, it is from MODCLK right? Then why still use TimerB? I still don't understand why there's two value for TBCCR (TBCCR0 = 0xFFFE;TBCCR1 = 0x8000). Could you explain please?

 

2,3. You are determining the source and destination addresses. Obviously in this case, ADC12MEM0 goes to the DMA0SA source address and your destination address is the variable you want the data stored to. As far as declaring DMA_DST=ADC12MEM0, I don't think that will work as you're not also declaring a source address. If you're just wanting to make a statement moving the ADC12MEM0 to a variable, why would you bother with the DMA?

 

I thought of using DMA, the transferring of data will be faster because it doesn't involve the CPU. So, I want to study how to use DMA but I got a lot don't understand. Is it that when we want to transfer data using DMA, we have to use the two __data16_write_addr function? One is for source address and one is for destination address? From the above coding's comment regarding this, the first one (ADC12MEM0) stated it is 'Source block address' and the second one (DMA_DST) stated it is 'Destination single address'. How to differentiate between block address and single address? I can't find a register that determine which is block address or single address from the datasheet.

Actually what do you mean by block address? I know single address is just one address from the memory. Does block address means multiple address together? Why is it in this coding, ADC12MEM0 is block address?

 

4. See first statement. And if you want all 14 channels to transfer via DMA, you just configure the ADC12 to multisample and select which adc channels you want sampled. Then configure the DMA for the number of block conversions and setup the destination address to autoincrement.

 

Thanks for the coding. Do you have any other coding that's using DMA transferring on ADC12? My coding here is just for one channel of the ADC12. I'm planning to use DMA to transfer all 14 channels of the ADC12. The ADC side I know how to configure to 14 channels. But the DMA side I don't know how to write. Can you please help me?

Share this post


Link to post
Share on other sites

Your Sample and Hold Time(ADC12SHT0) is a different setting than Sample and Hold Source(ADC12SHS).

 

The Sample and Hold Time is the number of clock cycles for a sample. This is determined by the R/C time of the analog device you are using. ADC12SHT0_15 defines 1024 clock cycles for a sample. (timer * cycles = sample time) The actual length of time this takes is determined by which Timer you use and how you've set up the timer. The two values for TBCCR(if you're using TimerB as the SHS), are determining the window of time to sample the adc12. There are numerous ways to configure the Timer to work. You can set OUTMOD_4 (toggle), and not have to set TBCCR0, as it will be assumed to be zero. (BTW, 0xFFFE is setting your timer to the max 16 value it can count to with out overflowing)

 

Yes, using the DMA is faster to transfer the data. Using the DMA eliminates you from having to stop to read the ADC12MEM register. Using the two __data16_write_addr functions essentially connect the ADC12 conversions to a variable specified by the destination address, via the DMA. With this method, you can read the destination variable from any point in your program without need for an ISR or checking ADC12MEMx. In my example, the ADC read is started by the main while loop and only stopped by the DMA isr. When it returns, the ADC starts again. There's no need to read the ADC12MEM register in your ISR and all of your ISR functions can be moved to your main routine. (or a subroutine that is called upon returning from the DMA isr.)

 

The block size, in this case, is how many samples you intend to take from the ADC. For example, channels 1-14, one sample each would only be 14 conversions. 2 channels, 32 times each would be 64...

 

For another example on using the DMA, check this http://www.43oh.com/forum/viewtopic.php?f=10&t=1756&p=12081&hilit=fraunchpad+peripherals#p12074. It's using the ADC10 on a Fraunchpad, but the setup and DMA usage are exactly the same. It will help just to figure out the flow of how the DMA works.

Share this post


Link to post
Share on other sites
The two values for TBCCR(if you're using TimerB as the SHS), are determining the window of time to sample the adc12. There are numerous ways to configure the Timer to work. You can set OUTMOD_4 (toggle), and not have to set TBCCR0, as it will be assumed to be zero. (BTW, 0xFFFE is setting your timer to the max 16 value it can count to with out overflowing)

I still don't understand, why is it there is two TBCCR (TBCCR0 and TBCCR1) values from my code but from your sample code, there is only one TA0CCR0 value? The timer counts to TBCCR0 = 0xFFFE or counts to TBCCR1 = 0x8000? That's why I ask why is it there is two TBCCR. And by the way, how do you determine the values of TBCCR?

 

Is it that we must use a timer to trigger ADC12? Can't we use the default ADC12SC bit? What is the difference of using a timer and the ADC12SC bit? Which is better?

 

The block size, in this case, is how many samples you intend to take from the ADC. For example, channels 1-14, one sample each would only be 14 conversions. 2 channels, 32 times each would be 64...

I see. Thanks for the explanation. But what I want to know is the block address. Back to my below coding:

__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0);  // Source block address __data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &DMA_DST);  // Destination single address  

Why is it stated comment there the ADC12MEM0 is block address? I thought ADC12MEM0 is a single address? Or is it just a typing error? How do you determine for a variable which is block address or single address?

Share this post


Link to post
Share on other sites

There are values for TBCCR0 and TBCCR1, because that's how TI created their example. You can configure the Timer in multiple ways and for different windows. Using their example, the window is between 0xFFFE (65,535-1) and 0x8000 (32768). Ultimately, those example numbers are arbitrary and can be adjusted for your needs. This means you determine the values for the CCR registers.

 

You do not need to use a Timer to trigger the ADC. In can be triggered by software. There is no "better" method, it's all on how you want to write your program. Need all the Timers for other functions? Use software control. Have an extra TimerA or TimerB? Use one of those.

 

The comment states block address because that's how the writer viewed it. My init is commented in the way that I view it:

__data16_write_addr( (unsigned short)&DMA0SA, (unsigned long)&ADC12MEM0 );	// dma single source address
__data16_write_addr( (unsigned short)&DMA0DA, (unsigned long)&ADCdata[0] );	// destination array

That simply shows that we are sourcing from ADC12MEM0 as our single source address register. The destination, in my example, is an array as 64 samples will be sampled so the data is stored. The DMA settings determine how the destination address will be incremented.

// repeat; increment dest address; enable dma; enable interrupt; high level
DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN + DMAIE + DMALEVEL;

 

I don't like how TI's example creates the destination address as DMA_DST. With all caps, it almost makes it look like a DMA register and not a storage variable. If you look at the beginning of the code it's "unsigned int DMA_DST". The example is simply enabling the DMA and writing ADC12MEM0 to the variable DMA_DST. With my example, the DMA moves ADC12MEM0 to ADCdata[x]. 'x' is incremented by the DMA, where the maximum of x is the block size; 64 in my case.

 

I'd really recommend that you read the TimerA (or B), ADC12 and DMA sections of the slaa144h (MSP430x2xx Family

User's Guide). Also, search the web for "MSP430 Timer" and "MSP430 DMA".

Share this post


Link to post
Share on other sites
There are values for TBCCR0 and TBCCR1, because that's how TI created their example. You can configure the Timer in multiple ways and for different windows. Using their example, the window is between 0xFFFE (65,535-1) and 0x8000 (32768). Ultimately, those example numbers are arbitrary and can be adjusted for your needs. This means you determine the values for the CCR registers.

 

You do not need to use a Timer to trigger the ADC. In can be triggered by software. There is no "better" method, it's all on how you want to write your program. Need all the Timers for other functions? Use software control. Have an extra TimerA or TimerB? Use one of those.

I see. I've also saw the word software control from the internet. What exactly it is? Could you explain to me how do we use software control to trigger the DMA? Is the time we set for CCR registers (long or short) effecting the ADC accuracy?

 

I've read the MSP430x5xxx family datasheet on ADC12 and DMA already. But I still have a lot don't understand. That's why I posted my questions here hoping somebody to explain to me.

Share this post


Link to post
Share on other sites

Software control is when you enable/disable ADC12ENC manually. The sampling timer can also be configured on demand as well, when using ADC12SHP=1.

for example, in the main routine:

ADC12CTL0 |= ADC12ENC + ADC12SC;	// start sampling and conversion
LPM0;

and in the DMA isr (provided you've configured everything correctly):

ADC12CTL0 &= ~ADC12ENC;		// disable adc12 to re-select channel after exit
LPM0_EXIT;

 

Yes, your timer selection, configuration and adc configuration can affect accuracy. The length of the sample and hold time is determined by the device.

 

This is from the TI MSP430F5529 user's guide. (page 493)

22.2.5.3 Sample Timing Considerations

When SAMPCON = 0, all Ax inputs are high impedance. When SAMPCON = 1, the selected Ax input can

be modeled as an RC low-pass filter during the sampling time tsample (see Figure 22-5). An internal MUX-on

input resistance RI (maximum 1.8 k?) in series with capacitor CI (25 pF maximum) is seen by the source.

The capacitor CI voltage VC must be charged to within one-half LSB of the source voltage VS for an

accurate n-bit conversion, where n is the bits of resolution required.

Figure 22-5. Analog Input Equivalent Circuit

The resistance of the source RS and RI affect tsample. The following equation can be used to calculate the

minimum sampling time tsample for a n-bit conversion, where n equals the bits of resolution:

tsample > (RS + RI)

Share this post


Link to post
Share on other sites

void adc_DMA_init(void)
{
  DMACTL0 = DMA0TSEL__ADC10IFG;                  // select adc10 trigger
  __data16_write_addr( (unsigned short)&DMA0SA, (unsigned long)&ADC10MEM0 );   // dma single source address
  __data16_write_addr( (unsigned short)&DMA0DA, (unsigned long)&ADCdata[0] );   // destination array

  DMA0SZ = 64;            // 64 conversions each channel, channels 12-14 selected in main routine after isr exit

  // repeat; increment dest address; enable dma; enable interrupt; high level
  DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN + DMAIE + DMALEVEL;

}

 

According to the code on your sample code (above), I have a few question:

1. Is it that this ADC conversion always get from ADC10MEM0? If I wan to use multiple channels, how does it get the value from it's memory for example ADC10MEM1 or ADC10MEM2?

2. Is it it store on ADCdata[0] array too if I use ADC10MEM1 or ADC10MEM2? Or I need to create another array like ADCdata1[0] or ADCdata[2]?

Share this post


Link to post
Share on other sites

With that ADC10 -> DMA example I posted, it does sample 3 channels but individually instead of a sequence.

 

Psuedo code:

ADC10ENC =1 (on)

Sample 64 times on channel X.

-> loop to fill ADCdata[n]

ADC10ENC =0 (off)

Average X data and output.

Change channels.

ADC10ENC =1 (on)

Sample 64 times on channel Y.

->loop to fill ADCdata[n]

ADC10ENC =0 (off)

Average Y data and output.

Change channels.

ADC10ENC =1 (on)

Sample 64 times on channel Y.

->loop to fill ADCdata[n]

ADC10ENC =0 (off)

Average Z data and output.

 

That example was done that way as the accelerometer on the MSP-EXPFR5739 is on channels 12-14. When it was set to sequentially grab all channels, the ADC10 peripheral will scan channels 0-14. So instead of 64 samples * 3 channels, it was 64 samples * 15 channels. Which took longer and required filtering of the random data from unused channels.

 

If you're using channels 0-2, the ADC10 would be configured a bit differently so it could even more quickly loop and collect all 64 samples * 3 channels.

 

The ADC12 peripheral can be configured for sequential samples in the order you choose, the ADC10 can not.

 

With these methods, all you need is ADC10MEM0. I've looked at the different ADC10MEM_X as being used for different ADC configurations. For example, if I have multiple sensors that all require slightly different SHT settings, I would use ADC10MEM0 for configuration 1, ADC10MEM1 for configuration 2 and so on. However, you will have to reinitialize the DMA for each adc memory block or use multiple DMA channels. For eg, you could have ADC10MEM0 being transferred with DMA0 from channels 0-3 and ADC10MEM1 being transferred with DMA1 from channels 12-14.

Share this post


Link to post
Share on other sites

With these methods, all you need is ADC10MEM0.

So it is mean that using the coding you showed, doesn't matter I use multiple channels like for example from channel 0 to 2 or channel 0 to 15, the conversion will always store in ADC10MEM0?

 

I notice the coding will still use the ADC10CTL1 = ADC10CONSEQ_2 for repeat single channel instead of ADC10CTL1 = ADC10CONSEQ_3 for repeat sequence of channel? Why? I thought we are using multiple channels?

 

So, the ADC conversion is in sequence from channel 0, 1, 2, 3, .... to finally channel 15. Then if my device input is at the last channel, which is channel 15, doesn't we have to wait a long time only get the conversion result? Cause it need to convert all other channels first before getting to channel 15. Then, it will be like my ADC response time is very slow. Is there any solutions to this?

Share this post


Link to post
Share on other sites
So it is mean that using the coding you showed, doesn't matter I use multiple channels like for example from channel 0 to 2 or channel 0 to 15, the conversion will always store in ADC10MEM0?

Yes, if you're using the DMA.

 

I notice the coding will still use the ADC10CTL1 = ADC10CONSEQ_2 for repeat single channel instead of ADC10CTL1 = ADC10CONSEQ_3 for repeat sequence of channel? Why? I thought we are using multiple channels?

We are using multiple channels. However, look at the psuedo code. We're turning the ADC off an on in between channel changes. So, yes we are using multiple channels but manually changing the channel in software. Using repeat_sequence_of_channels with ADC10 peripherals means you pick the last channel of the sequence and it scans through all of them.

So, the ADC conversion is in sequence from channel 0, 1, 2, 3, .... to finally channel 15. Then if my device input is at the last channel, which is channel 15, doesn't we have to wait a long time only get the conversion result? Cause it need to convert all other channels first before getting to channel 15. Then, it will be like my ADC response time is very slow. Is there any solutions to this?

Exactly. If each sample is taking 1ms, taking 64 samples of 15 channels, plus filtering to only use channel 15's data, is going to take some time. If you only need channel 15, use that example I posted but remove the 2nd and 3rd adc starts and change the adc channel to 15.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...