#include <16f628.h> // Descriptores de dispositivo.
#fuses NOWDT, HS, NOMCLR, BROWNOUT, PROTECT // No Whatdog. , oscilador de cuarzo, no Master clear, Reset Brownout, Codigo protegido.
#use delay(clock=20000000) // Función Delay tendrá en cuentra la velocidad del cristal elegido.
#use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8) // El puerto RS232 operará a 9600 bps, 8N1.
#bit led=0x006.0 // Macro de instancia al puerto B0 donde se ha conectado un diodo led indicador.
#byte CMCON=getenv("SFR:CMCON") // Macro de instancia al registro CMCON para configrar el modo de trabajo de los comparadores analógicos.
#bit TMR1IF=0x00c.0 // Macro de instancia para bandera interrupcion desbordamiento del timer 1
#bit TMR0IF=0x00b.2 // Macro de instancia para bandera interrupcion desbordamiento del timer 0
void main() {
led = 0; // Led de barrido/control apagado inicialmente.
set_tris_a(0b11110111); // Configuración de entradas y salidas.
set_tris_b(0b11111010);
CMCON = 0xc6; // Comparadores en modo referencia común (+COMUN "PIN A2"), es decir, que el pin A2 está conectado a las entradas + de ambos comparadores.
// Las salidas son independientes y los (-) son independientes. No se invierten las salidas.
// Usaremos solo la salida del comparador 1 (Pin A3).
// La entrada (-) del comparador 1 (Pin A0) será donde se conecta el circuito RC
setup_timer_0(T0_EXT_L_TO_H | T0_DIV_1); // El timer0 se incrementa de forma externa, en flanco de subida, sin prescalador. La salida del comparador será quien incremente este timer.
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // El timer1 es conectado al oscilador interno sin prescalador. Será usado como base de tiempo para la medición.
led = 1; // Genero un parpadeo de medio segundo para indicar que la cpu está en marcha.
delay_ms(500); // y así también hago una espera de estabilidad de clock, de alimentación, etc.
led = 0; // Vuelvo a apagar el led.
while(1) { // Bucle de función.
int16 desbtmr0 = 0; // Contador de desbordamientos del timer0
int8 desbtmr1 = 0; // Contador de desbordamientos del timer1
set_timer0(0); // Timer0 puesto a cero.
TMR0IF = 0; // Banderas de desbordamiento inicialmente a cero.
TMR1IF = 0;
while(desbtmr1 < 76) { // Generamos bucle de aproximadamente 1 segundo. (Entrada a timer1 = 5000000, deborda cada (65535 + 1), 5000000/65536 = 76,29 desbordamientos necesarios para 1 segundo)
if (TMR0IF) { // ¿Ha desbordado el timer0?
desbtmr0++; // Incremento su contador de desbordamientos.
TMR0IF = 0; // Bajo la bandera de desbordamiento.
}
if (TMR1IF) { // Ha desbordado el timer1?
desbtmr1++; // Incremento su contador de desbordamientos.
TMR1IF = 0; // Bajo la bandera de desbordamiento.
}
}
// ¿Se han cumplido los 76 debordamientos del timer1?.
int16 resultado = (((int32)desbtmr0 * 256) + get_timer0()) / 1000; // Genero variable para totalizar el numero de pulsos totales contados por el timer0.
// Para ello, como el timer0 desborda cada (255 + 1) pulsos, multiplico 256 * el numero de veces que ha desbordado.
// A ello le sumo el resto del ultimo valor que contiene el timer y obtenemos el numero de pulsos totales.
// Divido finalmente entre 1000 para eliminar los digitos que no necesito. Con 4 digitos es suficiente, me quedo
// los 4 digitos mas estables.
led = 1; // Genero un parpadeo en cada transmisión que se efectúa.
printf("LEV"); // Envio el resultado enmascarado en una trama de control. Empieza con 3 bytes que contienen la palabra clave (LEV), putc(make8
(resultado
,1)); // seguido de dos bytes que contienen el valor del nivel medido codificado en un entero simple en 16 bits, MSB primero, putc(make8
(resultado
,0)); // LSB después. putc('L' + 'E' + 'V' + make8
(resultado
,1) + make8
(resultado
,0)); // y cierro la trama con un checksum convencional. led = 0; // Fin del parpadeo del led.
// El receptor recibirá una trama cada 1 segundo. Para parsear la trama deberá leerla entera, identifica la palabra LEV, que servirá como control para saber que los dos siguientes
// bytes contienen el valor del nivel medido. Por ultimo comprueba la suma de verificación checksum y si es válido procesa el valor.
} // Fin de bucle de función.
} // Fin de programa.