4 votos

Utilizando MSP430G2452 temporizador + ADC

Estoy tratando de construir un simple afinador de guitarra usando MSP430G2452. La guitarra de la señal de que va a venir a través de sus pastillas, a través de un amplificador y 1 khz filtro que he construido utilizando LM358.

== Context ==

Ahora, mi concepto de la cancha de detección se basa libremente en los puntos de cruce cero. Estoy contando el número de picos que tengo por mantener un seguimiento de 3 muestras a la vez. Si la media de la muestra es mayor que el de los dos en los lados, es un pico. De esta manera, puedo contar la aparición de los picos y de encontrar el terreno de juego (que puede ser la fundamental o uno de los armónicos).

He probado esta usando grabado guitarra notas y Python en mi PC, y no parece funcionar en la teoría.

== Ahora, mi problema ==

Quiero que el ADC para ser activada en mi deseado de la tasa de decir, 2kHz. Para ello, voy a usar un temporizador de interrupción activa y comienza la conversión ADC. El ADC de interrupción de los procesos de mi muestra y ajusta el temporizador de nuevo. Este proceso cíclico se supone que me da un ejemplo de cada 1/2000 segundos.

Sin embargo, me he dado cuenta de que el temporizador no funciona como se espera para los recuentos muy bajos.

Digamos que tengo el temporizador de reloj en 12 khz (VLOCLK) y el número 6 para obtener una interrupción cada 1/2000 seg. Me puse un LED para activar o desactivar el temporizador de interrupción para ser capaz de verlo. Naturalmente, la frecuencia es tan rápido que el LED debe aparecer para ser completamente brillante. Pero en lugar de eso, el LED parpadea una vez en 4 o 5 segundos. Parece como si el temporizador de cuenta de todo el camino hasta el valor más alto, y el regreso a las 6, y sólo entonces se genera una interrupción.

Esto sólo ocurre si el valor del contador es demasiado baja. Tengo un áspero código de abajo. Esta es una versión ligeramente antigua que la actual que tengo. Pero debe darle una buena idea de lo que estoy tratando de lograr. (En el siguiente código, el temporizador se ha establecido interrumpir una vez por segundo, pero no funciona muy bien para la baja intervalos quiero)

#include <msp430g2452.h>

#define TIMER_COUNT 12000
volatile unsigned int value = 0;

void configClocks();
void configTimer();
void configADC();

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

    P1DIR = 0xFF;
    P1DIR &= ~BIT5;
    P1SEL |= BIT5;

    configClocks();
    configTimer();
    configADC();

    TACCR0 = TIMER_COUNT;
    TACTL |= MC_2;

    __enable_interrupt();

    while (1)
    {
    }
}

void configClocks()
{
    //Set basic clock
    DCOCTL = CALDCO_1MHZ; //DCO 1mhz
    BCSCTL1 = CALBC1_1MHZ; //Aclk 1mhz
    BCSCTL2 = SELM_0 + DIVM_0 + SELS + DIVS_0; //Master 1 Mhz, SMCLK = VLO = 12
}

void configTimer()
{
    TACTL = TASSEL_2 + ID_0 + MC_0; // SMLCK, No div, Stopped
    TACCTL0 = CCIE;
}

void configADC()
{
    ADC10CTL1 = INCH_5 + ADC10SSEL_1;
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;
    ADC10AE0 |= BIT5;
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
    P1OUT ^= 0x01;
    ADC10CTL0 |= ENC + ADC10SC;
}

//ADC10 interrupt routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
    value = ADC10MEM;
    P1OUT ^= BIT6;
    TACCR0 += TIMER_COUNT; //Set timer count
    //__bic_SR_register_on_exit(CPUOFF);        // Return to active mode
}

== Otro enfoque que estoy pensando ==

Podría haber algo estoy vistas, o mi idea en sí misma podría ser fundamentalmente errónea. El otro plan pensé que iba a tener todo dentro de un bucle while. Algo como la siguiente:

while (1)
{
    //delay for 1/2000 time
    //enable ADC
    //SLEEP (will be woken up by ADC interrupt
    value = ADC10MEM
    //do something meaningful with the value
}

Tengo el intentar por encima de uno. Pero he puesto que sólo en caso de que uno de ustedes puede capturar cualquier error en ella, o me apunte a una mejor manera de hacerlo.

1voto

Passerby Puntos 28913

El MSP430G2452 tiene tres Temporizador de Un fallo en ambas revisiones, cualquiera de los cuales podría estar afectando. Se puede leer en la fe de Erratas para el chip. Creo que tal vez Bug TA12:

La interrupción se pierde (lento ACLK):
Timer_A contador se ejecuta con lentitud reloj (externo TACLK o ACLK)en comparación con MCLK. La comparación se selecciona el modo de captura/comparación de canal y la CCRx registro se incrementa en uno con la que ocurre comparar interrupción (si TAR = CCRx). Debido a la rápida MCLK la CCRx registro de incremento (CCRx = CCRx+1) ocurre antes de que el Timer_A contador se incrementa de nuevo. Por lo tanto, la próxima comparar interrupción debe suceder a la vez con el siguiente Timer_A incremento del contador (si TAR = CCRx + 1). Esta interrupción se pierde.

Solución: Cambiar de captura/comparación del modo de captura modo antes de la CCRx registro de incremento. Cambie a modo de comparación después.

Incluso si este no es el caso, usted puede fácilmente solucionar este problema. Usted está utilizando el valor predeterminado de 1 mhz de reloj Maestro. Usted puede cambiar esto a 2 MHz 4 MHz con un simple cambio de código, al punto que el mismo divisor, se produciría un VLO de 24 khz o 48 khz. Esto le permitirá establecer un temporizador de contar un poco mayor, de nuevo de 12 o 24, evitando el bajo conteo problema. Por supuesto, es necesario realizar pruebas para estar seguro.

Su plan alternativo también funciona. Si usted no está demasiado preocupado con bajo consumo de energía, retrasos iba a funcionar. Por supuesto, ya que este se ejecuta en el Master de reloj de 1Mhz, en su lugar, usted tendrá que calcular el propósito de retraso, y darse cuenta de que habrá algunos ligera deriva.

1voto

hortstu Puntos 175

Parece que va a poner el temporizador en modo Continuo (MC_2), en cuyo caso el temporizador contará hasta 65535 antes de que se devuelve 0. Se interrumpirá cada vez que golpea a 6 (o de 12000 o cualquiera que sea el valor de TA0CCR0 lo es), pero no se reinicia el contador a 0, en ese caso, lo que significa que la primera interrupción puede ocurrir en 6 de las garrapatas, pero el período de la interrupción será 65536.

Yo creo que se quiere modo (MC_1), que se restablezca el contador cuando se alcanza el valor objetivo.

Usted también puede querer para desactivar el temporizador (TACLR) como de encenderlo, sólo para que sepan de que el temporizador está empezando desde cero.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X