Electronic – Making PWM from 2 Analog input in MSP430G2231

analogmicrocontrollervoltage measurement

I am a newbie to this MSP430. So, please tell me when I go wrong.

I have a final project making MPPT (Maximum Power Point Tracker) using MSP430G2231. The basic idea is to measure to Analog input (voltage and current), then multiply it (power) and compare to the previous result. That's why, before going further to the algorithm of the MPPT itself, I am trying to use this MSP430G2231 to read 2 analog input and create PWM using it.

I use two pins as an input, P1.0 and P1.1. Then, I use P1.2 to produce the PWM.
The coding that I made goes like this:

#include <msp430.h>
#include "msp430g2231.h"

//Global Variable
unsigned int AdcData[2] ;                 // Store results A1,A0
unsigned int Current ;         // store value from P1.0
unsigned int Voltage ;         // store value from P1.1

void main (void)
{
  WDTCTL = WDTPW + WDTHOLD;   // Stop WDT

  BCSCTL1 = CALBC1_1MHZ;   // Set range
  DCOCTL = CALDCO_1MHZ;      // SMCLK = DCO = 1MHz 

  ADC10CTL1 = INCH_1 + CONSEQ_1;            // A1/A0, single sequence
  ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
  ADC10DTC1 = 0x02;                         // 2 conversions
  ADC10AE0 |= 0x03;                         // P1.1,0 ADC10 option select

  P1DIR |= BIT2;                            // P1.2 = output
  P1SEL |= BIT2;                            // P1.2 = TA1 output
  TACCR0 = 1024-1;                             // PWM Period
  TACCTL1 = OUTMOD_7;                       // TACCR1 reset/set
  AdcData[0]=32;
  AdcData[1]=16;
  Voltage = AdcData[0];
  Current = AdcData[1];             
  TACCR1 = (Voltage*0.04)*(Current*0.05);         // TACCR1 PWM Duty Cycle
  TACTL = TASSEL_2 + MC_1;                  // SMCLK, upmode


  while (1)
  {
  __bis_SR_register(LPM0_bits + GIE);     // LPM0, ADC10_ISR will force exit
   ADC10SA = (unsigned int)&AdcData;        // Data transfer location
   ADC10CTL0 |= ENC + ADC10SC;             // Start sampling
  }
}


// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  __bic_SR_register_on_exit(LPM0_bits);     // Exit LPM0
}

I try to trace it using "step into" in debugging mode. Everything seems goes well until it reach this line :

ADC10SA = (unsigned int)&AdcData;        // Data transfer location

When the pointer reach that line, the "step into" button is not active anymore which means there's something wrong.

Do I write the algorithm right, especially when assign the values from ADC to the AdcData?
And, I can multiply the output value from ADC right and then use it to generate PWM?


In response to jsolarski answer (thank you for giving me feedback)

Actually I've been writing the algorithm like you mention and it goes like these and it still not working

for (;;)
{
   ADC10CTL0 &= ~ENC;
   while (ADC10CTL1 & BUSY);               // Wait if ADC10 core is active
   ADC10SA = (unsigned int)&AdcData;        // Data transfer location 
   ADC10CTL0 |= ENC + ADC10SC;             // Start sampling
   __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit  
}


// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
  //code from reading from res and sending it to AP
  __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
}

I don't use this code: P1OUT |= 0x01; because I use that Pin for ADC input.
And this line,

ADC10SA = 0x200;                        // Data buffer start

ADC10SA means ADC10 Start Address right, where you want to transfer the ADC conversion value? So, when I want to transfer it to my AdcData array, is it okay to write it like it did?

Best Answer

You are not waiting for the ADC to finish the conversions. You would have to do something like this:

 for (;;)
{
  ADC10CTL0 &= ~ENC;

  while (ADC10CTL1 & BUSY);                 // Wait if ADC10 core is active
    ADC10SA = 0x200;                        // Data buffer start
    P1OUT |= 0x01;                          // Set P1.0 LED on
    ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
    __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit
    P1OUT &= ~0x01;                         // Clear P1.0 LED off
 }

}

You should read the user guide - chapter 20 (I think) ADC10 and look at the code examples on ADC10 with DTC