Consulta de OSCCAL en PIC12F629

Buenas que tal...
me estoy involucrando con el pic 12f629... y tengo dudas con el valor del osccal de fabrica.... entiendo que el valor original hay que guardarlo para que pueda funcionar a 4Mhrz correctamente... pero entonces porque hay programas en hex que necesitan el osc int y lo cambian a por ejemplo 80??? se que hay que ponerlo que no lo cambie cuando pregunta... pero porque en el programa le da la instruccion de cambiarlo?
otra cosa mas... se puede recuperar? creo haber leido por ahi que hay una especie de circuito con un socalo para el pic para configurarlo nuevamente a un valor de la pos 0x03ff al valor que tenia correspondiente a su funcionamiento en 4 mhrz... puede ser?
desde ya gracias!
 
ok , gracias!

ya estuve averiguando... y logicamente cuanto mas sé, mas dudas me surgen.
por ejemplo el MCLR si no lo activo (OFF) no puedo regrabar el micro... correcto?
pero si lo activo solo puedo usar el puerto GP3 como interrupcion y no como entrada de datos común... no es cierto???

por cierto... cual seria un buen código en ensamblador para calibrar el OSC INT??? porque lei unos cuantos y no se cual me es mejor...
desde ya gracias!!!
 
por cierto... cual seria un buen código en ensamblador para calibrar el OSC INT??? porque lei unos cuantos y no se cual me es mejor...
desde ya gracias!!!

Yo creeria que el suministrado por Microchip, aca te lo subo, personalmente no lo probe, chauuuuuuu
 

Adjuntos

  • 00250a.pdf
    233.9 KB · Visitas: 404
  • an250.zip
    3.5 KB · Visitas: 160
Ese datasheet no lo tenia Gracias!
igualmente por lo que leo es para RE-calibrar el pic... yo quiero dejarlo a la frecuencia normal de 4Mhrz con el valor de 0x3FF.
creo que es algo como:
Código:
bsf              STATUS,RP0           ;ir al banco 1
call             3FFh                      ;toma el valor de osc por defecto en el pic
movwf         OSCCAL                  ;lo calibra en el registro OSCCAL
bcf              STATUS,RP0           ;vuelve al banco 0


hasta acá creo que esta bien (según el datasheet) pero tambien creo que antes de finalizar el programa se tiene que poner unas instrucciones mas... puede ser???


IGUALMENTE sigo con la duda del MCLRE si lo desactivo puedo usar el GP3 como entrada común... si lo activo como interrupcion pero si no lo activo no puedo reescribir el PIC... no es cierto???
o sea que mi única alternativa es usarlo como interrupcion si luego quisiera reusar el PIC
 
Última edición:
Mira , el pin MCLR lo puedes usar como entrada,solo como entrada.

Si desactivas MCLR no pasa nada al querer reprogramar , solo tienes que enviar VPP primero antes que VCC al pic para que no se haga el loco.

Por eso en el pickit2 trae la opción de VPP first Entry.

También te comento que yo tengo configurado el pin MCLR como entrada y tiene la función de RX junto con la interru´pción por cambio de estado.

Te adjunto un fragmento de una minicontroladora de servos.
El pic recibe los comandos seriales por RA3 osea MCLR. Hecho en C con CCS

Mira esta línea

enable_interrupts(INT_RA3); //Habilitamos interrupcion por cambio de estado
//en pin RA3

Código:
void main(){
 
   setup_comparator(NC_NC_NC_NC);      //Comparador deshabilitado
 
   output_A(0x00);                     //Latch 
   set_tris_A(0B001000);               //MCLR=A3= RX input Int_RA3 on Change
  
   enable_interrupts(GLOBAL);          //Interrupciones Habilitadas
   enable_interrupts(INT_TIMER1);      //Habilitamos interrupcion desborde TMR1
   SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);
   enable_interrupts(INT_RA3);         //Habilitamos interrupcion por cambio de estado
                                       //en pin RA3
 
 
