Aquí pongo mi primer programa en C para pic. Próximamente subiré los esquemáticos y las PCB.
Un saludo.
Si alguien ve que se puede mejorar algo,o hay algún fallo, bienvenida sea la critica.
Jose Antonio
//**************************************************
//* *
//* Control de temperatura para acuario tropical *
//* *
//* mediante refrigeración con agua a 2ºC *
//* *
//* Por Jose Antonio *
//* *
//* freshdesing (17/07/07) *
//* *
//**************************************************
// DESCRIPCIÓN:
// Consiste en un sistema para regular la temperatura de un acuario de agua
// tropical, queremos que en verano no sobrepaso los 28ºC. Mediante el PIC
// controlams que la temperatura este dentro de este rango, y cuando lo
// sobrepasa activamos una bomba de recirculación que hace circular el agua del
// acuario sobre una nevera con agua con hielo (aprox 2ºC). El sistema se
// cuando se llega a los 27ºC.
// También dispone de un pulsador, mediante el cual podemos ver la
// temperatura de la habitación.
// Mediante otro pulsador, podemos parar la bomba del filtro para que la
// comida no caiga tan rápido al fondo.
// FUNCIONES:
// captura: Captura el dato del adc del pic, según el canal que este
// seleccionado
// representar: representamos las decenas,unidades y decimas en 3 displays de
// 7 segmentos.
// control_temp: Cada cierto tiempo vemos si hemos pasado los 28º para activar
// la bomba de recirculación. Asi si hemos llegado a los 27º para
// desactivarla.
// muestreo5seg: intervalo de 5 segundos para actualizar el valor adc y para
// ver el valor de la temperatura.
// control_timer1: Interrupción el timer1, en el que controlamos tiempos.
#include "16F876.h"
#device adc=10 //ADC DE 10 BITS
#fuses NOLVP,XT,NOWDT,NOPROTECT,PUT
#use delay (clock=4000000)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#byte port_a = 0x05
#byte port_b = 0x06
#byte port_c = 0x07
//#define ch_acuario 0;
//#define ch_ambiente ;
int decenas,unidades,decimas,contador=0,canal=0,cont_ch=0,flag_ch=0,flag_filtro=0; //variables globales
float acuario=0,ambiente=0;
int16 cont_filtro=0;
setup_adc_ports (0x84); //RA3,RA1,RA0 Analog
setup_adc(ADC_CLOCK_INTERNAL);
//Función que captura el valor del ADC y lo almacena en temperatura, y a su vez
//en unidades y decenas
void captura(void)
{
double lectura_adc;
if(canal==0){
set_adc_channel(0); //seleccionamos canal AN0
delay_ms(5);
lectura_adc = read_adc(); //leemos el canal correspondiente
acuario=lectura_adc*50.0/1023.0;
decenas=(int) acuario/10;
unidades=(int) acuario-(decenas*10);
decimas=(int) (acuario*10-(decenas*100+unidades*10));
}
if(canal==1){
set_adc_channel(1); //seleccionamos canal AN1
delay_ms(5);
lectura_adc = read_adc(); //leemos el canal correspondiente
ambiente=lectura_adc*50.0/1023.0;
decenas=(int) ambiente/10;
unidades=(int) ambiente-(decenas*10);
decimas=(int) (ambiente*10-(decenas*100+unidades*10));
}
}
//Función que refresca los displays y lo saca en BCD
void representar(void)
{
output_bit(PIN_C0,Bit_test(decimas,0));
output_bit(PIN_C1,Bit_test(decimas,1));
output_bit(PIN_C2,Bit_test(decimas,2));
output_bit(PIN_C3,Bit_test(decimas,3));
output_bit(PIN_C4,0);//activamos el led correspondiente de decenas
delay_ms(7);
output_bit(PIN_C4,1);//desactivamos el led correspondiente de unidades
output_bit(PIN_C0,Bit_test(unidades,0));
output_bit(PIN_C1,Bit_test(unidades,1));
output_bit(PIN_C2,Bit_test(unidades,2));
output_bit(PIN_C3,Bit_test(unidades,3));
output_bit(PIN_C5,0);//activamos el led correspondiente de decenas
delay_ms(7);
output_bit(PIN_C5,1);//desactivamos el led correspondiente de unidades
output_bit(PIN_C0,Bit_test(decenas,0));
output_bit(PIN_C1,Bit_test(decenas,1));
output_bit(PIN_C2,Bit_test(decenas,2));
output_bit(PIN_C3,Bit_test(decenas,3));
output_bit(PIN_C6,0);//activamos el led correspondiente de decenas
delay_ms(7);
output_bit(PIN_C6,1);//desactivamos el led correspondiente de decenas
}
//Subrutina de control de temperatura
void control_temp(void)
{
if(acuario>=28){
output_bit(PIN_B2,1);//si superamos 28º activamos al bomba
} //Activa en alta. Rele NA.
if(acuario<=27){
output_bit(PIN_B2,0);//si bajamos de 27º desactivamos al bomba
} //Activa en alta. Rele NA.
}
//Subrutina de muestreo cada 5 segundos
void muestreo5seg(void)
{//************poner cada 5 seungdos o cada 30 segundos
captura(); //capturamos adc
if(canal==0){control_temp();}//vemos como esta la temperatura
contador=0;
}
//Subrutina de interrución del TMR1
#INT_TIMER1
control_timer1()
{
output_bit(pin_b1,!input(pin_b1)); //Parpadeo de Led Status
contador++;
if((cont_filtro==10) && (flag_filtro==1))
{
output_bit(pin_b3,0);
flag_filtro=0;
}
else
{
cont_filtro++;
}
if((cont_ch==10) && (flag_ch==1))
{
canal=0;//ponemso el canal0
flag_ch=0;
}
else
{
cont_ch++;
}
}
void main(void)
{
disable_interrupts(GLOBAL);
set_tris_a(0xFF); // RA0,RA1 y RA3 como entradas analogicas
// RA0--> TEMPERATURA ACUARIO
// RA1--> TEMPERATURA AMBIENTE
port_b_pullups(false); // Resistencias de polarización del puerto B
set_tris_b(0xF1); // RB7:4, RB0 ENTRADAS, RB3:1 SALIDAS
// RB7--> SELECCIONAR Tª ACUARIO/Tª AMBIENTE
// RB6--> PARA FILTRO DURANTE 5 MINUTOS
// Activo en alta y NC
// RB5-->
// RB2--> SALIDA BOMBA
// RB1--> STATUS
set_tris_c(0x00); // Puerto C entero como salida para display
// RC0:3--> A0:A3 salida BCD para displays
// RC4--> Control display Unidades
// RC5--> Control display Decenas
setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
//enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
output_bit(PIN_C4,1);//desactivamos led decimas
output_bit(PIN_C5,1);//desactivamos led unidades
output_bit(PIN_C6,1);//desactivamos led decenas
contador=0;
output_bit(PIN_B2,0);//Bomba apagada
output_bit(PIN_B3,0);//Bomba apagada
while(1) {
if(!input(pin_b7))
{
canal=1;
cont_ch=0;
flag_ch=1;
}
if(!input(pin_b6))
{
output_bit(pin_b3,1);//paramos el filtro durante 10 minutos
flag_filtro=1;
cont_filtro=0;
}
//Capturamos los datos en la interrupción del timer1
representar();
if(contador==5){muestreo5seg();}
} // fin while
}