The ADC12 module of the MSP430 microcontroller is a 12-bit precision A/D conversion module, which has the characteristics of high speed and versatility. Most of them have built-in ADC modules. Some chips without ADC modules can also realize AD conversion by using the built-in analog comparator. In the series of products, we can simply understand their ADC function implementation through the following list. Series model ADC function to achieve conversion accuracy MSP430X1XX2 comparator to achieve 10 bits MSP430F13X ADC module 12 bits MSP430F14X ADC module 12 bits MSP430F43X ADC module 12 bits MSP430F44X ADC module 12 bits MSP430X32X ADC module 14 bits As can be seen from the ADC12 structure diagram below, the ADC12 module is composed of the following parts: 16-way analog switch input, ADC internal voltage reference source, ADC12 core, ADC clock source part, acquisition and hold/trigger source part, ADC data output part, ADC control register, etc. 16-way analog switch input The 16-way analog switch is input by 8 analog signals outside the IC and 4 internal reference power inputs, 1 internal temperature sensor source and AVCC-AVSS/2 voltage source. The external 8-way input is from A0-A7, which is mainly the analog variable signal during external measurement. The internal 4-way is the output positive terminal of Veref+ ADC internal reference power supply, Vref-/Veref- ADC internal reference power supply negative terminal (internal/external). 1 AVCC-AVSS/2 voltage source and 1 internal temperature sensor source. The on-chip temperature sensor can be used to measure the temperature on the chip, which can be used to make some useful controls during design; it is used more in practical applications. Other power reference source inputs can be used to verify ADC12 and can be used for self-calibration during design. ADC internal voltage reference source The ADC voltage reference source is used as a reference signal for the ADC12 core, which is an indispensable part of the ADC. In the ADC12 module, the reference voltage source can be set to 6 different combinations through software. AVCC (Vr+), Vref+, Veref+, AVSS (Vr-), Vref-/Veref-. ADC12 core The module core of ADC12 is shared, and the acquisition input is completed separately through the front-end analog switch. ADC12 is an ADC core with a precision of 12 bits, 1 bit of nonlinear differential error, and 1 bit of nonlinear integral error. The core will refer to two reference voltages during conversion. One is the reference relative maximum input maximum value. When the analog variable output by the analog switch is greater than or equal to the maximum value, the output digital quantity of the ADC core is full scale, that is, 0xfff; the other is the minimum value. When the analog variable output by the analog switch is greater than or equal to the maximum value, the output digital quantity of the ADC core is the lowest range, that is, 0x00. These two reference voltages can be set by software programming. ADC clock source part ADC12 clock sources are divided into ADC12OSC, ACLK, MCLK, SMCLK. One of the clock sources can be selected through programming, and the frequency can be appropriately divided. Acquisition and holding, trigger source part The ADC12 module has a good acquisition and holding circuit, and it has flexible applications with different settings. For details about this, please refer to the register description in the manual. We will make up for this part later. ADC data output section: Each time the ADC core completes a conversion, it will store the output result of the corresponding channel into the corresponding channel buffer unit. There are 16 channel buffer units in total. At the same time, the 16 channel buffer units have corresponding control registers to achieve more flexible control. ADC Control Registers ADC12CTL0 Conversion Control Register 0 ADC12CTL1 Conversion Control Register 1 ADC12IE Interrupt Enable Register ADC12IFG Interrupt Flag Register ADC12IV Interrupt Vector Register ADC12MEM0-15 Storage Control Registers 0-15 ADC12MCTL0-15 Storage Control Registers 0-15 MSP430 ADC12 Module Structure Diagram ADC12 Should Have Routine //****************************************************************************** #include //****************************************** ***** //Table area unsigned char number_table[]={'0','1','2','3', '4','5','6','7','8','9'}; unsigned char display_buffer[]={0x00,0x00,0x00,0x00,0xff}; //************** *****Baud rate**********300 600 1200 2400 4800 9600 19200 38400 76800 115200const //************************************[0]**[1 ]**[2]*[3]**[4]**[5]***[6]***[7]****[8]***[9]* unsigned char BaudrateUBR0[] ={0x6D,0x36,0x1B,0x0D,0x06,0x03, 0xA0, 0xD0, 0x68, 0x45}; unsigned const char BaudrateUBR1[] ={0x00,0x00,0x00,0x00,0x00,0x00, 0x01, 0x00, 0x00, 0x00}; [ size=4]unsigned const char BaudrateUMCTL[]={0x22,0xD5,0x03,0x6B,0x6F,0x4A, 0xC0, 0x40, 0x40, 0x4A}; unsigned char timp;[/ size] //Variable area unsigned int ADC0 ; //Subroutine declaration void init (void); //Initialization void ADC12setup(void); //ADC12 initialization void BaudrateSetup(unsigned char U0); //UART0 initialization void data_converter(unsigned char *p,unsigned int vaule); //Data conversion void send_data(unsigned char *p); //Serial port sends array //******* ************************************* void main(void ) { init(); //Main loop for (;; ) { LPM0; ADC12CTL0 |= ADC12SC; //sampling open, after AD conversion is completed (ADC12BUSY=0) ,ADC12SC automatically resets; while((ADC12IFG & BIT0) == 0); //Wait for the conversion to end ADC0 = ADC12MEM0; //Read the converted data value and clear the ADC12IFG0 flag at the same time data_converter(display_buffer,ADC0); //Data conversion send_data(display_buffer); //Send data /size] } } //*********** ************************************************** ******************* void init(void) { [size= 4] WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR=0x01;P1OUT=0x0f; //LED settings BaudrateSetup(6);[/size ] ADC12setup(); _EINT(); // Global interrupt enable } ]//*************************************************** *********************************** //Serial port receiving interrupt, Exit LPM0 mode. #pragma vector=USART0RX_VECTOR __interrupt void usart0_rx (void) { LPM0_EXIT; } //******************** *************************************************** ************ //ADC12 initialization void ADC12setup(void) {[ /size] //ADC12 settings**************************** P6SEL |= 0x01; //Use A/D channel A0 ADC12CTL0 = ADC12ON; //Open ADC12 core, set SHT0=2 (N=4) ADC12CTL1 = SHP ; //SAMPCON signal is selected as sampling timer output //ADC12 Internal reference voltage setting ADC12CTL0 |= REF2_5V; //Select the internal reference voltage as 2.5V ADC12CTL0 |= REFON; //Internal reference voltage turned on [/size ] ADC12MCTL0 |= SREF_1; //R+=2.5V R-=VSS //Conversion allowed ADC12CTL0 |= ENC ; // Conversion enabled (rising edge) ADC0 = 0x00;} //****************************************** ******************************************* [size= 4]//UART0 initialization void BaudrateSetup(unsigned char U0) { unsigned int i; [ size=4] if(U0>5) //When U0>5, enable XT2 { BCSCTL1 &= ~XT2OFF; //Start XT2, do { IFG1 &= ~OFIFG; //Clear the OSCFault flag for(i=0xFF;i>0; i--); //Delay waiting } while((IFG1 & OFIFG) != 0); //Check OSCFault, when it is 0, the conversion is complete BCSCTL2 |= SELS; //SMCLK is XT2 } //UART0 P1OUT=0x00; if(U0>5){UTCTL0=SSEL1 ;} // Clock source: SMCLK else{UTCTL0=SSEL0;} // Clock source: ACLK UCTL0 &= ~SWRST; // SWRST reset, USART Enable UCTL0=CHAR; // 8bit ME1|=UTXE0 + URXE0; // Enable Tx0,Rx0 IE1|=URXIE0; // RX enable UBR00=BaudrateUBR0[U0]; // Low divider factor [ size=4] UBR10=BaudrateUBR1[U0]; // High-order divider factor UMCTL0=BaudrateUMCTL[U0]; // Baud rate adjustment factor P3SEL |= 0x30; // Set P3.4,5 to use peripheral module = USART0 TXD/RXD P3DIR |= 0x10; // Set P3.4 to output (send), P3. 5Default is input (receive) } //******************************************* *************************************** // Data conversion void data_converter(unsigned char *p,unsigned int value) { unsigned int m,n,j=0; p[0]=number_table[value/1000]; m=value%1000; p [1]=number_table[m/100]; n=m%100; p[2]=number_table[n/10]; j=n%10; p[3]=number_table[j/1];[/ size] } //************************ *************************************************** ********** //Serial port sends array void send_data(unsigned char *p) {unsigned int n; timp=RXBUF0; for(n=0;p[n]!=0xff;n++)[/ size] { while ((IFG1 & UTXIFG0) == 0); // USART0 sends UTXIFG0=1, indicating that UTXBUF is ready to send the following character [size =4] TXBUF0 = p[n]; } } //********* ************************************************** *********************** //ADC12 module routine ends