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.