Hey all,
I have tried getting this code to work and filter it so it is a smooth sine wave using an active 2nd order Butterworth filter or a passive RC filter and I get the attached photo. My issues is that my math is not acting correctly. I have been able to get a constant 50Hz signal out but cannot get a smooth sine wave to exist. When I have been using a look-up table the frequency will not stay constant so right now the array I have set is only at one constant output value.
Here is the math I have been using:
Output Freq= Clock Frequency /(PWM clock ticks * size of array)
PWM Frequency = (Clock frequency / PWM clock ticks)
Using either of the filters I have been able to get this at a constant Frequency but unable to get a smooth wave out. Here is the code I have been using.
/*
* Simple DAC for the MSP430F5438A
* Author: Alexander Coffin
* Date:
* Code set at 650 to allow a constant 50Hz output. Variation is done in PWM output values
*
************************************************************************/
#include <msp430f5438a.h>
unsigned char counter; // Current location in wave array
// Wave range is from 0-255. 255 will give an output around 1v pk-pk(all above 0)
//100 gives 250mv pk-pk(split between both)
//150:
//200: 800mv pk-pk(half and half)
unsigned char wave[4] =
{
100, 100, 100, 100
};
unsigned int i; // Used for 'for' loops.
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P4DIR |= BIT1; // P4.1 output
counter = 0; // Reset counter
// Initialize Timer
TB0CCTL0 = CCIE; // CCR0 interrupt enabled
TB0CCTL1 = CCIE; // CCR1 interrupt enabled
TB0CCR0 = 650; // Set PWM period to 650 clock ticks
TB0CCR1 = wave[counter]; // Set first duty cycle value
TB0CTL = TBSSEL_1 + MC_1 + TBIE + TBCLR; // ACLK, upmode, enable interrupt, clear TB1R
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
/**
* TimerB0 interrupt service routine
**/
#pragma vector=TIMER0_B0_VECTOR
__interrupt void TIMER0_B0_ISR(void)
{
P4OUT |= BIT1; // Set P4.0
TB0CCR1 = wave[counter]; // Set next duty cycle value
counter += 1; // Add Offset to CCR0
if ( counter == 4) // If counter is at the end of the array
{
counter = 0; // Reset counter
}
}
/**
* TimerA1 Interrupt Vector (TAIV) handler
**/
#pragma vector=TIMER0_B1_VECTOR
__interrupt void TIMER0_B1_ISR(void)
{
switch( TBIV )
{
case 2: // CCR1 interrupt
P4OUT &= ~BIT1; // Clear P4.0 to determine duty cycle.
break;
default:
break;
}
}
If this code can be configured to allow for a steady wave to be produced I need to know how a long with how I could possibly build in a DC step.
Thanks!