¿Hacer PWM a partir de 2 entradas analógicas en MSP430G2231?

3

Soy un novato en este MSP430. Así que, por favor, dime cuando me equivoque.

Tengo un proyecto final que hace MPPT (Maximum Power Point Tracker) usando MSP430G2231. La idea básica es medir a la entrada analógica (voltaje y corriente), luego multiplicarla (potencia) y compararla con el resultado anterior. Es por eso que, antes de continuar con el algoritmo del MPPT, estoy tratando de usar este MSP430G2231 para leer 2 entradas analógicas y crear PWM usándolo.

Yo uso dos pines como entrada, P1.0 y P1.1. Luego, uso P1.2 para producir el PWM. La codificación que hice es así:

#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
}

Intento rastrearlo usando "step into" en el modo de depuración. Todo parece ir bien hasta que llega a esta línea:

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

Cuando el puntero llega a esa línea, el botón "entrar en" ya no está activo, lo que significa que hay algo mal.

¿Escribo el algoritmo correctamente, especialmente cuando asigno los valores de ADC a AdcData? ¿Y puedo multiplicar el valor de salida de la derecha de ADC y luego usarlo para generar PWM?

En respuesta a la respuesta de jsolarski (gracias por darme sus comentarios)

En realidad, he estado escribiendo el algoritmo tal como lo mencionaste, y sigue así y aún no funciona

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)
}

No utilizo este código: P1OUT |= 0x01; porque uso ese Pin para la entrada ADC. Y esta línea,

ADC10SA = 0x200;                        // Data buffer start

ADC10SA significa ADC10 Dirección de inicio derecha, ¿dónde desea transferir el valor de conversión de ADC? Entonces, cuando quiero transferirlo a mi matriz AdcData, ¿está bien escribirlo como lo hizo?

    
pregunta Agus Praditya

1 respuesta

4

No está esperando que el ADC termine las conversiones. Tendrías que hacer algo como esto:

 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
 }

}

Debe leer guía de usuario - capítulo 20 (creo) ADC10 y mire ejemplos de código en ADC10 con DTC

    
respondido por el jsolarski

Lea otras preguntas en las etiquetas