float llegir_temperatura (void)
{
int temp;
float temperatura;
unsigned char correcte=1, crc[9], i, error=0;
_IC1IE = 0; //Desactiva interrupció IC1
_INT1IE = 0; //Desactiva interrupció Interrupcio Externa 1
_INT2IE = 0; //Desactiva interrupció Interrupcio Externa 2
while (correcte != 0)
{
while (pols_reset_OW()==1); //Realitzar reset i esperar pols presència ds18b20
escriure_byte_OW(Skip_rom); //Saltar orde ROM
escriure_byte_OW(Convert_T); //Indicar a ds18b20 que realitzi conversió temperatura
while (llegir_bit_OW()==0); //Esperar que ds18b20 acabi conversió temperatura
while (pols_reset_OW()==1); //Realitzar reset i esperar pols presència ds18b20
escriure_byte_OW(Skip_rom); //Saltar orde ROM
escriure_byte_OW(Read_scratchpad); //Llegir dades de ds18b20
for (i=0; i<9; i++)
{
crc[i] = llegir_byte_OW(); //Guarda el valor dels 9 bytes del scratchpad
}
correcte = comprovar_crc(crc); //Comprovar si la lectura ha estat correcte
//Al quart intent de lectura amb fallo CRC sortir i avisar
}
_IC1IE = 1; //Activa interrupció IC1
_INT1IE = 1; //Activa interrupció Interrupcio Externa 1
_INT2IE = 1; //Activa interrupció Interrupcio Externa 2
temp = crc[1] << 8;
temp = temp | crc[0]; //Uneix LSB i MSB de la temperatura en 2 bytes
if (temp & 0x80) //Temperatura negativa
{
temp = ~temp + 1;
temperatura = (((float) temp)/16)* (-1);
}
else //Temperatura positiva
temperatura = ((float) temp)/16;
return (temperatura);
}
T4CONbits.TON = 1; //Activa el Timer 4 en mode 16 bits
_T4IE = 1;
while (correcte != 0)
{
TMR4 = 0;
PR4 = 0xF424;
_LATA0 = 1;
while (_T4IF != 1);
_LATA0 = 0;
_T4IF = 0;
while (_T4IF != 1)
{
if (pols_reset_OW()==0)
{
error = 0;
//break;
}
else
{
error = 1;
correcte = 0;
}
}
_T4IF = 0;
Lamentablemente si no queres esperar vas a tener que usar interrupciones.
Mi pregunta es...
¿Tan rapida es la comunicacion con el DS18B20 que no podes tener habilitada las interrupciones?
Digo por que ejecutar un poco de codigo (que es lo que deberia ser una interrupcion), en un PIC24 que imagino que ira a cerca de 80Mhz te llevaria nanosegundos y tenes una GRAN amplitud de tiempo como para mandar/recibir el dato.
Ejemplo mandar un 0 al DS18B20 (me fije en el datasheet) implica tenerlo en 0 al menos 15us como maximo (75 instrucciones a 20Mhz,150 a 40Mhz y es sufficiente como para una interrupcion) y luego en 1 hasta completar los 60 minimo a 120 us maximos ( La cantidad de instrucciones que pueden ir aqui son demasiadas).
En fin, por eso preguntaba si era que necesitabas desactivar las interrupciones. Para que sea mas rapido podes usar una interrupcion por el puerto (si es que posee) y si tenes un timer corriendo usar ese valor para saber exactamente el tiempo entre un dato y otro, tratando de hacer una especie de maquina de estado en la interrupcion.No acabo de entender exactamente lo que quieres decir con eso. Comunicar el pic con el DS18B20 a través de interrupciones y calcular los tiempos a través de un timer?
Con respecto a que falle el cable, no te queda otra que implementar una especie de "timeout", o tomas un timer que esta corriendo, cuando mandas el pulso tomas el tiempo y luego vas preguntando, si supero cierta cantidad de ciclos del timer significaria que hubo algo malo y procedes a salir del while + activar una bandera que indique un error.
Si tenes un timer de mas directamente usas ese timer como timeout y se vuelve mas simple ya que solo te fijas en el flag.
Ademas tenes que considerar que tenes parado el micro esperando los datos cuando la conversion puede durar hasta 750ms maximo en 12-bit, es MUCHO.Si. Pero para la aplicación, aunque a priori es desaprovechar el pic, no es un problema.
Mi primea idea era lo que comentas último. Hacer correr el timer4 para que generara interrupción al cabo de x tiempo. Lo que no acabo de ver es como hacer salir del bucle. Había pensado en cambiar de estado una variable y que fuera condición del bucle, no se. Lo que pasa es que tengo las funciones hechas en una libreria a parte del programa principal y no se como pasar la variable para que la reconozca (hacia mucho tiempo que no programaba en C y me estoy volviendo loco con la visibilidad de las variables intentando que no sean globales)
CitarMi primea idea era lo que comentas último. Hacer correr el timer4 para que generara interrupción al cabo de x tiempo. Lo que no acabo de ver es como hacer salir del bucle. Había pensado en cambiar de estado una variable y que fuera condición del bucle, no se. Lo que pasa es que tengo las funciones hechas en una libreria a parte del programa principal y no se como pasar la variable para que la reconozca (hacia mucho tiempo que no programaba en C y me estoy volviendo loco con la visibilidad de las variables intentando que no sean globales)
Para salir de un while() utiliza un break;Código: C
while(1) { if(Flag_timer_4) { timeout=1; break; } }
El break te sirve para salirte del os for(), do..while y while