¿Cómo controlar el potenciómetro controlado digitalmente X9C102?

4

Tengo un montón de Intersil X9C102P , potenciómetros controlados digitalmente que quiero probar Estos dispositivos constan de una matriz de resistencias y algunos conmutadores analógicos que seleccionan la combinación de resistencias para obtener la resistencia deseada. Por favor, eche un vistazo al siguiente diagrama:

Comosepuedevereneldiagramaanterior,eldispositivotiene6pines,exceptolospinesdealimentación.Trespinesalaizquierdasonlospinesquecontrolanellimpiadordelpotenciómetro.

Echaunvistazoaldiagramadeabajo,yverásquebásicamentefuncionaasí;secontrolauncontadorArriba/Abajode7bitsconlospinesdecontrolmencionadosanteriormente.Luego,elvalordeestecontadorsealimentaaundecodificadorde100,quecontrolalaspuertasdelostransistoresparaconectarlaresistenciadeseadaallimpiador.

El control del potenciómetro digital parece fácil, aunque no puedo lograr el éxito. Le da un PIN BAJO a CHIP SELECT mientras que INCREMENTO es ALTO y estable, y luego mantiene CHIP SELECT BAJO.

Para mover el limpiador hacia arriba, disminuya la resistencia en mi caso, haga que ARRIBA / ABAJO coloque ALTO, luego haga que INCREMENTO coloque un pin bajo. En el borde descendente de INCREMENTO , el limpiador se mueve hacia arriba.

Para mover el limpiador hacia abajo, simplemente aplique el procedimiento anterior con ARRIBA / ABAJO pin BAJO.

Una vez que esté satisfecho con el resultado, irá al modo de espera y apagará la lógica dentro del X9C102. Tienes dos opciones; puede guardar el estado actual en la memoria no volátil del chip o no guardar. Para estar en espera con la tienda, debes poner CHIP SELECT ALTO cuando INCREMENTO sea ALTO. En el flanco ascendente de CHIP SELECT , el dispositivo entrará en modo de espera después de guardar el valor, que tarda 20 ms. Si no desea almacenar cuando ingresa el modo de espera, entonces mantendrá INCREMENTO pin BAJO.

Aquíestámiesquemaqueusoparalograreléxito.ParaprobarlospotenciómetrosdigitalesX9C102Pquetengoamano;Muevoellimpiadorhaciaabajo100veces,luegolomuevohaciaarriba50vecesyluegomidoelvoltajeenelpinWIPER.Sinembargo,nopuedolograreléxito.Asíque,porahora,heescritouncódigoquemueveellimpiadorhaciaabajo100vecesylomuevehaciaarriba100veces.

Elcódigode

parael PIC16F616 está debajo. He intentado volver a dormir sin almacenar después de cada movimiento de limpiaparabrisas, sin embargo eso no cambió el resultado. Aquí hay una cita de la hoja de datos al respecto:

  

Los interruptores electrónicos en el dispositivo operan en un "make-before-break"   Modo cuando el limpiaparabrisas cambia las posiciones del tap. Si se mueve el limpiaparabrisas   Varias posiciones, múltiples toques están conectados al limpiaparabrisas para TIW   (INC a VW / RW cambio). El valor RTOTAL para el dispositivo puede temporalmente   reducirse en una cantidad significativa si el limpiador se mueve varias   posiciones.

/* 
 * File:   main.c
 * Author: abdullah
 *
 */

#include <xc.h> // Include the header file needed by the compiler
#define _XTAL_FREQ 4000000 // Internal oscillator is set to 4 MHz.
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_ON & IOSCFS_4MHZ & BOREN_ON);

#define X9C102_Increment    PORTCbits.RC3
#define X9C102_UpDown       PORTCbits.RC4
#define X9C102_ChipSelect   PORTCbits.RC2
#define wiperReadAnalogCH   ANS5
#define wiperReadAnalogCHN  5
#define statusLED           PORTCbits.RC5  // This LED is the user interface.

unsigned short long ADC_ResultBuffer; // This variable will store ADRESH ADRESL combined.
unsigned char wiperValue = 0; // This value will hold scaled value of ADC_ResultBuffer
unsigned char i = 0; // Generic counter variable.

// Interrupts will wake-up the CPU.

void interrupt myInterrupt(void)
{
    if (INTF) // If there is a falling edge on INT pin,
    {
        INTF = 0; // Clear the interrupt flag.
    }
}

