martes, 8 de noviembre de 2011

Oscilador Interno de PIC (Pic C CCS) y #FUSES

Oscilador Interno de PIC (Pic C CCS)
Haz Parpadear un LED

Cuentas veces tenemos proyectos escolares o de trabajo donde no es necesaria tanta precisión en cuestiones de tiempo, es decir, no tenemos comunicación USB ni comunicación Serial o PWM que necesiten tiempos exactos de apagado - encendido y no queremos colocar un Oscilador externo, porque en primera, cuestan, da flojera conectarlos, ocupan espacio etc...

Bien ahora lo bueno, podemos usar el oscilador interno de nuestro PIC, si es que nuestro pic lo permite, que ahora la gran mayoría lo hace, antes que nada, voy a colocar un poco de introducción a los FUSES, así es, Fusibles en español, que son registros en el Pic que le indican al PIC como comportarse (tiene que ser buen chico!!! LOL ).






Coloco el siguiente fragmento:
La palabra fuse viene a significar fusible. Sonará bastante raro, que un PIC pueda tener fusibles, pero nos sonará más familiar cuando comprendamos su funcionamiento. Hay ciertos aspectos del PIC que han de ser activados o desactivados mediante hardware a la hora de programarlo. Esto quiere decir que no se pueden volver a cambiar  hasta que el chip no se reprograme de nuevo. Como no se pueden cambiar, de ahí le viene que sea como un fusible, el cual han fundido intencionadamente para proteger el modo de funcionamiento del procesador. Esto suena a tontería, pero en la realidad se aplica con fusibles de verdad. 
Extraído de:  Fuente



Ahora, como sabemos, de cajón tenemos que colocar un oscilador, así que hay que decidirnos el interno o el externo, como dice el título de esta entrada, usaremos en interno, por tanto el codigo para programar un PIC16f627A quedaría de la siguiente manera (el codigo se explica por sí mismo):




#include <16f627a.h>
#fuses NOWDT         //Deshabilita Watchdog
//#fuses INTXT            //Cristal Externo
//#fuses RC                //Oscilador RC (Resistencia Capacitor Externos)
//#fuses HS                //Modo Full Power de alta Velocidad, hasta 10MHZ, más depende el micro
//#fuses LP                //Modo Bajo Consumo hasta 200KHZ
#fuses INTRC         //Cristal Interno RC
#use delay(clock=4000000)
void main()
{
   set_tris_b(0);
   //setup_oscillator(OSC_4MHZ);       
      //No es necesaria esta instruccion debido a que al momento de usar INTRC y                    
      //delay(clock=...) el Oscilador interno se programa en automatico
   output_low(PIN_B1);
   
   while(1)
   {
      output_toggle(PIN_B1);           //Cambiamos el estado del Pin,
      delay_ms(100);                   //Esperamos a lo sonso 100 ms
   }
}

Pequeño esquematico

Recordar que una lista completa de los Fuses que soporta tu Pic está dentro del .h del pic mismo y un análisis más detallado lo encuentras en la datasheet del mismo.

Que disfruten!!!!!!!!

