Codigo CCS que deja identificable el pic

Pues se trata de eso, un código que cada vez que se lo meto me da una mala programación y el pic queda que no lo vuelve a reconocer, se trata del 16f818 y ya me he cargado 6. El pic queda grabado, pero ya no se puede volver a regrabar y no lo reconoce.
El código consiste en una secuencia de comparaciones en las que cambio mayor por menor, es la UNICA diferencia.
Posteo los dos códigos, uno que funciona perfectamente con el mayor en la secuencia de comparaciones del main, y el que destruye el pic. Haber si sabeis a que se debe.
Porque yo lo achaco a un fallo del ccs.
Debo decir que el programador funciona perfectamente, es la primera vez que me pasa esto. Y el código he probado también a darle un valor fijo a la variable TA por si fuese que se queda con la posibilidad de que en algún momento no tenga valor, pero me extrañaria que fuese eso, ya que como he dicho el pic queda inservible.

Gracias por la ayuda.

Codigo correcto y completo:

Código:
#include <16f818.h>
#device ADC=10
#fuses nowdt,noput,nobrownout,protect,NOMCLR,INTRC_IO 
//nomclr... habilita la patita mclr para que sea RA5 (I/O) 
//intrc_io... usa reloj interno, habilita RA6 y RA7 como I/O 
#use delay(clock=8000000) 
#use standard_io(b)
float valor;
int TA;
int TB;
const int MAX=20;

void configura_adc(){
     setup_adc(ADC_CLOCK_INTERNAL);
     setup_adc_ports(AN0);
}
void lectura_adc(){
     valor=0.0;
	 set_adc_channel(0);
     //delay_ms(1);
     valor=read_adc();
	 valor=valor*0.00477;
	 //valor=valor*3.2185;
}

void retrasando(){
    TB=MAX-TA;
    switch (TA){
       case 0:
			output_b(0X3F);break;
       case 8:
            output_b(0X0C);break;
       case 9:
			output_b(0X5B);break;
       case 10:
       	    output_b(0X5E);break;
       case 11:
            output_b(0X6C);break;
	   case 12: 
			output_b(0X76);break;
       case 14:
            output_b(0X67);break;
       case 16:
			output_b(0X1C);break;
       case 18:
       		output_b(0X7F);break;
       case 20:
			output_b(0X7C);break;
    }
    if (TA!=20){
       output_low(PIN_A1);
       delay_ms(TB);
    }
    if (TA>0 && TA<21){
        output_high(PIN_A1);
        delay_ms(TA);
    }
       
}

void main(){
configura_adc();
do{
      lectura_adc();
[B]      if (valor>0.0){
         TA=0;
      }   
      if (valor>0.5){
         TA=8;
      }
      if (valor>1.0){
         TA=9;
      }
      if (valor>1.5){
         TA=10;
      }
      if (valor>2.0){
         TA=11;
      }   
      if (valor>2.5){
         TA=12;
      }
   	  if (valor>3.0){
         TA=14;
      }
      if (valor>3.5){
         TA=16;
      }
	  if (valor>4.0){
         TA=18;
      }
	  if (valor>4.5){
         TA=20;
      }[/B]
   
      
      retrasando();
   
}while (true);
}

Y esta es la parte del codigo que modifico:

