ADC

=__**Introduction**__:=

An ADC is an electronic device that allows to convert an analog value of voltage or current to a digital number proportional to the magnitude of the voltage or current which will be used by a micro controller.All the voltages we measure in electrical circuits are analog in nature.So they have to be converted to a digital lnumber to be fed to the microcontroller for processing.An analog signal has infinite resolution theoretically.But a digital signal will have a finite resolution depending on the number of bits available to store the corresponding number. MSP 430 device have mostly 10 bit and 12 bit ADC available .We will be discussing 10 bit ADC for the time being. For the ADC value, there will be two reference voltages to be defined V+ and V-.Hence for a 10 bit ADC, if the input voltage is Vin. Then the digital value is equal to 1023X (Vin-V-)/(V+ - V-) //Example// : Voltage comparator---Take two dc voltages as input and compare their digital values //Basic Idea ://
 * Input the two analog voltages to the microcontroller
 * Convert the analog values to their digital values by enabling ADC
 * Compare the two digital numbers
 * We can use 2 different coloured LEDs to show the result of the comparison


 * KEY POINTS FOR USING ADC IN MSP430** :
 * Disable Watchdog timer (discussed in another tutorial)


 * Define two input channels for the analog inputs out of 8 available channels


 * Select a clock source for the ADC conversion


 * Select a mode for the functioning of ADC like continuous or one-time conversion


 * Select the Reference voltages for ADC .For example 0V and 5V.


 * Select the Sample and Hold Time for the ADc conversion


 * Enable the corresponding pin for ADC input


 * Switch ON ADC


 * Enable ADC


 * Read the value after conversion

__**Inputting the voltages :**__ There are 8 channels available in msp430 where we can input the analog voltages for the ADC conversion. We need 2 input channels presently for the voltage comparator. Look up to the datasheet for the msp430 device you are using. We have used MSP430x2xxx devices for our purpose. The selection of the input channels is done by ADC Control Register 1 or //ADC10CTL1// (10 stands for the 10 bit ADC and CTL stands for Control register).

Suppose we want to use Channels 4 and 5 for the analog inputs.It will be done as follows : INPUT_1 and INPUT_2 are the name of the macros which can be edited and can be given any name. INCH is defined in ADC10CTL register wich will be clear after looking up in the datasheet.
 * define INPUT_1 INCH_4**
 * define INPUT_2 INCH_5**

__**CLOCK SOURCE SELECTION**__ : So far we have selected the input channels we will be using .Now we know that ADc need a clock to work on.So we have to select a clock source for ADC and a clock divider factor if required. These are also done in ADC10CTL1 register 00 => ADC10OSC 01 => ACLK 10 => MCLK 11 => SMCLK
 * ADC10SSELx** --ADC10 clock source select

We can select any clock source by the following command : //ADC10CTL1= ADC10SSEL_0;// Or //ADC10CTL1=ADC10SSEL_1;// Or //ADC10CTL1=ADC10SSEL_1;// Or //ADC10CTL1=ADC10SSEL_1;//

The clock factor can be selected by **ADC10DIV** command. For a factor of 4, we need to do the following : //ADC10CTL1=ADC10DIV_3//; Look up in the datasheet for different conversion factors.

__**ADC Conversion MODES**__ : There are 4 modes available for conversion : These modes can be selected by **CONSEQx** Bits in **ADC10CTL1** register. We will be showing the use of Single conversion with single channel mode as it will be easier to implement in our program.Since we are using 2 input channels, we have to call the function two times and implement a for OR while loop for continuous conversion.
 * Single channel, Single conversion
 * Sequence of channels
 * Repeat single channel
 * Repeat sequence of channels

__**REFERENCE VOLTAGE SELECTION**__ : The reference voltage selection is very important and is dependent on the nature of task we need to perform. Reference voltage selection is done using **SREF** bits in **ADC10CTL0** register. If we do //ADC10CTL0=SREF_0//; it will select Vcc as positive reference voltage and ground as negative reference voltage. If we want to change the reference voltage the **REFON** bit must be set and other reference voltages can be used.

__**SAMPLE AND HOLD TIME SELCTION**__ : The Sampling time is very important for the ADC conversion .The more is the sampling time, the better will be the accuracy of the digital value we get after conversion. We can select a certain number of Clock cycles to be used for ADC sampling. //ADC10SHT_0// => 4 Clock Cycles //ADC10SHT_1// => 8 Clock Cycles //ADC10SHT_2// => 16 Clock Cycles //ADC10SHT_3// => 64 Clock Cycles

__**Enable Analog inputs**__ : Analog Enable control register **ADC10AE0** will be use for enabling the corresponding the input channels. Since we are using channels 4 and 5, we need to enable these two channels. Channel 4 can be enabled by : ADC10AE0 = 0x10; //0x10=0b00010000// => channel 4 Channel 5 can be enabled by //: ADC10AE0 = 0x20; 0//x20=0b00100000 => channel 5

__**ENABLE ADC**__ : ADC enable pins are available in ADC10 Control register 0. There are 2 commands we need to implement : //ADC10CTL0 = ADC10ON;// //ADC10CTL0= ENC;// //ENC// stands for ENable Conversion

