Usando DTC y para lecturas repetidas de un solo canal en el MSP430

1

Estoy intentando usar el DTC para actualizar continuamente una variable sin la intervención de la CPU. Sin embargo, no estoy obteniendo ningún resultado y no puedo entender por qué. Cualquier ayuda sería apreciada.

Aquí está el método para inicializar el DTC:

void initializeDTC(unsigned int channel,unsigned int *pointer){
    // Disable ADC before configuration.
    ADC10CTL0 &= ~ENC;

    // Turn ADC on in single line before configuration.
    ADC10CTL0 = ADC10ON;

    // Set channel, Use SMCLK, 1/8 Divider, Repeat single channel.
    ADC10CTL1 = channel | ADC10SSEL_3 | ADC10DIV_7 | CONSEQ_2;
    // 0 clock ticks, Use Reference, Reference on, ADC On, Multi-Sample Conversion, Interrupts enabled.
    ADC10CTL0 |= ADC10SHT_1 | SREF_1 | REFON | MSC;

    // Put results at specified place in memory.
    ADC10SA = (int)pointer;
    // Only one conversion at a time.
    ADC10DTC1 = 0x01;
    // Repeat conversion.
    ADC10DTC0 = ADC10CT;

    // Start conversion.
    ADC10CTL0 |= ENC | ADC10SC;
    // I've read that trying to start the conversion twice is necessary.
    ADC10CTL0 |= ENC | ADC10SC;
}

Lo llamo así:

unsigned int temperature;
initializeDTC(INCH_10,&temperature);
// Do stuff with temperature in a loop.

Si he entendido la documentación correctamente, después de cada conversión, el ADC debería iniciar la siguiente conversión debido al bit MSC . Al mismo tiempo, el DTC debe transferir el valor de ADC10MEM al valor en la dirección en ADC10SA (el valor de mi puntero). El valor de mi variable temperature permanece en el valor predeterminado de lo que había en la memoria anteriormente (35 mil y algo para mí).

Consideré la posibilidad de que el DTC no haya finalizado antes de la siguiente conversión, pero la documentación indica que el DTC tendrá un máximo de 4% de ciclos de MCLK . En mi aplicación, I SMCLK = MCLK y como la conversión toma 8 SMCLK ciclos, debería estar bien a este respecto.

    
pregunta Fr33dan

2 respuestas

0

He encontrado la respuesta. La clave fue al configurar el DTC para establecer ADC10SA al final. Si observa Figura 22-10 del En la Guía del usuario puede ver que la configuración ADC10DTC1 mueve el DTC del estado "Restablecer" al estado "Inicial", por lo que antes de eso establecería ADC10DTC0 . Luego espera una escritura en ADC10SA antes de comenzar.

También hice algunas modificaciones para permitir un cambio fácil entre los modos de secuencia y de canal único. Mi código final se ve así:

void initializeDTC(unsigned int channel,unsigned int pointer[], bool sequence){

    // Disable ADC before configuration.
    ADC10CTL0 &= ~ENC;

    // Turn ADC on in single line before configuration.
    ADC10CTL0 = ADC10ON;

    // Make sure the ADC is not running per 22.2.7
    while(ADC10CTL1 & ADC10BUSY);

    // Repeat conversion.
    ADC10DTC0 = ADC10CT;
    // Only one conversion at a time.
    ADC10DTC1 = sequence ? channel >> 12 : 1;
    // Put results at specified place in memory.
    ADC10SA = ((unsigned int)pointer);

    // 8 clock ticks, Use Reference, Reference on, ADC On, Multi-Sample Conversion, Interrupts enabled.
    ADC10CTL0 |= ADC10SHT_1 | SREF_1 | REFON  | ADC10IE | MSC;
    // Set channel, Use SMCLK, 1/8 Divider, Repeat single channel.
    ADC10CTL1 = channel | ADC10SSEL_3 | ADC10DIV_7 | (sequence ? CONSEQ_3 : CONSEQ_2);

    // Enable conversion.
    ADC10CTL0 |= ENC;
    // Start conversion
    ADC10CTL0 |= ADC10SC;
}
    
respondido por el Fr33dan
0

Probablemente quieras:

volatile unsigned int temperature;

De lo contrario, el compilador podría colocar la variable en un registro y no leerá la ubicación de la memoria actualizada.

    
respondido por el Turbo J

Lea otras preguntas en las etiquetas