Comportamiento extraño del pin con pic16f88

He estado aprendiendo (intentando al menos) cómo trabajar con microcontroladores pic, y he notado este comportamiento que no estoy seguro de si es solo mi culpa o se supone que debe suceder. Escribí el siguiente programa con la esperanza de hacer que un LED parpadee. Parpadea muy bien cuando se conecta al pin etiquetado como RA2, pero cuando conecto el led al pin 15 (etiquetado como RA6/OSC2/CLKO en la hoja de datos) el led permanece encendido, como si lo hubiera conectado a Vdd. Luego, cuando lo vuelvo a poner en RA2 donde pertenece, está apagado. La única forma de volver a encenderlo es conectando una resistencia de 10k entre Vdd y MCLR (como cuando se programa). ¿Que está sucediendo aquí? También se necesita MCLR cuando se conecta a otros pines. ¿Estoy causando daño?
El circuito son 3 pilas AA que alimentan la foto, con una resistencia de 330 y un led de 3 mm en serie que va desde el pin 1 (RA2) al pin 5 (tierra).
hoja de datos pic16f88
Código:

#include <xc.h>

__CONFIG(MCLRE_ON & CP_OFF & WDTE_OFF);

void main(){

    TRISA = 0x0000;
   // RB6 = 0b000010;
    for(;;){
        RA2 = 1;
        Wait();
        RA2 = 0;
        Wait();
    }
}
int Wait(void) // gives me a delay of 1/3rd a second or so
{
for (int i = 0; i < 50; i++)
 {
 }
}

Respuestas (3)

Debe atar el pin MCLR alto durante el funcionamiento normal; de lo contrario, el chip se mantendrá en reinicio. Observe la barra sobre MCLR, esto significa que está activo bajo .
Use una resistencia entre MCLR y Vdd de alrededor de 10kΩ (<40kΩ)
Consulte la página 132/133 de la hoja de datos.

Entonces, ¿debo mantener esa resistencia de 10kΩ allí permanentemente? Parecía funcionar bien cuando eso no estaba allí. ¿Qué hace estar retenido en reinicio? ¿Poner _MCLRE_OFF en la parte de configuración del programa arreglaría esto?
Funcionará de forma intermitente cuando no esté allí debido a la impedancia muy alta de la entrada CMOS; solo tocarlo con la mano hará la diferencia cuando esté flotando. Si la parte se mantiene en reinicio (MCLR en realidad se tira a tierra en lugar de flotar), entonces el oscilador principal se apaga y la parte "duerme" (consumo de energía muy bajo) Apagar MCLR hará que el estado del pin sea irrelevante, sí.
Lo que es mejor/más seguro/más inteligente para el mcu, mantener mclr apagado en la configuración, o mantenerlo encendido y mantener la resistencia allí. ¿Qué se suele hacer?
Depende de usted, si no necesita poder restablecer externamente el micro (por ejemplo, presionar un botón), apagarlo y guardar un par de componentes es una opción. Los microchips tienen muchas notas de aplicación sobre estos temas, haría una búsqueda en su sitio y leería un poco.
Eso funciona bien, gracias. Me doy cuenta de que si toco el pin 9 (RB3/PGM/CCP1) con el dedo, el LED se mantendrá encendido y luego se apagará. Después de unos 5 segundos, se volverá a encender. ¿Lo que está sucediendo allí?
Es difícil decir exactamente, pero probablemente se deba a que flota (establecido en la entrada) y al cambio de valor que causa algún problema. Puede ser que tengas configurado LVP (Programación de bajo voltaje) y entre en modo de programación. Asegúrese de tener el encabezado y las declaraciones de configuración correctos, y configure todos los pines no utilizados en salida (alta o baja) para evitar problemas relacionados con la flotación.
Menciono el encabezado correcto y los bits de configuración ya que su rutina de espera como se muestra no debería durar 1/3 de segundo (debería ser más como unas pocas decenas de microsegundos) Asegúrese de tener el oscilador configurado correctamente en los bits de configuración.
Todo bien gracias. Entonces, debo agregar LVP_OFF ​​a la configuración, ¿y en qué debo configurar el oscilador? El mcu tiene una potencia nominal de 20 mhz, ¿es un valor aceptable?
Si tiene un cristal externo de 20 MHz, entonces sí, puede configurarlo para esto. De lo contrario, utilice el oscilador interno de 8 MHz. Puede apagar el LVP si no lo usa, sí, y puede detener lo que está viendo (pero el pin debe configurarse en una salida de todos modos) Le aconsejo leer detenidamente la hoja de datos, toda la información sobre configuración (oscilador , restablecer, LVP, etc.) está ahí.
Todo está funcionando correctamente ahora, creo que sé lo que ha estado sucediendo ahora. Lo configuré para usar el oscilador interno con el bit de configuración FOSC_INTOSCIO. Aumenté el ciclo de espera a 500 veces y obtengo un poco más de un segundo entre cada parpadeo. Cuando lo bajo a cincuenta, parpadea mucho más rápido.

