This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADC10SC won't trigger ADC sampling and convert

Other Parts Discussed in Thread: MSP430G2332, MSP430WARE

Hi all,

This is my first project with an MSP430, namely the MSP430G2332. I am trying to implement the ADC10 functionality, in "single-channel, single-conversion" mode, triggered by setting the ADC10SC bit in ADC10CTL0. My understanding from the User Guide is that, as long as everything is configured correctly all I need to do is set the ADC10SC bit to trigger an ADC sample and convert, with the result being made available in ADC10MEM.

Unfortunately I must be doing something wrong, as my code below does not trigger an ADC sample and convert. I can, however, get it to work properly if I toggle ENC manually, but from my understanding of the User Guide this should not be necessary. Can anyone see what it is that I'm missing?

Here is my code, many thanks in advance for any suggestions!:

(main.cpp)

#include <msp430.h>

void initialise(void) {
	/* ADC Control register 0 settings:
	 * ADC10ON		- enables ADC
	 * REFON 		- enables use of internal voltage reference
	 * SREF_1		- uses internal voltage reference as ADC reference
	 * REF2_5V 		- sets internal voltage reference to 2.5V
	 * ADC10SR		- "Sample Rate" bit reduces current consumption (sampling rate must be < 50ksps)
	 * ADC10SHT_3	- "Sample and Hold Time", sets sampling period to 64 clock cycles
	 * */
	ADC10CTL0 = ADC10ON + REFON + SREF_1 + REF2_5V + ADC10SR + ADC10SHT_3;
	/* ADC Control register 1 settigns:
	 * SHS_0		- "Sample and Hold Source", ADC sampling is triggered by setting ADC10SC (not triggered by timers)
	 * ADC10DIV_7	- Clock divisor set to 7
	 * ADC10SSEL_2	- ADC clock set to MCLK
	 * */
	ADC10CTL1 = SHS_0 + ADC10DIV_7 + ADC10SSEL_2;
	/* "Analog Enable" - Disables port pin buffer on pins being used for analog
	 * sensing (eliminates risk of possible parasitic current increasing power
	 * consumptionfrom analog signals on these pins that are near the digital
	 * threshold level) */
	ADC10AE0 = BIT2;
}

// Read ADC on channel A2
unsigned int readADC(void) {
	// Select ADC channel 2 to sample and convert.
	// Channel to convert is defined by INCHx, in the upper 4 bits in ADCCTRL1
	ADC10CTL1 |= INCH_2;
	// Issue instruction to sample and convert, by setting ADC10SC bits in ADCCTRL0
	ADC10CTL0 |= ADC10SC;
	// Wait whilst sample is being taken and converted, and stored in ADC10MEM
	// by checking the ADC10BUSY bit in ADCCTRL1
	while( (ADC10CTL1 & ADC10BUSY) );
	// Save ADC reading in results array
	unsigned int val = ADC10MEM;
	return val;
}

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    initialise();
    for(;;) {
    	unsigned int ADC_reading = readADC();
    	// Now do something with ADC_reading
    }
    return 0;
}

  • You should change the functionality of the default GPIO pin you are using for ADC input.
  • Refer some examples.
    there are plenty of examples in msp430ware driver library.
  • I do agree that only setting (SC | ENC) simultaneously seems to work. And I thought (from reading the manual) setting ENC once and start a sample via SC should do the job, too. But same behaviour in my experience.
  • Without Changing the default GPIO pin functionality ADC will not know which is input channel.
    so provide that and you will get your results
  • That's not correct. The pin is controlled by the ADC10AE.x bits which is set for bit 2 in the posted code.

    Look at table 14 on page 36 of the datasheet:

    The behaviour described has nothing to do with the pin-configuration.

    Dennis

  • You don’t need to toggle ENC but you need to set it at least once!

    And be careful with “ADC10CTL1 |= INCH_2;”. If you had previously selected another channel ORing here might give you the wrong channel. First clear with AND all channel bits.

  • Yes, I would imagine it to be like that, but I have experienced the same behaviour. Setting ENC once and then only

    |= SC

    will not cause a sampling, but setting

    |= (ENC | SC)

    will do.
  • The ENC bit must be set at the end of the ADC initialization, otherwise it can be cleared by a –wrongly configured- operating mode, but also other configuration bits can be ignored when ENC already is set.
  • OK, I did not set it at the end of the configuration - I set it with all other bits in the ADC10CTL0 register with one instruction. But of course I did not overwrite it with other settings. Anyway, if setting it at the end will do the job I will try the next time I use the ADC10 again.
  • Thanks all for your fast and helpful answers. Do we conclude then that it's the User Guide at fault for suggesting that ENC does not need to be toggled when it's configured in the way I have (Single-Channel, Single-Conversion Mode with ADC10SC as the trigger source), when actually it does? For reference I have pasted in the relevant passage from the User Guide on pg. 554 of SLAU144I:


    22.2.6.1 Single-Channel Single-Conversion Mode
    A single channel selected by INCHx is sampled and converted once. The ADC result is written to ADC10MEM. Figure 22-5 shows the flow of the single-channel, single-conversion mode. When ADC10SC triggers a conversion, successive conversions can be triggered by the ADC10SC bit. When any other trigger source is used, ENC must be toggled between each conversion.


    To me is seems pretty clear from this passage that ENC does not need to be touched when ADC10SC is used as the trigger source. Am I reading this wrong? Is the User Guide misrepresenting this? Or is there something we are missing? I am happy to keep on toggling the ENC bit as it does seem to work, but it does seem a bit Heath Robinson if in fact it is not actually necessary, and is only the result of something else that I am doing wrong.

    In reply to some of the other helpful suggestions posted so far:

    • Leo - My use of ADC10CTL1 |= INCH_2 to set the sampling channel is a replacement for the original loop I had in there to sample a number of channels, as I thought I'd extract only the most relevant lines of code to this discussion. In the original I am careful to make sure this channel set is done correctly but I can see that as this forum serves as reference to many other people it's best to use better practice even for example code! Sorry about that.
    • Because I need to sample a number of channels I need to clear the ENC bit after each sample so I can modify ADC10CTL0 with a new "INCH", so I can't get away with setting ENC after initialisation. As described on pg.550 of SLAU144I: The ADC10 core is configured by two control registers, ADC10CTL0 and ADC10CTL1. The core is enabled with the ADC10ON bit. With few exceptions the ADC10 control bits can only be modified when ENC = 0. ENC must be set to 1 before any conversion can take place.
    • Sunil - thanks for your suggestion about taking a look at some of the examples from MSP430Ware - I have downloaded this and will have a peruse today.
  • Edward Matos said:
    When any other trigger source is used, ENC must be toggled between each conversion.

    Edward Matos said:
    To me is seems pretty clear from this passage that ENC does not need to be touched when ADC10SC is used as the trigger source.

    It doesn’t say that, it says “Between conversions”.

    Edward Matos said:
    ENC must be set to 1 before any conversion can take place.

    And here you see that it ‘Must’ be set.

    Where to set ENC differs on the use of the ADC and their channels. Sometimes an ADC can add a delay after changing his configuration but this applies more to the SD converters.

    In your case it’s good to use ENC and SC at the same time, and finish the conversion with clearing the ENC bit.

  • Great, I can see now that I was reading it wrong - I thought as much! In this mode, ENC toggling is required between sampling channels, not as a botch, but as a well-documented part of the functionality. Thank you Leo for clarifying that.

**Attention** This is a public forum