13 comentarios:

  1. Hola muy buenas, dispongo de un 16f88 (Que también dispone de reloj interno) y no consigo hacerlo funcinar. y no tengo ni idea, por que puede ser.

    Pongo tu programa y no parpadea el led y pongo este:

    /*#include <16f88.h>
    #use delay (clock=8M)
    #fuses INTRC_IO, NOMCLR

    main(){
    output_high(PIN_A0);
    output_low(PIN_A1);
    delay_ms(2000);
    output_low(PIN_A0);
    output_high(PIN_A1);
    }

    Y tarda unos 8 minutos en conmutar. ¿Alguna idea?

    Un saludo.

    ResponderEliminar
    Respuestas
    1. Según yo tienes que poner "internal=8M" en vez de "clock=8M". A mí me funciona. PD. Si la intención de tu programa es que las salidas A0 y A1 parpadeen tu código tendría que ser más o menos así:

      #include <16f88.h>
      #fuses INTRC_IO, NOMCLR
      #use delay (internal=8M)

      void main(){
      while (true){
      output_high(PIN_A0);
      output_low(PIN_A1);
      delay_ms(2000);
      output_low(PIN_A0);
      output_high(PIN_A1);
      delay_ms(2000);
      }
      }

      De lo contrario solo conmutarían una vez.

      Eliminar
  2. Sergio Andréz Gutiérrez Rojas.28 de septiembre de 2013, 20:24

    Muchas gracias, tío! me sirvio no solo para usar el oscilador interno si no ademas para darme cuenta que los fueses dan un bitconfig al micro que si le das borrar primero al PIC el Programador te los borra y te pone por defecto 3FF cosa que hace que el bitconfig no sea el que tenia tu codigo y que NUNCA funcione. Dure 5 dias intentando de todo estaba apunto de tirar los PICS y el programador a la luna, hasta que probando tu código me di cuenta del error, solo hay que darle Write, el Pickit 2 no solo se encarga de borrar en el proceso si no que ademas de esa forma no cambia el config de los fuses de tu micro y FUNICONA!!, gracias de nuevo.

    ResponderEliminar
  3. Hola, también uso un PIC 16F88 pero no logro hacer funcionar este es el programa:

    #include <16f88.h>

    #FUSES HS // High speed Osc (> 4mhz for PCM/PCH) (>10mhz
    // for PCD)
    #FUSES MCLR // Master Clear pin enabled
    #FUSES NOBROWNOUT // No brownout reset
    #FUSES NOLVP // No low voltage prgming, B3(PIC16) or B5
    // (PIC18)used for I/O
    #FUSES NOCPD // No EE protection
    #FUSES NOPUT // No Power Up Timer
    #FUSES NOPROTECT // Code not protected from reading
    #FUSES NOWDT // No Watch Dog Timer
    #USE delay(internal=20000000) // Frecuencia de 20Mhz
    #USE standard_io(B) // Configuramos el PORTB

    #DEFINE Led_blink PIN_B0 // Definimos el PIN RB0 como "Led.blink"
    #DEFINE Retardo 500 // Definimos 500 como "Retardo"

    void main()
    {
    disable_interrupts(GLOBAL); // Desactivamos las interrupciones
    while(true) // Bucle infinito. True = 1
    {
    output_high(Led_blink); // Activamos RB0
    Delay_ms(Retardo); // Esperamos 0.5 segundos
    output_low(Led_blink); // Desactivamos RB0
    Delay_ms(Retardo); // Esperamos 0.5 segundos
    } // End while(TRUE)
    } //Fin void main

    ResponderEliminar
  4. Hola Buen dia:

    Respecto al inconveniente con el pic16f88 con la problematica de que no parpadea el LED. Utilice algunos de tus comandos y me funciono perfectamente.

    Agradesco tu aporte a la comunidad.

    Este es el codigo que implemente en el Pic16f88

    //////////////////////////////////////////////////////////////////////////

    #include <16f88.h>
    #use delay(internal=8M)



    #fuses INTRC_IO
    #fuses NOWDT
    #fuses PUT
    #fuses NOMCLR

    void main(){


    set_tris_b(0b11101111);// B4 Salida


    output_low(pin_b4);





    while(true){

    output_toggle(pin_b4);
    delay_ms(200);


    }

    }

    ResponderEliminar
  5. INTXT es para oscilador interno y externo a la vez, el externo (crystal) para el modulo usb y el interno para el CPU del micro y demas perifericos.. corregirme si no estoy en lo cierto por favor..

    ResponderEliminar
    Respuestas
    1. Es correcto.

      Puedes encontrar la referencia al FUSE dentro del .h de cada pic.

      "A list of all valid options has been put at the top of each
      devices .h file in a comment for reference. The PCW device edit utility can modify a particular devices
      fuses. The PCW pull down menu VIEW | Valid fuses will show all fuses with their descriptions."

      Saludirijillos

      https://www.ccsinfo.com/downloads/ccs_c_manual.pdf

      Eliminar
  6. me gusta el blog. felicitaciones de verdad me ha ayudado a aclarar algunas cosas. antes no sabia nada de esto.

    ResponderEliminar
  7. hola, quiero hacer una matriz de leds giratorios y en la simulacion me trabaja perfectamente, pero cuando lo pruebo en el protoboard no es asi... me pueden colaborar con la instruccion para utilizar el oscilador interno es que no se si lo estoy haciendo mal... gracias...

    ResponderEliminar
  8. Te recomiendo que hagas tu proyecto de forma incremental.
    Apuesto a que conectaste todo en la Protoboard (micro, leds, resistencias...) esperando a que funcionara y no fue así.

    Primero conecta el micro solo con lo mínimo necesario: MCLR, VCC y GND. Después trata de hacer un LED parpadear.
    Ya que tienes lo anterior es entonces cuando estarás seguro que el micro está conectado correctamente a la proto y todo funciona bien, es ahora cuando intentas cargar otro programa más completo.

    Como nota, siempre ten un LED conectado a un pin del micro y haz que parpadee cada cierto tiempo, de esta forma siempre sabrás si el micro está funcionando, si no parpadea podría significar que el programa falló o el micro está mal conectado y descartas otro tipo de errores. A este forma de colocar un LED se le conoce como Alive LED

    ResponderEliminar
  9. Disculpe, ¿Qué diferencia hay entre INTRC y INTRC_IO?
    Saludos

    ResponderEliminar
  10. INTRC hará que el pic use por default el oscilador RC interno.
    INTRC_IO hará que el pic use de igual forma el oscilador RC interno, pero además el pin CLKOUT estará activado y tendrá una señal de salida cuadrada igual a la oscilación interna.

    CPD Data EEPROM Code Protected
    NOCPD No EE protection
    PROTECT Code protected from reads
    NOPROTECT Code not protected from reading
    NOMCLR Master Clear pin used for I/O
    MCLR Master Clear pin enabled
    PUT Power Up Timer
    NOPUT No Power Up Timer
    INTRC_IO Internal RC Osc, no CLKOUT
    INTRC Internal RC Osc
    RC_IO Resistor/Capacitor Osc
    RC Resistor/Capacitor Osc with CLKOUT
    BROWNOUT Reset when brownout detected
    NOBROWNOUT No brownout reset

    ResponderEliminar