This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430G2231: ADC read not working

Part Number: MSP430G2231


Tool/software: Code Composer Studio

Hello,

I started writing a code for a program that samples 2 analog signals from port 0 and 1, and control frequency and width factor for two outputs pin 6 and pin 7, the program builds, compiles but it doesn't do what I want, pin 6 has a impulse signal that is fixed and pin 7 has a continuous signal. I am close to a deadline and I also didn't have much time for this to begin with (2 days with other things to do as well). Any idea will help. 

Thank you.

Below the code i have written

#include <msp430.h>
// Global Variables
unsigned int adc[2] = {0}; // This will hold the FREQ and PWM values
unsigned int FREQ;
unsigned int PWM;
unsigned int i;
unsigned int j;
unsigned int k;

//Function Prototypes
void Setup_HW(void); // Setup watchdog timer, clockc, ADC ports
void Read_Acc(void); // This function reads the ADC and stores the FREQ and PWM values
int main(void)
{
Setup_HW();
P1DIR |= BIT6;
P1DIR |= BIT7;
while (1)
{
Read_Acc(); // This function reads the ADC and stores the FREQ and PWM values

for(k=0;k>100;k++); //Small delay between alternating pulses
P1OUT ^= 0x20; //Pin 6 output set to 1
for(k=0;k>100;k++); //Small delay between alternating pulses
i=100*(FREQ-((PWM/1024)*FREQ));
for(;i=0;i--); //Delay generated by potentiometers
P1OUT ^= 0x20; //Pin 6 output set to 0

for(k=0;k>100;k++); //Small delay between alternating pulses
P1OUT ^= 0x40; //Pin 7 output set to 1
for(k=0;k>100;k++); //Small delay between alternating pulses
j=100*(FREQ-(FREQ-((PWM/1024)*FREQ)));
for(;j=0;j--); //Delay generated by potentiometers
P1OUT ^= 0x40; //Pin 7 output set to 0

}
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}

void Setup_HW(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
ADC10CTL1 = INCH_2 + CONSEQ_1; // A1/A0, single sequence
ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
ADC10DTC1 = 0x02; // 2 conversions
ADC10AE0 |= 0x02; // Disable digital I/O on P1.0 and P1.1
}
void Read_Acc(void)
{
ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
ADC10SA = (unsigned int)adc; // Copies data in ADC10SA to unsigned int adc array
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start

FREQ = adc[0]; // adc array 0 copied to the variable FREQ
PWM = adc[1]; // adc array 1 copied to the variable PWM
__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit
}

  • A few things jump out:

    > i=100*(FREQ-((PWM/1024)*FREQ));
    PWM/1024 will always be 0. You probably want to consider scaled arithmetic here, and you might need to expand the intermediate results to "unsigned long".
    I'm not quite sure what you're computing, but maybe something like this will work:
    > i=100*(FREQ-((FREQ*(unsigned long)PWM/1024)));

    ADC10CTL1 = INCH_2 + CONSEQ_1; // A1/A0, single sequence
    You probably want INCH_1 here, since that's what you're doing. (This may or may not be causing visible trouble.)

    FREQ = adc[0]; // adc array 0 copied to the variable FREQ
    PWM = adc[1]; // adc array 1 copied to the variable PWM
    __bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit

    The CPUOFF is intended to wait for the ADC to complete, so you should fetch the results afterward, not before.
  • > You probably want INCH_1 here, since that's what you're doing. (This may or may not be causing visible trouble.)
    I take it back -- this is almost certainly causing trouble, since your result array contains A2/A1, not A1/A0.
  • Thank you for the quick reply, I solved the problem with your suggestion. Sorry for my late answer.

**Attention** This is a public forum