Pic18f458 Lenguaje c Timer e Interrupciones

download Pic18f458 Lenguaje c Timer e Interrupciones

of 11

description

8 Lenguaje c Timer e Interrupciones

Transcript of Pic18f458 Lenguaje c Timer e Interrupciones

  • PRCTICAS MICROPROCESADORES Manuel Moreno, primavera 2013.

    SESIN 2. UTILIZACIN DE LIBRERAS, TIMERS E INTERRUPCIONES

    INTRODUCCIN

    El objetivo de esta prctica es familiarizarse con los perifricos bsicos del microcontrolador PIC18F458, como son los puertos de entrada/salida, los timers y el generador de seal PWM. Para ello se utilizar una sencilla electrnica, cuyos esquemas podr encontrar en el anexo de esta documentacin.

    DESARROLLO DE LA PRCTICA

    Trabajo previo:

    - Lea detenidamente las siguientes partes del datasheet del PIC18F458 (9.0 I/O Ports, Pg. 96, 11.0 Timer0, pg. 111, 8.0 Interrupts, pg. 79).

    - Lea detenidamente las siguientes partes del manual C18_Lib_51297d.pdf (4.5 Delay Functions, pg. 146), referentes a las libreras software de retardos.

    - Lea detenidamente las siguientes partes del manual C18_Lib_51297d.pdf (2.9 Timer Functions, pg. 61), referentes a las libreras de utilizacin de los timers.

    - Lea detenidamente las siguientes partes del manual C18_UG__51288e.pdf (2.9.2.3 Interrupt vectors, pg. 37), referentes a la programacin de los vectores de interrupcin.

    Conocimientos tericos:

    - Puertos de entrada/salida del microcontrolador PIC18F458. - Utilizacin de libreras. - Temporizadores del microcontrolador PIC18F458. - Bits de configuracin y programacin mediante ICD2. - Interrupciones (alta y baja prioridad).

    Recomendaciones:

    - En la medida de lo posible, utilice variables globales - Documente cada lnea de programa para futuras referencias. - A la hora de programar el microcontrolador es importante asegurarse de escoger

    un oscilador de alta frecuencia (opcin oscillator = HS) y deshabilitar el WatchDog Timer, para evitar resets indeseados del microcontrolador.

  • E2.1. Implemente un programa en C que encienda y apague un LED (amarillo o verde) de la placa de prcticas lo ms rpidamente posible. Programe el microcontrolador y observe los resultados. Por qu el LED parece siempre encendido? Razone la importancia de inicializar los puertos de salida a un valor correcto en el programa principal. Tambin puede probarlo con el simulador. A travs del men: Debugger->Select Tool-> MPLAB SIM, puede activar el simulador. A travs del men: View->Simulator Logic Analyzer, le aparecer una ventana tipo osciloscopio donde podr visualizar pines de entrada/salida del microcontrolador. Con el botn Channels, seleccione el pin de salida que quiere visualizar.

    E2.2. Implemente un programa en C que haga una intermitencia visual de los LEDs (amarillo y verde) de la placa de prcticas. Utilice una frecuencia aproximada de 1Hz empleando las libreras de retardo (delays.h) del MPLAB C18. Haga una intermitencia alterna, es decir, si se enciende el LED verde, el amarillo se debe apagar y viceversa. Es necesario incluir en la cabecera del programa principal la sentencia #include. Verifique el corrector funcionamiento mediante simulacin y mediante la placa experimental.

    E2.3. Implemente la intermitencia de los leds utilizando el Timer0 de 16 bits del microcontrolador e interrupciones. Es necesario incluir en la cabecera del programa principal la sentencia #include. Haga una primera versin con interrupciones de alta prioridad y una segunda versin con interrupciones de baja. Verifique el correcto funcionamiento. Por qu es preferible utilizar interrupciones en lugar de retardos?

    E2.4. Implemente un programa en C que mediante un autmata encienda aproximadamente cada segundo uno de los cuatro actuadores de la placa. Es decir, primero se enciende el LED amarillo, despus se enciende el LED verde (apagando el amarillo), despus se enciende el ventilador (apagando el LED verde) y finalmente se enciende la resistencia de calentamiento (apagando el ventilador). El autmata debe funcionar de forma indefinida. Puede hacerlo mediante retardos o bien mediante interrupciones. Tenga cuidado con la lgica de control de cada uno de los actuadores (los LEDs se encienden escribiendo un 0 en el puerto, mientras que el ventilador y la resistencia de calentamiento se encienden escribiendo un 1 en el puerto de salida).

    E2.5. Utilizando el PWM hardware del PIC18458, controle la velocidad del ventilador. Genere una rampa de arranque y frenada de baja frecuencia, variando el ciclo de trabajo de la seal PWM que controla el ventilador. Compruebe experimentalmente su funcionamiento.

    EJERCICIOS ADICIONALES OPTATIVOS

    A1. Genere simultneamente interrupciones de alta y baja prioridad e invente un mecanismo para comprobar que efectivamente las interrupciones de baja prioridad son interrumpidas por las interrupciones de alta prioridad.

  • ANEXO

    INICIALIZACIN DE PUERTOS DE ENTRADA / SALIDA

    En cualquier aplicacin de microcontrolador, es necesario programar la direccin de los puertos (Entrada Salida). En el caso de los microcontroladores PIC, se utilizan unos registros especiales de configuracin (TRIS). En el caso del PIC18F458, hay 5 puertos (A-B-C-D-E) y por tanto 5 registros TRIS de configuracin.

    -------------------------------------------------------------------------------------------------------------------------------

    #include

    void main(void) {

    // CONFIGURACIN DEL PIC, PUERTOS Y PERIFRICOS

    CMCON = 0x07; // Comparadores OFF, puertos totalmente digitales I/O TRISA = 0xFF; // Entradas TRISB = 0b11111000; // Entradas, excepto RB2 = TX-CAN, Leds (RB0-RB1) TRISC = 0b10000000; // Salidas, excepto RC7 = RX-UART TRISD = 0xFF; // Entradas TRISE = 0xFF; // Entradas

    while(1) {

    }

    } -------------------------------------------------------------------------------------------------------------------------------

    BITS DE PROGRAMACIN

    A la hora de programar un microcontrolador PIC es necesario especificar una serie de bits de configuracin (tipo de reloj, watchdog, etc.) Para la placa de prcticas utilizaremos la siguiente configuracin (Men: Configure->Configuration Bits): Oscillator: HS WatchDog Timer: Disable

    Si no configura el reloj correctamente, el microcontrolador no funcionar. Si no deshabilita el watchdog timer, el microcontrolador se resetear frecuentemente.

    Otra opcin es hacerlo por cdigo, por ejemplo, con la directiva #pragma config OSC = HS

    En el directorio de instalacin del compilador (c:\mcc18 c:\archivos de programa\mcc18) encontrar un directorio (\doc) con documentacin til. En otras cosas, encontrar el archivo de ayuda hlpPIC18ConfigSet, donde encontrar, para cada procesador, todos los bits de configuracin con su correspondiente nomenclatura.

  • DEFINICIONES DE HARDWARE

    Para facilitar la programacin y el mantenimiento de una aplicacin basada en microcontrolador, es comn la definicin de una serie de alias. Para la placa de prcticas utilizaremos los siguientes alias:

    #define LED_VERDE LATBbits.LATB0 #define LED_AMARILLO LATBbits.LATB1 #define R_CALENTAMIENTO LATCbits.LATC1 #define VENTILADOR LATCbits.LATC2

    #define LED_APAGADO 1 #define LED_ENCENDIDO 0 #define ACTUADOR_OFF 0 #define ACTUADOR_ON 1

    La utilizacin es sencilla. Ejemplos:

    LED_VERDE = LED_ENCENDIDO; // Enciende el Led verde de la placa VENTILADOR = ACTUADOR_ON: // Enciende el Ventilador de la placa LED_AMARILLO = !LED_AMARILLO; // Complementar el estado del Led amarillo

    UTILIZACIN DE RETARDOS

    El MPLAB C18 incluye unas libreras para facilitar la generacin de retardos puros (el microcontrolador pierde el tiempo). Para utilizarlas, es necesario aadir en el programa principal #include. La llamada a una funcin es del tipo:

    Delay10KTCYx(250); // Retardo de 0.5 segundos, 250 x 10,000 ciclos (cada ciclo son 200ns a 20MHz)

    UTILIZACIN DEL TIMER0 DEL PIC18F458

    El PIC18F458 tiene 4 timers o temporizadores (TIMER0, 1, 2 y 3). El compilador MPLAB C18 incluye unas libreras para facilitar el manejo de los temporizadores.

    TIMER0

    Es necesario incluir la cabecera #include Configuracin del Timer0 (tpicamente despus de las inicializaciones):

    - con interrupcin del programa principal - de 16 bits (cuenta desde 0 hasta 216 -1 (65535) - fuente interna de pulsos - prescalador (divisor de frecuencia) por 64

    OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_64 );

    Si cada ciclo de reloj son 200ns y tenemos un prescaler de 64, el periodo de reloj ser:

    200 ns x 64 x 216 = 0.83886 segundos

  • Cuando el timer llega a 0xFFFF (65535), con el siguiente pulso da la vuelta y empieza en 0x0000, activando el bit (INTCONbits.TMR0IF). Es necesario borrar este bit en el programa principal o en el servicio de interrupcin para poder detectar que el timer llega al final de nuevo.

    MANEJO DE INTERRUPCIONES

    El microcontrolador PIC18F458 dispone de interrupciones de alta y baja prioridad, que permiten interrumpir el programa principal y as conseguir implementar aplicaciones en tiempo real.

    INTERRUPCIONES DE ALTA PRIORIDAD

    El microcontrolador salta a la direccin de memoria de programa (ROM) 0x08. All se incluir un salto a nuestra rutina de servicio de interrupcin. En la rutina del servicio de interrupcin deberemos preguntar de qu interrupcin se trata. Muy importante es borrar el bit de interrupcin correspondiente para evitar interrupciones reentrantes.

    Para inicializar una interrupcin de alta prioridad hay que realizar 3 pasos: - indicar la interrupcin en concreto. Ej. OpenTimer0(TIMER_INT_ON ....) - indicar prioridad alta (INTCON2bits.TMR0IP = 1) - habilitar las interrupciones con prioridad

    RCONbits.IPEN = 1; // Enable priority levels INTCONbits.GIEH = 1; // Enable interrupts.

    INTERRUPCIONES DE BAJA PRIORIDAD

    El PIC18F458 dispone de interrupciones de baja prioridad, es decir, aquellas que pueden ser interrumpidas por interrupciones de alta prioridad. En este caso, el microcontrolador salta a la direccin de memoria de programa (ROM) 0x18.

    Para inicializar una interrupcin de baja prioridad es necesario:

    - indicar la interrupcin en concreto. Ej. OpenTimer0(TIMER_INT_ON ....) - indicar prioridad baja (INTCON2bits.TMR0IP = 0) - habilitar las interrupciones con prioridad

    RCONbits.IPEN = 1; // Enable priority levels INTCONbits.GIEL = 1; // Enable low priority interrupts. INTCONbits.GIEH = 1; // Enable interrupts.

  • Ejemplo Interrupcin Alta prioridad:

    #include

    void InterruptHandlerHigh();

    void main(void) {

    OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_64 ); INTCON2bits.TMR0IP = 1; // High priority for Timer0 RCONbits.IPEN = 1; // Enable priority levels

    INTCONbits.GIEH = 1; // Enable interrupts

    while(1) { // programa principal del usuario ... }

    }

    //----------------------------------------------------------------------------

    #pragma code InterruptVectorHigh = 0x08 void InterruptVectorHigh(void) { _asm goto InterruptHandlerHigh //jump to interrupt routine _endasm }

    //---------------------------------------------------------------------------- // High priority interrupt routine

    #pragma code #pragma interrupt InterruptHandlerHigh

    void InterruptHandlerHigh() { if(INTCONbits.TMR0IF) // Ha llegado la interrupcin del Timer0 { INTCONbits.TMR0IF = 0; // Borrar interrupcin // Cdigo usuario... }

    }

  • Ejemplo Interrupcin Baja prioridad:

    #include

    void InterruptHandlerLow();

    void main(void) {

    OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_64 );

    INTCON2bits.TMR0IP = 0; // Low priority for Timer0 RCONbits.IPEN = 1; // Enable priority levels INTCONbits.GIEL = 1; // Enable interrupts INTCONbits.GIEH= 1; // Enable interrupts

    while(1) {

    }

    }

    //---------------------------------------------------------------------------- // Low priority interrupt vector

    #pragma code InterruptVectorLow = 0x0018 void InterruptVectorLow(void) { _asm goto InterruptHandlerLow //jump to interrupt routine _endasm }

    //---------------------------------------------------------------------------- // High priority interrupt routine

    #pragma code #pragma interrupt InterruptHandlerLow

    void InterruptHandlerLow() { if(INTCONbits.TMR0IF) // Ha llegado la interrupcin del Timer0 { INTCONbits.TMR0IF = 0; // Borrar interrupcin // Cdigo usuario... }

    }

  • UTILIZACIN DEL PWM

    El PIC18F458 dispone de un PWM hardware basado en el TIMER2. Para utilizar el PWM, en necesario seguir los siguientes pasos:

    - incluir la cabecera #include - Inicializar el PWM (antes del bucle infinito de control)

    OpenPWM1(200);// Establecemos la frecuencia de trabajo OpenTimer2(TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_16);

    - Imposicin del ciclo de trabajo: SetDCPWM1(Ciclo de trabajo con 10 bits);