#include <16f876.h>
#fuses XT,NOWDT
#use fast_io(c)
#use fast_io(b)
#use delay(clock=4000000)
#include "lcd.c"
#define CS PIN_C0
float valor;
void main(){
set_tris_b(0xFF);
set_tris_c(0b00010000);
setup_spi(spi_master|spi_h_to_l|spi_ss_disabled);
output_low(CS);
lcd_init();
while(1){
lcd_gotoxy(1,1);
while(!spi_data_is_in());
valor=spi_read();
printf(lcd_putc,"Temp=%f grados",valor);
}
}
Hola, no has adjuntado el diseño de proteus.
Para que el sensor te comience a dar una lectura continua de datos hay una secuencia de inicialización que le debes enviar mediante el SPI. En la hoja de datos aparece la secuencia, como un ejemplo ,de una adquisición continua de datos (página 10).
Creo que cuando intentas leer el SPI con (spi_read()), en los parámetros le debes poner algo para que genere el reloj, sino no lo genera (por ejemplo spi_read(0)).
Ten en cuenta que el sensor no te entrega los datos en decimal, sino que te los entrega en un formato hex de 16Bit
Si adjuntas los archivos fuente o el hex del programa, hasta podriamos ayudarte a depurarlo...
En el código, le falta la inicialización del sensor para que comienze a hacer capturas continuamente, como te comenté antes. La sentencia spi_data_is_in(), solo se usa en modo esclavo, y no en modo maestro, pues es el maestro el que envía la señal de reloj.
Con el tema del formato de los datos, el sensor no los da en formato decimal sino que cuando lees el registro de temperatura te da 13 bits que son los que tenés que usar para pasarlos a grados. En realida el CCS por hardware solo permite realizar una lectura de a 8 bits, por lo tanto leyendo 2 veces y guardando los datos en dos registros de 8 bits, obtenemos 16 bits leidos del sensor. Éste solo da 13bits válidos y los otros 3 bits restantes no forman parte de la temperatura medida
Hola:
No acaba de funcionar bien. Te adjunto el codigo completo por si me ha escapado algo.Código: [Seleccionar]
#include <16f876.h>
#fuses XT,NOWDT
#use fast_io(c)
#use fast_io(b)
#use delay(clock=4000000)
#include "lcd.c"
#define CS PIN_C0
float valorh;
float valorl;
float valorregistroh;
float valorregistrol;
float decimales;
float temperatura;
float enteros;
int TempL;
int TempH;
int16 Temp16bits;
int banderanegativo;
void main(){
set_tris_b(0xFF);
set_tris_c(0b00010000);
setup_spi(spi_master|spi_h_to_l|spi_ss_disabled);
lcd_init();
while(1){
output_low(CS);
valorh=spi_read(0); //lectura byte alto
valorl=spi_read(0);//lectura byte bajo
spi_write(0x00);
spi_write(0xFF);
valorregistroh=spi_read(0);
valorregistrol=spi_read(0);
spi_write(0x00);
spi_write(0x00);
output_high(CS);
TempL=spi_read(0); //leo el byte menos significativo de temperatura
TempH=spi_read(0); //leo el byte mas significativo de temperatura
Temp16Bits=make16(TempL,TempH); //Con esto obtengo el registro de 16 bits con los datos de la temperatura actual
//Como el sensor nos da el valor en complemento a dos para los números negativos:
if (Temp16Bits<0){
banderanegativo=1;//asignamos una bandera para saber si el número es negativo
Temp16Bits=~Temp16Bits+9;}//si es negativo lo complementamos a 2 y le sumamos 8
else{
banderanegativo =0;}
Temp16Bits=Temp16Bits>>3; //descartamos los 3 bits menos significativos
decimales=(float)(Temp16Bits&0b0000000001111)*0.0625;//damos formato a los decimales, segun la resolucion de 0.0625grados/bit(hoja de datos)
enteros=(float)(Temp16Bits>>4); //damos formato a los enteros, solo descartando los decimales
if (banderanegativo){
Temperatura=-1*(enteros+decimales);
}
else{
Temperatura=(enteros+decimales);
}
lcd_gotoxy(1,1);
printf(lcd_putc,"Temp=%3.4f \n",Temperatura);
}
}
Un saludo
Aitor
La idea la captaste, pero tienes alguno problemas en el código, acá va una correción, pero todavía hay un error con los decimales, pero no se si es error el el programa o en la resolución del sensor en el proteus. Por lo pronto vas a tener que estudiar la hoja de datos y ver si entiendes lo que hice con el código y encontrar a ver si estábien o hay algún error.
Hola:
he estado haciendo algunas pruebas y con este codigo me funciona la simulacion en proteus. He cambiado tu codigo en la linea 45 donde ponias +9 por +8 (proteus no daba los valores exactos de temperatura) y tambien he modificado la configuracion inicial en modo continuo. Proteus simula la lectura del sensor sin dicha configuracion.
Un saludo
AitorCódigo: [Seleccionar]
#include <16f876.h>
#fuses XT,NOWDT
#use fast_io(c)
#use fast_io(b)
#use delay(clock=4000000)
#include "mylcd.c"
#define CS PIN_C0
int Templ=0;
int Temph=0;
signed int16 Temp16Bits=0;
float decimales=0;
float enteros=0;
int1 banderanegativo=0;
float Temperatura;
void main(){
set_tris_b(0xFF);
set_tris_c(0b00010000);
setup_spi(spi_master|spi_l_to_h| spi_ss_disabled);
lcd_init();
//configuracion del sensor en modo continuo
//output_low(CS);
//spi_read(0);//leemos byte alto
//spi_read(0);//leemos byte bajo
//spi_write(0x00);
//spi_write(0xFF);
//spi_read(0);//leemos byte alto
//spi_read(0);//leemos byte bajo
//spi_write(0x00);
//spi_write(0x00);
//output_high(CS);
while(1){
lcd_gotoxy(1,1);
output_low(CS);
Temph=spi_read(0);//obtenemos el Temp alto del registro de temperatura
Templ=spi_read(0);//obtenemos el Temp bajo del registro de temperatura
output_high(CS);
Temp16Bits=make16(Temph,Templ);//convertimos a un registro de 16Bits
banderanegativo=0;
if (Temp16Bits<0){
banderanegativo=1;
Temp16Bits=~Temp16Bits+8;
}//si es negativo lo complementamos a 2 y le sumamos 8
Temp16Bits=Temp16Bits>>3;//descartamos los 3 bits menos significativos
decimales=(float)(Temp16Bits&0b0000000000001111)*0.0625;//damos formato a los decimales
enteros=(float)(Temp16Bits>>4); //damos formato a los enteros, solo descartando los decimales
if (banderanegativo){
Temperatura=-1*(enteros+decimales);
}
else{
Temperatura=(enteros+decimales);
}
lcd_gotoxy(1,1);
printf(lcd_putc,"Temp=%3.4f \n",Temperatura);
delay_ms(100);
}
}
Me alegro que te haya funcionado.
Hola muchachos. Hay algo que no me queda del todo muy claro. Verán, este TC77 tiene implementado la interface SPI pero para los datos los hace en un solo pin (SI/O). Mientras que el hardware SPI de mi 18F4550 tiene su SDI y SDO independientes (RB0 y RC7, respectivamente). Asi que, no entiendo muy bien como el pic logra una comunicacion con el sensor habiendo esta limitacion, o es que estoy obiando alguna posibilidad que hay en el hardware spi del pic que permite hacer esto?
Gracias.
Yo vi en algun lado una configuracion de SPI donde con una resistencia (creo que entre SPI SO y SPI SI ), hacian comunicacion bidireccional contra un solo pin.Que interesante MGLSOFT, nunca se me habría ocurrido asi :o