¿Qué causa la activación de un solo pin de salida en el Microchip PIC16F690 para apagar espontáneamente otro pin en el mismo puerto?

7

¿Qué causa la activación de un solo pin de salida en el Microchip PIC16F690 para apagar espontáneamente otro pin en el mismo puerto? Puedo solucionar este problema escribiendo un byte en todo el puerto, controlando todos los pines simultáneamente, en lugar de solo un bit para controlar el estado del pin. Estoy usando el compilador Hi-Tech C aquí. Estoy determinando el estado del pin con 9 LED cada uno consumiendo 3 mA. Esto está muy por debajo de las especificaciones de potencia máxima.

El archivo de cabecera mplab tiene el pin 0 en el puerto A declarado como tal:

volatile       bit RA0  @ ((unsigned)&PORTA*8)+0;

Estoy activando el pin al escribirle un alto valor.

RA0 = 1;

¿El problema es que el complaciente trata el "1" como un byte y escribe a todo el puerto? ¿Necesito lanzarlo? Si es así, ¿no debería haber dado el complaciente un error?

RA0 = (bit) 1;

Si escribo en todo el puerto, todo funciona como se espera:

PORTA = 0b00000001;
    
pregunta Dave.Mech.Eng

5 respuestas

16

Es el conocido problema de lectura-modificación-escritura, encontrará detalles en la hoja de datos. Tienes que escribir a todo el registro, como has encontrado. Los dispositivos 18F y 16 bits no tienen el problema. Hay una buena descripción en la página 2 en este documento . El cambio de bits en un registro "en sombra" y luego la escritura del registro en el puerto de salida a menudo se usa para solucionar el problema.

    
respondido por el Leon Heller
1

Asegúrese de que el puerto que está utilizando esté definido como digital. ANSEL = 0;

Si un puerto se define como analógico y la lectura digital devuelve 0. Entonces, cuando el PIC F16xxx realiza la operación de lectura-modificación-escritura, lee 0 en todos los pines analógicos. Luego se escribe 0 en todos estos pines.

Si tiene ANSEL configurado en 1 para el PUERTO B, el código siguiente activará el PUERTO B durante 500 ms, luego lea el PORTB como 0b00000000 (porque es analógico). Luego, apague el PORTB porque pensó que estaba apagado.

    ANSEL = 0b11111111;
    TRISB = 0;
    PORTB = 0b11111111;
    __delay_ms(500);
    current = PORTB;
    PORTB = current;
    __delay_ms(500);

¡Asegúrate de establecer el bit ANSEL correspondiente en 0 para cualquier pin que quieras usar como digital!

    
respondido por el Rich
0

Yo uso el compilador de Microchip. Tiene un archivo de encabezado donde todos los registros tienen una unión con los bits definidos. Entonces, en mi código escribo:

LATAbits.LATA0 = 1;

También, usaría el registro de retención en lugar del registro de PUERTO para establecer la salida. Creo que a algunos chips no les importa, pero otros sí.

    
respondido por el Robert
0

Estoy 99% seguro de que el compilador está haciendo esto. Cualquier estructura definida para acceder al pin tiene una ambigüedad que el compilador está resolviendo para crear este comportamiento. La conversión de bits puede ayudar, pero no sé cómo (bit) está definido, así que no puedo estar seguro. El compilador no necesariamente le dará un error si el valor que se escribe en el pin es del tipo correcto. Supongo que la máscara (bit) podría desencadenar algo de lógica para preservar el estado de los otros pines pero aún así devolver el mismo escribe como tu constante.

No es sorprendente que la escritura en el puerto en sí funcione, pero trabajar con pines individuales es mucho más complicado. O bien hay un error en el código provisto, no fue diseñado para usarse con este compilador o simplemente no lo estás usando correctamente.

    
respondido por el AngryEE
-2

Escribir todo el puerto a 1 le muestra el problema. En binario, eso es 0b00000001, por lo que de hecho está desactivando los primeros siete bits y activando el último bit.

Debe utilizar operadores binarios para asegurarse de que solo está realizando el cambio en ese bit específico. Haz esto:

PORTA = PORTA | 1;
// Equivalently:
current = PORTA;
new = current | 1;
PORTA = new;

Si los pines 2-8 están actualmente altos, la operación OR devolverá verdadero y el bit permanecerá establecido.

Para hacer un poco bajo, use una operación binaria AND:

PORTA &= 1;

Tenga en cuenta que algunos compiladores tendrán macros específicas para hacer esto (es decir, _BV () en avr-gcc) y algunos micros tendrán direcciones específicas con alias en cada bit periférico para que no tenga que hacer esto. ciclo de escritura (memoria de banda de bits en Cortex-M3)

    
respondido por el Kevin Vermeer

Lea otras preguntas en las etiquetas