PIC16F18855 funciona a la mitad de la frecuencia de reloj cuando lo apago y lo enciendo demasiado rápido

1

Tengo una placa que tiene un PIC16F18855 funcionando a 8MHz desde un cristal externo. La mayoría de las veces funciona bien, pero si se apaga rápidamente, se reiniciará a 4MHz. Los principales síntomas de esto son cosas como la velocidad en baudios de UART y la frecuencia de PWM que se reduce a la mitad.

Más específicamente, si enciendo y apago el interruptor de alimentación en menos de ~ 2 segundos, funcionará a la frecuencia más baja. Más largo y funciona correctamente. Cuando programo la placa, se reinicia a 4 MHz, lo que significa que tengo que apagarla y encenderla físicamente antes de que funcione. Si corto el pin MCLR a tierra, el comportamiento es inconsistente, a veces comenzará a 4MHz y normalmente comenzará a 8MHz.

También he tenido un caso en el que tardó bastante más tiempo, cuando encenderlo a los 10 minutos de haberlo apagado comenzó a 4MHz. No estoy seguro de si el problema está relacionado, pero no puedo reproducir ese error en este momento.

Desde que probé el pin OSC2 / CLKOUT, puedo ver que el cristal mismo todavía se está ejecutando a 8MHz. Con las sondas que tengo, no puedo probar el pin OSC1 sin reiniciar el micro.

EDIT 1:

Cuando la placa se ejecuta a 8MHz, sus registros OSCCONx son:

OSCCON1: 0x70
OSCCON2: 0x70
OSCCON3: 0x10

y cuando se ejecuta a 4MHz son:

OSCCON1: 0x70
OSCCON2: 0x60
OSCCON3: 0x00

Se está ejecutando fuera del oscilador interno HF. Miraré esto un poco más de cerca. Sabiendo esto, es posible que pueda encontrar una solución, pero prefiero averiguar la causa del problema.

OSCFRQ = 0x02 , que es la configuración de 4MHz, así que esto es definitivamente lo que está sucediendo. Una solución terrible sería establecer el registro OSCFRQ en la configuración de 8MHz, por lo que funciona de la misma manera, pero luego pierdo la precisión del cristal. Puede que no arruine todo, pero tengo algunas cosas sensibles al tiempo, así que prefiero usar el cristal si puedo.

    
pregunta Escape

1 respuesta

1

Esta no es una explicación de por qué estaba sucediendo, pero encontré una solución. Lo primero que intenté fue establecer los bits de fusible para RSTOSC_EXT (es decir, #pragma fuses HS, RSTOSC_EXT ) sobre la base de lo que Spehro dijo en los comentarios, pero eso no me funcionó. Lo que hice fue agregar lo siguiente (tenga en cuenta que OSCCON2 es la configuración real, y OSCCON1 es el búfer):

if(OSCCON2 == 0x60){
    OSCCON1 = 0x60;
    OSCCON1 = 0x70;
}

Mi razón para intentar esto es: OSCCON2 es la configuración real, y cargará el valor en OSCCON1 cuando esté listo. De mi investigación anterior, supe que el valor correcto estaba en OSCCON1, y OSCCON2 nunca lo cargó. Por lo tanto, se asumió que el proceso de carga se atascó en algún lugar, y cargar el valor en OSCCON2 en OSCCON1 haría que el chip pensara que estaba cargado correctamente. Esto lo "desenredaría" y luego me permitiría volver a cargar el valor correcto sin que se atasque.

Este código está justo al inicio de la función principal, después de las declaraciones de variables. Resuelve el problema, pero no explica por qué sucedió en primer lugar. Si alguien sabe qué causó esto y si hay una solución mejor, todavía estoy abierto a mejores respuestas.

    
respondido por el Escape

Lea otras preguntas en las etiquetas