/*
* main.c
*
* Title: Assignment 4 Waveform Generation (Triangle Wave)
*
* Authors: Daniel Hodges & Omar Arriaga
*
* Description: Interfaces with the MCP4921 DAC via SPI to generate
* a 2Vpp triangle wave with 1VDC offset and a period of 20ms using timers.
*
*/
#include <msp430g2553.h>
void Drive_DAC(unsigned int level);
int ISRcounter = 0;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
// 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
// Init Ports
P1DIR |= BIT4; // Will use BIT4 to activate /CE on the DAC
P1SEL = BIT7 + BIT5; // These two lines dedicate P1.7 and P1.5
P1SEL2 = BIT7 + BIT5; // for UCB0SIMO and UCB0CLK respectively
// 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.
// set up SMCLK timer
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 98;
TACTL = TASSEL_2 + MC_2; // SMCLK, contmode
_enable_interrupts(); // enable interrupts
while(1){
// if statement determines when
// to increment/decrement DAC output
if (ISRcounter <= 1638){ // increments DAC output from 0 to 2V
Drive_DAC(ISRcounter);
}
else if(ISRcounter > 1638 & ISRcounter < 3276){ // decrements DAC output from 2 to 0V
Drive_DAC(3276-ISRcounter);
}
else{ // resets ISRcounter back to 0 to start over again
ISRcounter = 0;
Drive_DAC(ISRcounter);
}
}
}
// 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); // 0x3000 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;
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
ISRcounter++; // Increment ISRcounter
CCR0 += 98; // Extend timer by 6.125us
}