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.
parael
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?