Waveform Generation (Triangle Wave) C Program

How to write a Waveform Generation (Triangle Wave) program in C Programming Language ?


  1. /*
  2.  * main.c
  3.  *
  4.  * Title: Assignment 4 Waveform Generation (Triangle Wave)
  5.  *
  6.  * Authors: Daniel Hodges & Omar Arriaga
  7.  *
  8.  * Description: Interfaces with the MCP4921 DAC via SPI to generate
  9.  * a 2Vpp triangle wave with 1VDC offset and a period of 20ms using timers.
  10.  *
  11.  */
  12. #include <msp430g2553.h>
  13. void Drive_DAC(unsigned int level);
  14. int ISRcounter = 0;
  15. int main(void)
  16. {
  17.   WDTCTL = WDTPW + WDTHOLD;          // Stop watchdog timer
  18.   // 16Mhz SMCLK
  19.   if (CALBC1_16MHZ==0xFF)            // If calibration constant erased
  20.   {
  21.     while(1);                        // do not load, trap CPU!!
  22.   }
  23.   DCOCTL = 0;                        // Select lowest DCOx and MODx settings
  24.   BCSCTL1 = CALBC1_16MHZ;            // Set range
  25.   DCOCTL = CALDCO_16MHZ;             // Set DCO step + modulation
  26.   // Init Ports
  27.   P1DIR |= BIT4;                     // Will use BIT4 to activate /CE on the DAC
  28.   P1SEL  = BIT7 + BIT5;              // These two lines dedicate P1.7 and P1.5
  29.   P1SEL2 = BIT7 + BIT5;              // for UCB0SIMO and UCB0CLK respectively
  30.   // SPI Setup
  31.   // clock inactive state = low,
  32.   // MSB first, 8-bit SPI master,
  33.   // 4-pin active Low STE, synchronous
  34.   //
  35.   // 4-bit mode disabled for now
  36.   UCB0CTL0 |= UCCKPL + UCMSB + UCMST + /* UCMODE_2 */ + UCSYNC;
  37.   UCB0CTL1 |= UCSSEL_2;               // UCB0 will use SMCLK as the basis for
  38.                                       // the SPI bit clock
  39.   UCB0CTL1 &= ~UCSWRST;               // **Initialize USCI state machine**
  40.                                       // SPI now Waiting for something to
  41.                                       // be placed in TXBUF.
  42.   // set up SMCLK timer
  43.   CCTL0 = CCIE;                       // CCR0 interrupt enabled
  44.   CCR0 = 98;
  45.   TACTL = TASSEL_2 + MC_2;            // SMCLK, contmode
  46.   _enable_interrupts();               // enable interrupts
  47.   while(1){
  48.         // if statement determines when
  49.         // to increment/decrement DAC output
  50.         if (ISRcounter <= 1638){                        // increments DAC output from 0 to 2V
  51.                 Drive_DAC(ISRcounter);
  52.         }
  53.         else if(ISRcounter > 1638 & ISRcounter < 3276){ // decrements DAC output from 2 to 0V
  54.             Drive_DAC(3276-ISRcounter);
  55.         }
  56.         else{                                           // resets ISRcounter back to 0 to start over again
  57.                 ISRcounter = 0;
  58.                 Drive_DAC(ISRcounter);
  59.         }
  60.   }
  61. }
  62. // Drives DAC through SPI; takes value from 0 to 4096
  63. void Drive_DAC(unsigned int level){
  64.   unsigned int DAC_Word = 0;
  65.   DAC_Word = (0x3000) | (level & 0x0FFF);   // 0x3000 sets DAC for Write
  66.                                             // to DAC, Gain = 1, /SHDN = 1
  67.                                             // and put 12-bit level value
  68.                                             // in low 12 bits.
  69.   P1OUT &= ~BIT4;                           // Clear P1.4 (drive /CS low on DAC)
  70.                                             // Using a port output to do this for now
  71.   UCB0TXBUF = (DAC_Word >> 8);              // Shift upper byte of DAC_Word
  72.                                             // 8-bits to right
  73.   while (!(IFG2 & UCB0TXIFG));              // USCI_A0 TX buffer ready?
  74.   UCB0TXBUF = (unsigned char)
  75.                        (DAC_Word & 0x00FF); // Transmit lower byte to DAC
  76.   while (!(IFG2 & UCB0TXIFG));              // USCI_A0 TX buffer ready?
  77.   P1OUT |= BIT4;                            // Set P1.4   (drive /CS high on DAC)
  78.   return;
  79. }
  80. // Timer A0 interrupt service routine
  81. #pragma vector=TIMER0_A0_VECTOR
  82. __interrupt void Timer_A (void)
  83. {
  84.   ISRcounter++;   // Increment ISRcounter
  85.   CCR0 += 98;     // Extend timer by 6.125us
  86. }


Learn More :