Su problema radica en el pin! MCLR. Cuando programa el PIC, está utilizando la función VPP, pero el mismo pin tiene la función !MCLR (Master Clear), y dado que esta función está activa en nivel bajo, debe asegurarse de que este pin permanezca alto para que el PIC pueda ejecutar su código. Como dijo Oli, puede lograr esto conectando una resistencia pull-up al pin !MCLR.

Como alternativa, puede desactivar la función MCLR reiniciando (escribiendo un 0) el bit MCLRE en el registro CONFIG1.

__CONFIG(MCLRE_OFF & CP_OFF & WDTE_OFF);

Detalle del bit MCLRE de la página 130 de la hoja de datos:

MCLRE: Bit de selección de función de clavija RA5/MCLR/VPP
1 = La función de clavija RA5/MCLR/VPP es MCLR
0 = La función de clavija RA5/MCLR/VPP es E/S digital, MCLR vinculado internamente a VDD


Agregado

Con respecto al problema de lectura, modificación y escritura, ocurre debido a la forma en que funciona el PIC. Los PIC de 8 bits necesitan cuatro ciclos de reloj para cada ciclo de instrucción. Las escrituras se realizan en el último ciclo de reloj, mientras que las lecturas se realizan en el primer ciclo de reloj. Esto puede causar problemas cuando trabaja con diferentes bits del mismo puerto.

Supongamos que tiene el siguiente código:

RA0 = 1;
RA1 = 1;

Es de esperar que tanto RA0 como RA1 sean altos después de ejecutar este código. Este puede no ser el caso. Si tiene todos los bits establecidos en 0 en PORTA, cuando ejecute RA0 = 1el PIC leerá el valor en PORTA en el primer ciclo de reloj, establecerá el bit 0 y escribirá el resultado nuevamente en PORTA. Hasta ahora no hay problema, pero cuando ejecutas la segunda instrucción (RA1 = 1), el PIC primero leerá el valor de PORTA, y lo más probable es que el pin RA0 no haya tenido tiempo de subir a 1, entonces el valor leído para ese pin es 0 en lugar de 1, luego se establece el bit 1, luego el resultado se vuelve a escribir en PORTA, pero solo se establece el bit 1.

Para evitar esto, puede agregar demoras entre las instrucciones como esta:

RA0 = 1;
asm("nop");  // No operation
RA1 = 1;

Una nopinstrucción debería ser suficiente.

En tu código no deberías tener este problema por dos razones:

  1. No estás cambiando bits diferentes en PORTA
  2. Tiene una instrucción de espera entre escribe los bits de PORTA

El registro sombra del que hablaba Leon consiste en un registro donde los bits individuales se modifican antes de escribir todo el registro en el PORT.

Es posible que desee asegurarse de que sus fusibles de configuración estén configurados de manera que RA6 sea un pin GPIO y no la función CLKO que el pin también puede asumir. Me encontré con este problema con un programa simple y el compilador de CCS. El compilador tiene una documentación tan pobre que es imposible saber exactamente qué está pasando sin mirar los fusibles.

Hubiera esperado que, ya sea que el LED esté en RA2 o RA6, tendría un comportamiento errático si MCLR # no está alto. Quizás RA6 esté más cerca de MCLR# y el problema se agrave; no estoy seguro.