#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
}