//---------  PROGRAMA PRINCIPAL   -----------------------------\\\\
 
   while(1){  
         
         for(indice=0;indice<n_servos;indice++){      //Toma valor de n servos
               aux=T_Servo[indice];      
               aux=65091-(aux*8);
               SET_TIMER1(aux);
 
               switch(indice){                  //1 Lógico a servo correspondiente
               case 0:output_high(Servo_1);break;
               case 1:output_high(Servo_2);break;
               case 2:output_high(Servo_3);break;
               case 3:output_high(Servo_4);break;
               case 4:output_high(Servo_5);break;
               }//switch
 
               while(flag_timer1==FALSE){}     //Loop Mientras no desborde TMR1
               flag_timer1=FALSE;
 
               switch(indice){                  //0 lógico a servo correspondiente
               case 0:output_low(Servo_1);break;
               case 1:output_low(Servo_2);break;
               case 2:output_low(Servo_3);break;
               case 3:output_low(Servo_4);break;
               case 4:output_low(Servo_5);break;               
               }//switch
 
         }// for  
//++++++++++++   ACTUALIZACION DE LOS SERVOMOTORES +++++++//
   if(flag_rx==TRUE){
         if(dato_recibido>=251){                    //Si es mayor a 250 es Servo,si Flag=TRUE es posicion
           indice_rx=(0xFF-dato_recibido);          //operacion lógica AND solo servos de 0-5        
           flag_Supdate=TRUE;                       // YA se puede actualizar el valor del servo
            if(aux2==2)aux2=0;                      //corrigiendo posible error de recepcion
            }
      if(dato_recibido<=250&&flag_Supdate==TRUE){
                  T_Servo[indice_rx]=dato_recibido;   //Actualizando valor del servo
                  flag_Supdate=FALSE;                 //Reiniciamos varibles 
                  dato_recibido=0;                    //Tarea completada
                  }
   flag_rx=FALSE;
   }//if--rx              
//+++++++++++++++++++Pausa de 10 ms  +++++++++++++++++++//         
               SET_TIMER1(55536);               //10ms
               while(flag_timer1==FALSE){}     //Loop Mientras no desborde TMR1
               flag_timer1=FALSE;
       }//loop end while
   
 
}//end main
 
 
//+++++++++++++++   INTERRUPCIONES   +++++++++++++++++++//
#INT_TIMER1
void desborde_TMR1(){                 //Interrupcion por desborde de timer
   flag_timer1=TRUE;
} // interrupcion TMR1
 
#INT_RA
void recepcion(){                    //Interrupcion por cambio de estado en pines
   if(!input(PIN_A3)){          // Bit de inicio ???
      dato_recibido=getc();     //Recibir dato
      flag_rx=TRUE;            //Dato recibido
      }//if
} //int_ra3
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++//
 
Mira , el pin MCLR lo puedes usar como entrada,solo como entrada.

Si desactivas MCLR no pasa nada al querer reprogramar , solo tienes que enviar VPP primero antes que VCC al pic para que no se haga el loco.

Por eso en el pickit2 trae la opción de VPP first Entry.

También te comento que yo tengo configurado el pin MCLR como entrada y tiene la función de RX junto con la interru´pción por cambio de estado.

Te adjunto un fragmento de una minicontroladora de servos.
El pic recibe los comandos seriales por RA3 osea MCLR. Hecho en C con CCS

Mira esta línea

enable_interrupts(INT_RA3); //Habilitamos interrupcion por cambio de estado
//en pin RA3

Código:
void main(){
 
   setup_comparator(NC_NC_NC_NC);      //Comparador deshabilitado
 
   output_A(0x00);                     //Latch 
   set_tris_A(0B001000);               //MCLR=A3= RX input Int_RA3 on Change
  
   enable_interrupts(GLOBAL);          //Interrupciones Habilitadas
   enable_interrupts(INT_TIMER1);      //Habilitamos interrupcion desborde TMR1
   SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);
   enable_interrupts(INT_RA3);         //Habilitamos interrupcion por cambio de estado
                                       //en pin RA3
 
 
//---------  PROGRAMA PRINCIPAL   -----------------------------\\\\
 
   while(1){  
         
         for(indice=0;indice<n_servos;indice++){      //Toma valor de n servos
               aux=T_Servo[indice];      
               aux=65091-(aux*8);
               SET_TIMER1(aux);
 
               switch(indice){                  //1 Lógico a servo correspondiente
               case 0:output_high(Servo_1);break;
               case 1:output_high(Servo_2);break;
               case 2:output_high(Servo_3);break;
               case 3:output_high(Servo_4);break;
               case 4:output_high(Servo_5);break;
               }//switch
 
               while(flag_timer1==FALSE){}     //Loop Mientras no desborde TMR1
               flag_timer1=FALSE;
 
               switch(indice){                  //0 lógico a servo correspondiente
               case 0:output_low(Servo_1);break;
               case 1:output_low(Servo_2);break;
               case 2:output_low(Servo_3);break;
               case 3:output_low(Servo_4);break;
               case 4:output_low(Servo_5);break;               
               }//switch
 
         }// for  
//++++++++++++   ACTUALIZACION DE LOS SERVOMOTORES +++++++//
   if(flag_rx==TRUE){
         if(dato_recibido>=251){                    //Si es mayor a 250 es Servo,si Flag=TRUE es posicion
           indice_rx=(0xFF-dato_recibido);          //operacion lógica AND solo servos de 0-5        
           flag_Supdate=TRUE;                       // YA se puede actualizar el valor del servo
            if(aux2==2)aux2=0;                      //corrigiendo posible error de recepcion
            }
      if(dato_recibido<=250&&flag_Supdate==TRUE){
                  T_Servo[indice_rx]=dato_recibido;   //Actualizando valor del servo
                  flag_Supdate=FALSE;                 //Reiniciamos varibles 
                  dato_recibido=0;                    //Tarea completada
                  }
   flag_rx=FALSE;
   }//if--rx              
//+++++++++++++++++++Pausa de 10 ms  +++++++++++++++++++//         
               SET_TIMER1(55536);               //10ms
               while(flag_timer1==FALSE){}     //Loop Mientras no desborde TMR1
               flag_timer1=FALSE;
       }//loop end while
   
 
}//end main
 
 
//+++++++++++++++   INTERRUPCIONES   +++++++++++++++++++//
#INT_TIMER1
void desborde_TMR1(){                 //Interrupcion por desborde de timer
   flag_timer1=TRUE;
} // interrupcion TMR1
 