The ADC core converts an analog input to its 10 bit digital representation and stores the result in the **ADC10MEM** register. The digital output will be equal to the positive reference voltage if input voltage is greater than the positive reference voltage and will be equal to the negative reference voltage if it is less than the negative reference voltage.After the conversion, we can store the digital value in a variable //:// //Unsigned int adc_value = ADC10MEM;//
 * __READING THE DIGITAL VALUE AFTER CONVERSION__** //://

//**SUMMARY OF THE REGISTERS USED** :// //**ADC10CTL0** :Used for #Reference voltage selection// //#Sample and Hold Time Selection// //#enable ADC// //#storing Interrupt Flag// //**ADC10CTL1**: used for # input channel selection// //#clock source selection// //#Conversion sequence mode selection// //**ADC10AE0**: used for #enable analog input channel// //**ADC10MEM** : used for # storing the digital value after the end of the ADC conversion//

__**INTERRUPT FLAG**__ //:// How do we know that a conversion is completed ? This is done through checking the status of Interrupt flag bit (**ADC10IFG**) present in **ADC10CTL0** register. The flag bit is set when **ADC10MEM** is loaded with a conversion result. It is automatically reset when the interrupt flag is accepted, or it may be reset by software. //ADC10IFG = 0 =>//No interrupt is pending //ADC10IFG =1 =>//Interrupt pending

//**CODING** ://

//**Step 1** : a) D//efine main and required variables //.// //b) C//all a function to do the ADC conversion which will return the digital value. //c) C//all the function once again for obtaining the digital value of second input. //d) C//ompare the two digital values and blink two LEDs depending on the result //.//

//#include "msp430g2452.h"// //unsigned int adcvalue1 = 0;// variable for storing digital value of CH4 input unsigned int adcvalue2 = 0; //variable for storing digital value of CH5 input// //#define INPUT_1 INCH_4// //#define INPUT_2 INCH_5// //unsigned int analogRead(unsigned int pin) {// ...................... ...................... return ADC10MEM; }

//void main(void) {// //WDTCTL = WDTPW + WDTHOLD;// Stop Watchdog Timer P1DIR = 0x41; //P1.0=>LED1 and P1.6=>LED2//

//while(1){// //adcvalue1 = analogRead( INPUT_1 );// Read the analog input from channel 4 adcvalue2 = analogRead( INPUT_2 ); //Read the analog input from channel 5// //if ((adcvalue1>adcvalue2)){// //P1OUT = BIT6;// Glow LED2 if channel4 input > channel5 input } if ((adcvalue2>adcvalue1)){ P1OUT = BIT0; //Glow LED1 if channel4 input > channel5 input// //}// //}// //}//

//**STEP 2**// : **FUNCTION BODY** a) Switch ON ADC. b) Select sampling time. c) Choose appropriate clock source and reference voltages. d) Enable input channel 4 when taking the digital value of channel 4 and enable input channel 5 when taking the digital value of channel5. e) After the completion of conversion, reset the flag and enable conversion bits.


 * CODE FOR THE FUNCTIN BODY** :

//unsigned int analogRead(unsigned int pin) {// //ADC10CTL0 = ADC10ON + ADC10SHT_2 + SREF_0;// //ADC10CTL1 = ADC10SSEL_0 + pin;// //if (pin==INCH_4){// //ADC10AE0 = 0x10;// //}// //else if(pin==INCH_5){// //ADC10AE0 = 0x20;// //}// //ADC10CTL0 |= ENC + ADC10SC;// //while (1) {// //if (((ADC10CTL0 & ADC10IFG)==ADC10IFG)) {// //ADC10CTL0 &= ~(ADC10IFG +ENC);// //break;// //}// //}// //return ADC10MEM;// //}//

=__**FULL CODE**__ :=

//#include "msp430g2452.h"// //#define INPUT_1 INCH_4// //#define INPUT_2 INCH_5//

//unsigned int adcvalue1 = 0;// variable for storing digital value of CH4 input unsigned int adcvalue2 = 0; //variable for storing digital value of CH5 input//

//unsigned int analogRead(unsigned int pin) {// //ADC10CTL0 = ADC10ON + ADC10SHT_2 + SREF_0;// //ADC10CTL1 = ADC10SSEL_0 + pin;// //if (pin==INCH_4){// //ADC10AE0 = 0x10;// //}// //else if(pin==INCH_5){// //ADC10AE0 = 0x20;// //}// //ADC10CTL0 |= ENC + ADC10SC;// //while (1) {// //if (((ADC10CTL0 & ADC10IFG)==ADC10IFG)) {// //ADC10CTL0 &= ~(ADC10IFG +ENC);// //break;// //}// //}// //return ADC10MEM;// //}//

//void main(void) {//

//WDTCTL = WDTPW + WDTHOLD;// Stop Watchdog Timer P1DIR = 0x41; //P1.0=>LED1 and P1.6=>LED2//

//while (1){// //adcvalue1 = analogRead( INPUT_1 );// Read the analog input from channel 4 adcvalue2 = analogRead( INPUT_2 ); //Read the analog input from channel 5// //if ((adcvalue1>adcvalue2)){// //P1OUT = BIT6;// Glow LED2 if channel4 input > channel5 input } if ((adcvalue2>adcvalue1)) { P1OUT = BIT0; //Glow LED1 if channel4 input > channel5 input// //}// //}//

//}//