Código:
.....
.....
void main(){
configura_adc();
do{
      lectura_adc();
     [B] if (valor<10.0){
         TA=0;
      }   
      if (valor<4.5){
         TA=8;
      }
      if (valor<3.0){
         TA=9;
      }
      if (valor<3.5){
         TA=10;
      }
      if (valor<3.0){
         TA=11;
      }   
      if (valor<2.5){
         TA=12;
      }
   	  if (valor<2.0){
         TA=14;
      }
      if (valor<1.5){
         TA=16;
      }
	  if (valor<1.0){
         TA=18;
      }
	  if (valor<0.5){
         TA=20;
      }[/B]
   
      
      retrasando();
......
......
 
Es muy raro que el código te esté provocando eso, usas todas instrucciones comunes y nada inusuales. En el peor de los casos el PIC se trabaría en el programa y con solo resetearlo es suficiente, es muy raro.

PD: el valor que el CCS te lee al poner: read_adc(), ya te lo convierte a volts o es necesario hacer la conversion??
 
No creo que tenga que ver, pero es tan raro que conviene ir descartando cosas...

Quita el FUSE protect. Déjalo en noprotect por ahora.

Se supone que eso es para que el PIC no se pueda leer, pero no que lo deje inservible ¿no?

Por otro lado, comprueba que tu PIC es un 16F818 y no un 16C818, por si acaso.
 
Es que el único cambio que hago es en ese trozo de código. Lo demás esta todo igual que cuando funciona sin problema, y la conversión es correcta ya que el código funciona correctamente y me detecta cada valor de tensión.
Algún valiente se atreve a probar ese código en un pic??
 
¿Qué programador estás usando? Tanto hardware (¿un JDM?) como software.

He podido reproducir el fallo en un 16F88, y creo que también recuperar el chip, pero fallan los dos códigos que pusiste y luego te diré por qué en cuanto lo confirme...

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

Confirmado.

El problema viene como dije del FUSE protect que has puesto, aunque bastante tiene que ver también la no activación del MCLR, que es lo que hace que no puedas desprotegerlo.

Lo que creo que pasa: cuando programas el chip, el programador hace una verificación de cada dirección que programa. La primera vez que lo programas no pasa nada porque el FUSE protect no está todavía puesto, luego cada vez que escribe una dirección la lee y como es igual lo que lee que lo que escribe, todo perfecto.

El problema viene cuando lo programas por segunda vez. Escribe una dirección, pero al leerla inmediatamente, al tener el FUSE protect puesto, lee 0000, con lo cual ¡¡ERROR!!, y no se programa. Tampoco se borra, creo, por no tener el MCLR habilitado (quizá esto haga también que no cambie los FUSES)

Ahora viene el cómo recuperar el chip. He usado un programador JDM por puerto serie y el WinPIC800. Es importante seguir las instrucciones al pie de la letra. Y me supongo que igual que funciona para el 16F88, debería funcionar para otros modelos de PIC, incluido el tuyo.


  • Haces una lectura del PIC (flecha verde). Así es como queda el resultado en mi caso. Puedes ver que los datos son todos 0000, que MCLR no está habilitado y que CP sí lo está.
1.png

2.png


  • Activa el MCRL y quita el CP. Dale a programar (flecha roja).
3.png


  • Al final de la programación dará un error justo en la dirección 0x2007 que es la de los FUSES. Dale a aceptar.
4.png


  • Dale a leer de nuevo el PIC (flecha verde). Verás que el FUSE MCLR ahora sí está activado, pero CP sigue activado a pesar de que lo quitamos. Esto es porque no tenías el MCLR activado y por eso no se programaba bien.
5.png


  • Ahora que tienes el MCRL activo, vuelve a quitar el CP y dale de nuevo a programar (flecha roja).
6.png


  • ¡Ahora no ha dado error de programación! El PIC ya está desprotegido y listo para reutilizar.

Moraleja: trata de dejar activado el MCLR, al menos hasta el último momento, o bien mueve la señal que pusiste en el MCLR a otro pin del integrado. De igual modo, no actives la protección de código hasta tener la versión final del firmware.

Y como decía antes, falla con los dos códigos que pusiste, al menos a mi. Que no te haya fallado en un caso y sí en otro no me lo explico, quizá el compilador saca cosas distintas para un caso y otro, podrías revisar qué FUSES ha compilado en uno y otro caso (desde el WinPIC, al abrir el .hex, puedes verlos).
 
Última edición:
Estoy probandolo, y me da el error de fuse en 0x2007, pero los fuses al volver a darle a leer no me los cambia, se quedan como estan, estoy usando el kit149 que es el único programador que tengo ahora mismo.
Y si que es raro que con el cambio de código que no tiene nada que ver uno funcione y el otro no.
 
Hola

Con el K149 a mi directamente no me reconocía el PIC una vez grabado, por eso tuve que usar el JDM. Con éste, los pasos son tal cual los puse, estuve haciendo el manual a la vez que reparaba mi PIC :D

Un saludo
 
Pues eso es justamente lo que me hace a mi, no me lo reconoce... tendré que esperar a montar el pickit2 que hay por este mismo foro para poder recuperarlos.

Muchas gracias por todo, y por explicarme que es lo que hacia mal.
 
Por lo menos ya sabes que el programador JDM usado desde WinPIC funciona, no sé si con el pickit2 lo hará, igual intenta montarte un JDM que es bien sencillo de hacer, incluso casi lo puedes meter en protobard...
 
Eso me sucedió con micros de otra marca lo que sucede el programa usa los pines done el programador también los usa, lo solucione agregando un retardo antes de configurar los pines al inicio del programa.
Al momento que el programador recatee el chip le un tiempo para este lo capture en modo digital.
Hay un fuse que hace esto eso creo.
 
Atrás
Arriba