Processing math: 100%

5 votos

¿Cómo configurar el oscilador interno en un PIC16F616?

Quiero utilizar el oscilador interno en PIC16F616 en configuración de 8 MHz y tener la función de E/S en RA4 y RA5 . He leído la hoja de datos y no encuentro lo que estoy haciendo mal.

Por lo que entiendo de la siguiente información, TMR0 debería incrementarse cada 500 ns, y debería crear una interrupción cuando se desborde de "0xFF" a "0x00". Sin embargo, RA4 el pasador cambia cada 20 us.

De la hoja de datos:

5.1.1

MODO DE TEMPORIZADOR DE 8 BITS

Cuando se utiliza como temporizador, el módulo Timer0 incrementa cada ciclo de instrucción (sin preescalador).

El modo de temporizador se selecciona borrando el bit T0CS del registro registro OPTION a "0".

También;

Nota: El valor escrito en el registro TMR0 puede ajustarse para tener en cuenta el retraso de dos retraso del ciclo de instrucción cuando se escribe TMR0 se escribe.

Block Diagram of the TIMER0/WDT Prescaler

Aquí está mi código, mi compilador es MPLAB XC8. :

#include <xc.h>
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF & IOSCFS_8MHZ & BOREN_ON);

void interrupt myInterrupt(void)
{
    if (T0IE && T0IF)
    {
        RA4 = ~RA4;
        TMR0 = 254;
        T0IF = 0;
    }
}

void main()
{
    TRISA = 0;
    ANSEL = 0;

    PSA = 1; // Prescaler Assignment bit : 1 = Prescaler is assigned to the WDT, 0 = Prescaler is assigned to the Timer0 module
    T0CS = 0; // T0CS: TMR0 Clock Source Select bit : 0 = Internal instruction cycle clock (FOSC/4), 1 = Transition on T0CKI pin
    T0IE = 1; //T0IE: Timer0 Overflow Interrupt Enable bit
    GIE = 1; //GIE: Global Interrupt Enable bit

    while (1);
}

2voto

RelaXNow Puntos 1164

Establecer TMR0 a un valor fijo en la rutina de interrupción es una mala idea si quieres una interrupción periódica fiable. Lo estás poniendo a 254. Eso crea 2 ciclos muertos y luego necesita 2 ciclos más para desbordarse. La condición de interrupción se establecerá mucho antes de que el procesador pueda volver y meter otros 254 en el temporizador. Estás usando un compilador (no lo haces cuando miras las instrucciones individuales), así que no sabes cuántas instrucciones hay para salir de la rutina de interrupción y cuántas hay para entrar. 20 µs implica 40 ciclos de instrucción. Eso suena alto, pero de nuevo, está utilizando un compilador así que ya has dicho que no te importa la eficiencia y has renunciado al derecho de contar ciclos.

Si quieres verificar que el PIC está funcionando a la velocidad de reloj correcta, deja que el temporizador 0 funcione libremente sin tocarlo. Esto debería interrumpir cada 256 ciclos de instrucción, o cada 128 µs.

Si quieres una interrupción periódica fiable, la primera reacción debería ser utilizar el temporizador 2. Para eso está ahí y por eso tiene un registro de periodo incorporado. Si necesitas el temporizador 2 para otra cosa, puedes seguir usando el temporizador 0 pero añadir en él cada interrupción, no restablecer su valor. De esta manera el tiempo desde que el temporizador se envuelve hasta que lo reescribes no se pierde. Además, no esperes un período rediculamente corto como 4 ciclos de instrucción. El PIC no puede entrar y salir de una interrupción tan rápido, incluso sin guardar el estado.

-1voto

Ed. Puntos 1089

Lugar de cambio simple para void interrupción miInterrupción(void) después de función principal.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X