void main(void)
{
    ANSEL = 0; // Make all the pins digital i/o.
    ANSELbits.wiperReadAnalogCH = 1; // Make the wiper pin as analog input.

    TRISA = 0x04; // PORTA.2 is input, other PORTA pins are output.
    TRISC = 0x02; // PORTC.1 is input, other PORTC pins are output.

    X9C102_ChipSelect = 1;
    X9C102_UpDown = 1;
    X9C102_Increment = 1;
    statusLED = 0;

    ADFM = 1; // ADFM: A/D Conversion Result Format Select bit: 1 = Right justified, 0 = Left justified
    ADCON1bits.ADCS = 0x05; // ADCS<2:0>: A/D Conversion Clock Select bits : 101 = FOSC/16, 2us conversion time
    ADCON0bits.CHS = 0; // CHS<3:0>: Analog Channel Select bits : 0 to 7

    INTCONbits.INTE = 1; // Enable interrupt generation on INT interrupt.
    INTCONbits.GIE = 1; //GIE: Global Interrupt Enable bit

    // Power up, notice user by flashing the LED.
    for (i = 0; i < 5; i++)
    {
        statusLED = 1;
        __delay_ms(250);
        statusLED = 0;
        __delay_ms(250);
    }
    asm("sleep"); // Put the CPU to sleep. CPU will wake-up on button press.


    while (1)
    {
        // We have started the test, flash the LED.
        for (i = 0; i < 5; i++)
        {
            statusLED = 1;
            __delay_ms(250);
            statusLED = 0;
            __delay_ms(250);
        }

        // Move wiper down by 100 positions.
        for (i = 0; i < 100; i++)
        {
            X9C102_ChipSelect = 0;
            __delay_ms(1);
            X9C102_UpDown = 0;
            __delay_ms(1);
            X9C102_Increment = 0;
            __delay_ms(1);
            X9C102_Increment = 1;
            __delay_ms(1);
            // Return to sleep without storing.
            X9C102_ChipSelect = 1;
            // Wait for some time to allow debugging with multimeter
            __delay_ms(20);
        }

        // Going to move wiper down, alert user.
        for (i = 0; i < 5; i++)
        {
            statusLED = 1;
            __delay_ms(250);
            statusLED = 0;
            __delay_ms(250);
        }

        // Move wiper up by 100 positions.
        for (i = 0; i < 100; i++)
        {
            X9C102_ChipSelect = 0;
            __delay_ms(1);
            X9C102_UpDown = 1;
            __delay_ms(1);
            X9C102_Increment = 0;
            __delay_ms(1);
            X9C102_Increment = 1;
            __delay_ms(1);
            // Return to sleep without storing.
            X9C102_ChipSelect = 1;
            // Wait for some time to allow debugging with multimeter
            __delay_ms(20);
        }

        // Store the value.
        X9C102_Increment = 1;
        __delay_ms(1);
        X9C102_ChipSelect = 1;
        __delay_ms(25);

        /*
        // Following code is disabled. Normally, it checks the voltage on the
        // wiper pin and notifies user if it is in desired boundary.

        ADON = 1; // Turn the ADC ON.
        ADCON0bits.CHS = wiperReadAnalogCHN; // Select the appropriate analog channel.
        __delay_ms(1); // Wait the required acquisition time.
        GO_nDONE = 1; // Start the conversion.

        while (GO_nDONE);

        // Conversion is complete:
        ADC_ResultBuffer = ADRESL + (unsigned int) (ADRESH << 8); // Combine 8 bit "ADRESH" and  8 bit "ADRESL" to one 24 bit register.
        ADC_ResultBuffer *= 100; // Multiply by 100,
        ADC_ResultBuffer >>= 10; // and divide by 2^10 (1024), which,in turn, is (ADC_RESULT*100)/1024. So, we get a result from 0 to 100.
        wiperValue = (unsigned char) (ADC_ResultBuffer); // Put the result into the relevant variable.

        ADON = 0; // Turn the ADC OFF.

        if (wiperValue > 40 && wiperValue < 60)
        {
            statusLED = 1;
            __delay_ms(2500);
        }
        else
        {
            for (i = 0; i < 5; i++)
            {
                statusLED = 1;
                __delay_ms(250);
                statusLED = 0;
                __delay_ms(250);
            }
        }
         */

        statusLED = 0;
        asm("sleep"); // Put CPU into sleep mode.
    }
}

Cuando mido el pin 5, Rwiper, en el X9C102P, obtengo un valor máximo de 1.5V. Sin embargo, este valor difiere de un IC a otro. Salta alrededor de 1.3V a 1.8V, una vez recuerdo haber visto 2.5V. Además, he comprado algunos circuitos integrados nuevos y tienen el mismo problema. Entonces, está claro que tengo un problema con mi circuito o mi código. Además, los pasos no son lineales, son más como exponenciales, algo como "2 ^ x". Comienzan a incrementarse con pasos más grandes. Aquí están las tomas de alcance del pin 5, Rwiper, que muestran el movimiento del limpiaparabrisas, como se puede ver, esta vez solo sube a aproximadamente 1.7 V. ¿Qué causa este comportamiento extraño?

    

2 respuestas

3

Como primer paso, asegúrese de medir lo que cree que está midiendo. Desconecte el limpiador del pin de entrada PIC, en caso de que la corriente de fuga del pin PIC influya en sus mediciones.

Si este es realmente el problema, la solución normal es conducir la carga (la entrada PIC) desde una fuente de baja impedancia, es decir, un amplificador de búfer. Normalmente, este sería un tramo de "riel a riel" (los voltajes de entrada y salida pueden oscilar hacia los rieles de suministro) cableados en la configuración de ganancia unitaria.

¡Pero también verifique que el software PIC esté configurando ese pin up correctamente como entrada! Mirando la hoja de datos PIC (pin 165), la "fuente de voltaje analógica" debería tener una impedancia < 10k. El X9C102 ya lo hace, (su rango es de hasta 1k), por lo que su configuración original debería funcionar.

Intente tirar el pin PIC alto o bajo con una resistencia de 1 k; Si no se mueve muy cerca de los suministros, o bien tiene un problema de configuración del software (el pin sigue siendo una salida) o posiblemente un PIC dañado. De un vistazo, su software se ve bien, pero no estoy familiarizado con ese PIC.

    
respondido por el Brian Drummond
3

Sé que tienes una solución, pero pensé que agregaría otra opción, para futuras referencias.

Recientemente he estado usando un Bus Pirate como soporte para un microcontrolador externo en un sistema que soy trabajando en. Por $ 30 dólares, es una excelente herramienta.

Entusituación,puedesponerloenmodo"bit-bang" y utilizarlo para subir y bajar el bote.
También tiene un ADC de 10 bits, que puede usar para leer el valor del limpiador con bastante facilidad.

Si estuviera en tu situación, creo que probablemente elegiría algo como esto en vez de escribir C para un PIC, ya que puedes escribir al pirata del autobús desde una computadora (en mi caso, estoy usando python).

    
respondido por el Connor Wolf

Lea otras preguntas en las etiquetas