How to write a C Program to Implements an 8-bit sample and hold ADC on the MSP430 using its onboard comparator and transmission gate in C Programming Language ?
This C Program Implements an 8-bit sample and hold ADC on the MSP430 using its onboard comparator and transmission gate.
I/O Ports:
P1.0 <-> CA0 (sampling capacitor)
P1.1 <- CA1 (Vin)
P1.2 <- CA2 (resistor network ramp)
P1.4 -> /CS (DAC)
P1.5 -> SCLK (DAC)
P1.7 -> SD1 (DAC)
P2.0 -> BIT0 (resistor network)
P2.1 -> BIT1 (resistor network)
P2.2 -> BIT2 (resistor network)
P2.3 -> BIT3 (resistor network)
P2.4 -> BIT4 (resistor network)
P2.5 -> BIT5 (resistor network)
P2.6 -> BIT6 (resistor network)
P2.7 -> BIT7 (resistor network)
Solution:
- #include <msp430.h>
- /*
- * main.c
- *
- * Title: Project 3 ADC Fun!
- *
- * Authors: Daniel Hodges & Omar Arriaga
- *
- * Description: Implements an 8-bit sample and hold ADC on the MSP430 using its onboard comparator
- * and transmission gate.
- *
- * I/O Ports:
- *
- * P1.0 <-> CA0 (sampling capacitor)
- * P1.1 <- CA1 (Vin)
- * P1.2 <- CA2 (resistor network ramp)
- * P1.4 -> /CS (DAC)
- * P1.5 -> SCLK (DAC)
- * P1.7 -> SD1 (DAC)
- *
- * P2.0 -> BIT0 (resistor network)
- * P2.1 -> BIT1 (resistor network)
- * P2.2 -> BIT2 (resistor network)
- * P2.3 -> BIT3 (resistor network)
- * P2.4 -> BIT4 (resistor network)
- * P2.5 -> BIT5 (resistor network)
- * P2.6 -> BIT6 (resistor network)
- * P2.7 -> BIT7 (resistor network)
- *
- */
- void CLK16MHz();
- void portsSetup();
- void sampleInput();
- void compareInput();
- void Drive_DAC(unsigned int level);
- int ramp_Value = 0;
- int DAC_Value = 0;
- int main(void) {
- WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
- CLK16MHz(); // set clock to 16MHz
- portsSetup(); // setup and initialize ports
- _enable_interrupts(); // enable interrupts
- // samples input, determines input, sends sample to DAC
- while(1){
- sampleInput(); // sample Vin and hold for cap to charge
- compareInput(); // compare sampled Vin to a 0 to Vcc ramp
- // interrupt will trigger once CAOUT goes low
- Drive_DAC(DAC_Value); // send new sample to DAC
- }
- }
- // set SMCLK to 16MHZ
- void CLK16MHz(){
- // 16Mhz SMCLK
- if (CALBC1_16MHZ==0xFF) // If calibration constant erased
- {
- while(1); // do not load, trap CPU!!
- }
- DCOCTL = 0; // Select lowest DCOx and MODx settings
- BCSCTL1 = CALBC1_16MHZ; // Set range
- DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation
- }
- // initialize and setup ports
- void portsSetup(){
- /*****************************
- * Resistor Network Setup *
- ****************************/
- // Set P2.6,7 as GPIO ports
- P2SEL &= ~(BIT7 + BIT6);
- P2SEL2 &= ~(BIT7 + BIT6);
- P2DIR |= 0xFF; // Set Port2.0-7 as outputs for resistor network
- /*****************************
- * Comparator A Setup *
- ****************************/
- CAPD |= CAPD0 + CAPD1 + CAPD2; // Disable input buffer for CA0, CA1, CA2
- CACTL1 |= CAIES + CAIE; // Comparator interrupt enable, falling edge
- // select CA0 for first mux
- CACTL2 |= P2CA0;
- CACTL2 &= ~(P2CA4);
- /*****************************
- * DAC and SPI Setup *
- ****************************/
- P1SEL = BIT7 + BIT5; // These two lines dedicate P1.7 and P1.5
- P1SEL2 = BIT7 + BIT5; // for UCB0SIMO and UCB0CLK respectively
- P1DIR |= BIT4; // P1.4 used to activate /CE on DAC
- // SPI Setup
- // clock inactive state = low,
- // MSB first, 8-bit SPI master,
- // 4-pin active Low STE, synchronous
- //
- // 4-bit mode disabled for now
- UCB0CTL0 |= UCCKPL + UCMSB + UCMST + /* UCMODE_2 */ + UCSYNC;
- UCB0CTL1 |= UCSSEL_2; // UCB0 will use SMCLK as the basis for
- // the SPI bit clock
- UCB0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
- // SPI now Waiting for something to
- // be placed in TXBUF.
- }
- // samples Vin on sampling capacitor
- void sampleInput(){
- // select CA1 (Vin) for second mux
- CACTL2 |= P2CA1;
- CACTL2 &= ~(P2CA2 + P2CA3);
- CACTL2 |= CASHORT; // turn on transmission gate to start sampling
- _delay_cycles(1500); // delay for sampling cap to charge
- CACTL2 &= ~CASHORT; // turn off transmission gate to end sampling
- }
- // compares sample on sampling capacitor to 0 to Vcc ramp
- void compareInput(){
- // select CA2 (ramp) for second mux
- CACTL2 |= P2CA2;
- CACTL2 &= ~(P2CA1 + P2CA3);
- CACTL1 |= CAON; // turn comparator on
- // start ramp from 0 to Vcc using resistor network
- for(ramp_Value = 0; ramp_Value < 256; ramp_Value++){
- P2OUT = ramp_Value;
- }
- CACTL1 &= ~CAON; // turn comparator off
- P2OUT = 0; // set ramp back to 0
- }
- // Drives DAC through SPI; takes value from 0 to 4096
- void Drive_DAC(unsigned int level){
- unsigned int DAC_Word = 0;
- DAC_Word = (0x3000) | (level & 0x0FFF); // 0x1000 sets DAC for Write
- // to DAC, Gain = 1, /SHDN = 1
- // and put 12-bit level value
- // in low 12 bits.
- P1OUT &= ~BIT4; // Clear P1.4 (drive /CS low on DAC)
- // Using a port output to do this for now
- UCB0TXBUF = (DAC_Word >> 8); // Shift upper byte of DAC_Word
- // 8-bits to right
- while (!(IFG2 & UCB0TXIFG)); // USCI_A0 TX buffer ready?
- UCB0TXBUF = (unsigned char)
- (DAC_Word & 0x00FF); // Transmit lower byte to DAC
- while (!(IFG2 & UCB0TXIFG)); // USCI_A0 TX buffer ready?
- P1OUT |= BIT4; // Set P1.4 (drive /CS high on DAC)
- return;
- }
- // Comparator A interrupt service routine
- #pragma vector=COMPARATORA_VECTOR
- __interrupt void Comparator_A (void)
- {
- DAC_Value = (ramp_Value * 12); // convert and store current ramp_Value in DAC_Value
- }