#INT_RA
void recepcion(){                    //Interrupcion por cambio de estado en pines
   if(!input(PIN_A3)){          // Bit de inicio ???
      dato_recibido=getc();     //Recibir dato
      flag_rx=TRUE;            //Dato recibido
      }//if
} //int_ra3
 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++//

gracias por tu respuesta... pero y si no dispongo de un pickit2??? solo tengo un programador JDM....
en fin.... igualmente me estoy dando por vencido con este tema despues de haber arruinado 2 pics de ellos... (ya que me daba error al reprogramarlos)
Saludos!!!

kenoby dijo:
gracias por tu respuesta... pero y si no dispongo de un pickit2??? solo tengo un programador JDM....
en fin.... igualmente me estoy dando por vencido con este tema despues de haber arruinado 2 pics de ellos... (ya que me daba error al reprogramarlos)
Saludos!!!
Código:
ERROR -> De escritura en direccion 0x002007
   Escrito : 03194   Leído : 0x0004
me tira ese error

lee todo "0000"
sin embargo todavía lee el OSC a 3424 en 03fff
 
Última edición:
Puedo recuperar el OSCCAL del pic12f629 desde mi programador
pickit 2 clone??? u otro programador usb????
No, cuando se pierde el valor de calibración de fábrica, es porque se ha sobre escrito la dirección. 0x3FF
Por eso es recomendable guardar ese valor antes de grabar el PIC,
y no permitir que esa dirección sea escrita, reservando esa locación de memoria.

Existen varias formas para recuperar el valor de OSCCAL.
Una sencilla que es la que yo utilizo, es hacer un programa que incremente el valor de OSCCAL de 10 en 10.
Y mandar alguna frase por RS-232 a 2400bps, conteniendo el valor actual de OSCCAL.
Cuando en el Hyperterminal se puedan leer tres de los envíos, tomas el valor central.
Ese será el valor que debes usar para calibrar el oscilador interno.

Suerte.
 
Que diagrama armo y que software ...

Disculpa las preguntas
necesito los pasos! .... quiero rescatar 6 pics para
armar un proyectos de eficiencia energética!!

Gracias!
 
Que diagrama armo y que software ...

Disculpa las preguntas
necesito los pasos! .... quiero rescatar 6 pics para
armar un proyectos de eficiencia energética!!

Gracias!
OK. Adjunto el programa con el que recupero el valor de OSCCAL.
Dentro del archivo vienen también esquema, archivos hex, e instrucciones.

Cualquier duda, puedes preguntar.

Saludos.
 

Adjuntos

  • OSCCALRT.jpg
    OSCCALRT.jpg
    41.3 KB · Visitas: 143
  • 12F6XX OSCCAL Recovery Tool.rar
    73.2 KB · Visitas: 23
Hola Darkbytes.He probado el recuperador pero no se si lo estoy haciendo bien, ya que cuando le doy a convertir se me iluminan los pines , pero cuando lo coloco en el programador no sale el valor osccal en la linea correspondiente.Que estoy haciendo mal? Gracias
 
Hola D@rkbytes. He probado el recuperador pero no sé si lo estoy haciendo bien, ya que cuando le doy a convertir se me iluminan los pines, pero cuando lo coloco en el programador no sale el valor osccal en la línea correspondiente. ¿Qué estoy haciendo mal? Gracias.
En el post #14 dentro del archivo adjunto, se encuentran las instrucciones.
Si haces todo tal cual se indica ahí, no debes tener ningún problema.
 
Atrás
Arriba