////////////////////////////////modul1.c////////////////////////////////////
// Aquest programa s'encarrega de recollir l'informaciónrmacio enviada per dos//
// sensors de temperatura i pels tach de dos ventiladors, aquesta //
// informaciónrmacio es enviada per I2C a un altre microcontrolador que //
// s'encarrega de mostrarla per un LCD i calcular el nivell de PWM de cada//
// ventilador depenent de la temperatura llegida pels sensors. //
// //
// Els programes dels diferents moduls son exactamens iguals, l'unica //
// cosa que canvia es la direccio de slave. //
// //
// //
////////////////////////////////////////////////////////////////////////////
// #include <lcd.c>
// defineix el protocol de comunicacions I2C en mode slave
typedef enum {NOTHING,CONTROL_READ,ADDRESS_READ, READ_COMAND_READ} I2C_STATE;
I2C_STATE fState;
//determina l'estat de la comunicació I2C
byte address, buffer [0x10];
//array am els valors que l'esclau comprateix am el mestre
// defineix la paraula de configuració del pic
/*Aquesta directiva reserva les posicions de memoria 0x1F00 fins a 0x1FFF
per tal que el programa principal no es gravi damun del registre de carrega*/
////////////////////////////////////////////////////////////////////////////
// Definició de variables //
////////////////////////////////////////////////////////////////////////////
static long int tach1,tach2,cont1,cont2,rpm1=200,rpm2=150;
// definim com a variables glovals de 16 bit
static unsigned int temp1=70, temp2=60, i1=0, i2=0, duty1=0, duty2=0;
////////////////////////////////////////////////////////////////////////////
// Definició de les funcions //
////////////////////////////////////////////////////////////////////////////
void inter_I2C(); // interrupcio I2C
void inter_rb(); // interrupcio per canvi d'estat RB4:RB7
void inter_timer0(); // interrupcio pel desbordament del timer0
void inicial(); // configuracio inicial del PIC
//void temp_int(); // adquirim els valors dels sensors de temperatura
void buffer_i2c(); // donem els valors dels parametres al buffer I2C
void main(); // funció principal
///////////////////////////////////////////////////////////////////////////
// Funció d'interrupció per rebre la senyal del tach dels ventiladors //
///////////////////////////////////////////////////////////////////////////
void inter_rb()
{
short enc1,enc2;
static short ultim_enc1=1;
static short ultim_enc2=1;
enc1=input(pin_b5);
enc2=input(pin_b6);
if(ultim_enc1 && !enc1) tach1++; //si pasa de 1 a 0 sumem puls
if(ultim_enc2 && !enc2) tach2++;
ultim_enc1=enc1;
ultim_enc2=enc2;
}
///////////////////////////////////////////////////////////////////////////
// Funció d'interrupció per desbordament del timer0 //
///////////////////////////////////////////////////////////////////////////
void inter_timer0()
{
static byte timer_0_count=0;
if (timer_0_count<31)timer_0_count++;
else
{
timer_0_count=0;
cont1=tach1;
cont2=tach2;
rpm1=(cont1/4)*60;
rpm2=(cont2/4)*60;
// printf(lcd_putc,"\fr1=%lu r2=%lu",rpm1,rpm2);
tach1=0;
tach2=0;
// temp_int();
}
set_timer0 (8);
}
///////////////////////////////////////////////////////////////////////////
// Funció d'interrupció per activitat en el modul SSP (I2C) //
///////////////////////////////////////////////////////////////////////////
void inter_i2c()
{
byte incoming;/////es donde recibo el byte que me manda
if (i2c_poll() == FALSE) {
if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
i2c_write (buffer[address]);//interupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}
else {
incoming = i2c_read();
if (fState == NOTHING){
fState = CONTROL_READ;
}
else if (fState == CONTROL_READ) {
address = incoming;
fState = ADDRESS_READ;
}
else if (fState == ADDRESS_READ) {
buffer[address] = incoming;
fState = NOTHING;
}
}
}
////////////////////////////////////////////////////////////////////////////
// Funció de configuració inicial del PIC //
////////////////////////////////////////////////////////////////////////////
void inicial()
{
int i=0;
set_tris_a(0x2F); //port_A com a entrades
set_tris_b(0x0F); //RB0:RB3 sortides RB4:RB7 entrades
//set_tris_c(0x00); //port_C com a sortides
setup_adc_ports(AN0_AN1_AN2_AN4_VSS_VREF); //configura CAD RA3=vref
setup_adc(ADC_CLOCK_DIV_32); //Temps de lectura del CAD
setup_timer_2(T2_DIV_BY_1,9,1); //100khz PWM
setup_ccp1(CCP_PWM); //Mode PWM
setup_ccp2(CCP_PWM); //Mode PWM
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256); //interrupció timer cada 2 segons
set_timer0 (8);
enable_interrupts(INT_TIMER0); //activem interrupció timer0
enable_interrupts(INT_RB); //activem interrupció RB
enable_interrupts(INT_SSP); //activem interrupcio I2C
enable_interrupts(GLOBAL); //activem permis d'interrupcions
fState = NOTHING;
address = 0x00; //primera posició del buffer
for(i=0;i<0x10;i++)buffer[i]=0; //inicialitzem array a 0
}
////////////////////////////////////////////////////////////////////////////
// Funció per llegir els sensors de temperatura i les intencitats //
////////////////////////////////////////////////////////////////////////////
void temp_int()
{
disable_interrupts(global); //no es pot interompre la conversió
set_adc_channel(0); //preparem el canal 0
delay_ms(16);
temp1=read_adc(); //llegim temp 1
set_adc_channel(1); //preparem el canal 1
delay_ms(16); //per carregar el c intern del cad /// se le el voltage y sabiendo la R se
temp2=read_adc(); //llegim temp 2 /// calcula la intensidad
set_adc_channel(2);
delay_ms(16);
i1=read_adc(); // llegim intencitat 1
set_adc_channel(4);
delay_ms(16);
i2=read_adc(); // llegim intenciata 2
enable_interrupts(global); //activem interrupcions
}
///////////////////////////////////////////////////////////////////////////
// Dades que el slave comparteix amb el master //
///////////////////////////////////////////////////////////////////////////
void buffer_i2c()
{
buffer[0x00]=temp1; //guardem temp al buffer
buffer[0x01]=temp2;
buffer[0x02]=rpm1; //guardem rpm al buffer
buffer[0x03]=rpm2;
buffer[0x04]=i1; //guardem intencitat al buffer
buffer[0x05]=i2;
duty1=buffer[0x06]; //llegim el duty enviat pel master
duty2=buffer[0x07];
}
void main()
{
// delay_ms(10);
inicial(); //configuració inicial del PIC
// lcd_init(); // NOMES X DEBUG
while(1)
{
buffer_i2c(); //cridem a la funcio
set_pwm1_duty(duty1); //actualitzem pwm1
set_pwm2_duty(duty2); //actualitzem pwm2
}
}
// EL maestro debe multiplicar por 60 los pulsos del tach del ventilador para obtener las rpm
// se ha de tratar la señal que se recive del lm35
// la intensidad se calcula de la siguiente forma: hay una resistencia en paralelo con el ventilador, sabiendo la r,
// leemos el voltage con el CAD y sacamos la intensidad. Lo otro esta probado y funciona bien.