Buenas,
Como puse en un post anterior, tengo problemas a la hora de leer la temperatura del sensor TC74 de la placa de entrenamiento PICDEM. Cuando quiero mostrar la Temperatura actual en el main, me muestra el valor -128. Interpreto que no me lee nada. Me gustaría que me corrigieran el error en el código ya que ando un poco novato en este asunto.
Les dejo el código:
#include "16F877A.h"
#device adc=10
#use delay (clock=4000000)
#use I2C (MASTER,SDA=PIN_C4,SCL=PIN_C3,FORCE_HW)
#fuses XT,NOWDT,NOPROTECT,NOLVP,BROWNOUT,NOLVP,NOCPD,NOWRT
#use fast_io(all)
#byte PORTA=0x05 #byte PORTB=0x06
#byte TRISA=0x85 #byte TRISB=0x86
#bit RA0=PORTA.0 #bit RB0=PORTB.0
#bit RB1=PORTB.1
#bit RB2=PORTB.2
#bit RB3=PORTB.3
#bit RB4=PORTB.4
#bit RB5=PORTB.5
#bit RB6=PORTB.6
#bit RB7=PORTB.7
/*VARIABLES GLOBALES*/
//CONFIGURACION
int1 config_t=0; // Variables para poder llamar a la funcion cuando
int1 config_v=0; // indico que quiero cambiar Vout o Tmáx
int cont_dt=0; // Contadores, para la configuracion del de los distintos
int cont_dv=0; // parametros, que nos permitira saber cuando se termino
// de modificar las decenas y pasar a
// las unidades
//TECLADO
int fil,col; // Determinan la posición en el teclado
int paso; // Almacena el valor de PORTB
char tecla; // Guarda el valor de la tecla pulsada en el teclado
int pulsada; // Indica si se ha pulsado alguna tecla
int pasar=1; // Para manejar las teclas de +
char teclado[4][4]={{'T','V','N','E'}, // Asigno los valores y funciones de cada
{ 1, 2, 3, '+'}, // fila y columna al teclado
{ 4, 5, 6, 'N'},
{ 7, 8, 9, 0}};
//SENSOR
int t_max=60; // Variable para indicar la Tmáx admitida.
int t_act; // Variable donde se guarda la temperatura actual.
//PWM
int16 carga; // valor de carga en el PWM (carga=(Fosc*d)/(Prescaler*Fpwm)) (Vout=Ve por defecto)
float v_in; // Variable para indicar la Vin que tenemos
float v_out=10.0; // Variable para poner la Vout deseada
float save_v_out; // Variable intermedia donde salvamos el valor de v_out
int change_d=0; // Variable para indicar que queremos cambiar el duty
int temp_duty=1; // Variable para el apagado progresivo del PWM si
// se supera la Tmáx
/*LIBRERIAS*/
#include "lcd.c"
#include "funciones.c"
/*CONFIGURACION PREVIA*/
void configuracion(){
//TEMPORIZADOR PARADA TIMER1
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // Reloj intero con preescaler 1
set_timer1(15536); // Para contar 0.05 seg
//TECLADO
PORTB=0; // Define RB<7:4> como entradas y RB<3:0> como
set_tris_b(0b11110000); // salidas
delay_cycles(4); // Espera para estabilizar el valor de PORTB.
port_b_pullups(TRUE); // Habilita resistencias de pull-up.
PORTB=PORTB; // Lee PORTB para preparar interrupciones.
//CONVERSOR AD
setup_adc_ports(AN0); // Pone AN0 como entrada analogica
setup_adc(ADC_CLOCK_INTERNAL); // Frecuencia de conversión interna
set_adc_channel(0); // Selecciona AN0 y lo asigna a la línea RA0
//PWM
save_v_out=v_out;
carga=((v_out-(4.0/1023.0*read_adc()+8.0))/v_out)*200.0; // Para saber la carga inicial
setup_timer_2 (T2_DIV_BY_1,49.5,1); // Señal PWM de 20kHz
setup_ccp2(CCP_PWM); // Genera PWM con el CCP2.
set_pwm2_duty(carga);
//LCD
lcd_init(); // Inicializar pantalla LCD
//I2C
output_float (PIN_C3); // Dejamos flotantes los terminales
output_float (PIN_C4); // asociados a la comunicación I2C.
//GENERAL
enable_interrupts(INT_RB); // Habilita interrupciones del PORTB
enable_interrupts(GLOBAL); // Habilita interrupciones
//CONFIGURACION DE VALORES
ponervoltaje();
tecla=100;
ponertmax();
enable_interrupts(int_timer1); // Habilita la interrupcion del T1
set_tris_c(0b11111011); // Asegura que RC3 es salida
}
/*PROGRAMA */
void main(){
configuracion();
while(TRUE){
v_in=4.0/1023.0*read_adc()+8;
tecladofunc();
// MUESTRA LA TEMP ACTUAL Y LA TENSION DE ENTRADA O SALIDA //
if(pasar==1){
lcd_gotoxy(1,1);
printf(lcd_putc,"Tact=%d%cC ",t_act,0xDF);
lcd_gotoxy(1,2);
printf(lcd_putc,"Vin=%1.1fV ",v_in);
}
if(pasar==2){
lcd_gotoxy(1,1);
printf(lcd_putc,"Tact=%d%cC ",t_act,0xDF);
lcd_gotoxy(1,2);
printf(lcd_putc,"Vout=%1.1fV ",v_out);
}
//COMPRUEBA SI EL USUARIO HA DECIDIDO CAMBIAR ALGUNA VARIABLE//
if(config_t==1)
ponertmax();
if(config_v==1)
ponervoltaje();
// COMPRUEBA SI HA DE APAGARSE EL CONVERTIDOR O HAY QUE CAMBIAR EL DUTY //
if((change_d==1)||(t_act>=t_max)){
// Si estoy en el primer caso quiere decir que la temperatura actual ha superado
// a la temperatura máxima permitida, tendrá que apagarse el convertidor y por
// lo tanto la tensión de salida y la de entrada tendrán que ser iguales,
// lo que hace que el valor del duty sea 0% y entonces su carga tambien lo sea.
// Los cambios de la tension de salida solo seran progresivos en caso del apagado
// del convertidor. Para cambios de una tension de salida a otra posteriormente
// definida (else) el cambio será brusco.
if(t_act>=t_max){
carga=((v_out-(4.0/1023.0*read_adc()+8.0))/v_out)*200.0;
change_duty(carga,0); // Primero,segundo
}
else{
change_d=0;
carga=((v_out-(4.0/1023.0*read_adc()+8.0))/v_out)*200.0;
}
}
}
}
// FUNCION LEER LA TEMPERATURA //
void lee_t_act(){
i2c_start(); // Genera secuencia de START.
i2c_write(0b10011010); // Envía byte de control para escribir.
i2c_write(0x00); // Envía la dirección del sensor;
i2c_start(); // Genera otra secuencia de STAR
i2c_write(0b10011011); // Envía byte de control para leer.
t_act=i2c_read(0); // Lee el dato.
i2c_stop(); // Genera una secuencia de STOP.
}
// FUNCION CONFIGURAR TEMPERATURA MAXIMA //
void ponertmax(){
pulsada=0;
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("Introduce Tmax");
do{
if(pulsada==1&&cont_dt==0&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dt++;
t_max=tecla*10;
delay_ms(200);
}
if(pulsada==1&&cont_dt==1&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dt++;
t_max=t_max+tecla;
delay_ms(200);
}
lcd_gotoxy(1,2);
printf(lcd_putc,"[%u]%cC",t_max,0xDF);
}while(cont_dt<=2&&tecla!='E');
delay_ms(300);
cont_dt=0;
lcd_putc('\f');
config_t=0;
}
// FUNCION CONFIGURAR TENSION SALIDA //
void ponervoltaje(){
change_d=0;
pulsada=0;
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("Introduce Vout");
do{
if(pulsada==1&&cont_dv==0&&tecla>=1&&tecla<=9){
pulsada=0;
cont_dv++;
v_out=tecla*10;
delay_ms(200);
}
if(pulsada==1&&cont_dv==1&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dv++;
v_out=v_out+tecla;
delay_ms(200);
}
if(pulsada==1&&cont_dv==2&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dv++;
v_out=v_out+tecla/10.0;
delay_ms(200);
}
lcd_gotoxy(1,2);
printf(lcd_putc,"[%1.1f]V",v_out);
}while(cont_dv<=3&&tecla!='E');
delay_ms(300);
cont_dv=0;
change_d=1; // Al cambiar el voltaje deseado indica que tengo que cambiar el duty
save_v_out=v_out;
lcd_putc('\f');
config_v=0;
}
// FUNCION PARA FUNCIONES DEL TECLADO //
void tecladofunc(){
switch(tecla){
case 'T':
config_t=1; // Indico que quiero configurar la Tmax
break;
case 'V':
config_v=1; // Indico que quiero configurar la V_out
break;
case '+':
pasar++;
tecla=100; // Aumento "pasar" para que cambie la variable a mostrar por
if(pasar==3) // pantalla y al llegar al valor 2 la vuelvo a poner a 0
pasar=1; // para que el menu sea "rotacional"
break;
}
pulsada=0; // Recupera el marcador de “tecla no pulsada”.
}
// INTERRUPCION PARADA (SUPERADA TMAX )//
#INT_TIMER1
void parada(){
temp_duty=1;
}
// INTERRUPCION FUNCIONES DEL TECLADO //
#INT_RB
void pulsado(){
/* Se identifica la columna en que está la tecla pulsada determinando cuál
de los cuatro bits más altos de PORTB está a 0. Si no hay ninguno, es que
se ha entrado en la interrupción al soltar la tecla, por lo que se sale
inmediatamente */
if(!RB4)
col=0;
else
if(!RB5)
col=1;
else
if(!RB6)
col=2;
else
if(!RB7)
col=3;
else return;
pulsada=1; // Indica que se ha pulsado una tecla.
paso=PORTB; // Guarda el valor de PORTB.
set_tris_b(0b00001111); // Cambia entradas por salidas.
PORTB=paso; // Saca el valor almacenado a PORTB.
delay_cycles(4); // Espera para estabilizar señal.
/* Se identifica la fila en que está la tecla pulsada determinando cuál de
los cuatro bits más bajos de PORTB está a 0. Si no hay ninguno,es que se
ha producido algún error y se indica que no hay ninguna tecla pulsada */
if(!RB0)
fil=0;
else
if(!RB1)
fil=1;
else
if(!RB2)
fil=2;
else
if(!RB3)
fil=3;
else
pulsada=0;
tecla=teclado[fil][col]; // Se guarda el valor de la tecla pulsada.
set_tris_b(0b11110000); // Se deja todo como estaba recuperando la
PORTB=0; // definición inicial de E/S en PORTB y
delay_cycles(4); // poniendo todas las salidas a 0 y leyendo
PORTB=PORTB; // PORTB para preparar las interrupciones.
}
// FUNCION PARA DECREMENTAR LA CARGA DEL PWM EN CASO DE APAGADO //
void change_duty(int16 primero,int16 segundo){
// Procedemos a extinguir la carga del PWM hasta llegar 0, en intervalos de 2,
// 50ms entre cada decremento.
if((primero-segundo)>=0&&temp_duty==1){
carga=carga-2;
if(carga>60000){
carga=0;
change_d=0;
}
set_pwm2_duty(carga);
temp_duty=0;
}
}