/************************************************************************
Prototipo de contador de objetos por medio óptico, con función de
seguridad (guardado de datos en EEPROM)
Iván
************************************************************************/
#include <16f876a.h> // Selecciona el PIC
#fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT // Opciones de configuración, cristal, sin perro guardian, sin proteccion de codigo
#use delay(clock=4000000) // Velocidad del Cristal : 4 Mhz
#use standard_io(B) // PORTB en estandar IO digital
//#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3,PIN_B4,PIN_B5,PIN_B6,PIN_B7)
#use standard_io(A)
//#use standard_io(C) //Da problemas con la salida, estados indeterminados (1V)
#use fast_io(C)
#include <lcd.c>
#use fast_io(B)
#DEFINE ATRANCO 5 //segundos para determinar que hay un atranco en la barrera optica
char const RTCCxS=15; // Número de RTCC's para 1 segundo con 4 Mhz / 1:256.
// VARIABLES GLOBALES
int nRTCC=0x00; // Contador de interrupciones RTCC completas
int segundo=0x0; // Segundos del Reloj
//int l_digit, h_digit;
int DirCen = 0x00; // Dirección de las centenas en la EEPROM (0)
int DirDec = 0x01; // Dirección de las decenas en la EEPROM (1)
int DirUds = 0x02; // Dirección de las unidades en la EEPROM (2)
// Contador
int Cen = 0;
int Dec = 0;
int Uds = 0;
int alarma = 0; //flag de alarma
int contando = 0; // flag contando
//Funciones
void Cuentauno(void);
void cargaEEPROM(void);
void actualiza(void);
void clear(void);
//Interrupciones
#int_RTCC // Interrupción por desbordamiento
void RTCC_isr() { // del TIMER0 RTCC
if(++nRTCC==RTCCxS){
nRTCC=0x00;
segundo++;
}
}
void main(void) {
setup_spi(FALSE); //añadido
setup_comparator(NC_NC_NC_NC); //añadido
setup_vref(FALSE); //añadido
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); // TIMER0: Clock Interno y Preescaler 1:256
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
SET_TRIS_A(0b11110111);
SET_TRIS_B(0b00000000);
SET_TRIS_C(0b00000000);
output_bit(PIN_A3, 0);
lcd_init();
delay_ms(1000);
printf(lcd_putc,"\f Ivan\nContador optico");
delay_ms(1000);
enable_interrupts(INT_RTCC);// Habilito Interrupción RTCC
enable_interrupts(global); // Habilito Interrupciones
cargaEEPROM(); //cargamos los datos de la EEPROM en la RAM (función de seguridad)
actualiza();
delay_ms(3000);
do{ // Bucle infinito
if (alarma == 0) {
if (segundo >= ATRANCO && alarma == 0) { //Si llegamos al limite para considerar un atranco, activamos alarma
alarma = 1;
printf(lcd_putc, "\f ALARMA\n Retire atranco");
}
if (input(PIN_A2) == 0) { clear(); }
if (input(PIN_A0) == 0 && contando == 0) { // Si interrumpimos el haz y no está contando, sumamos uno
Cuentauno();
contando = 1;
actualiza();
delay_ms(150);
}
if (input(PIN_A0) == 1) {
segundo = 0; // Si no se interrumpe el haz, reseteamos el contador de alarma
contando = 0;
//actualiza();
}
}
if (alarma == 1) {
printf(lcd_putc, "\f ALARMA\n Retire atranco");
delay_ms(450);
if (input(PIN_A1) == 0) {
alarma = 0;
output_bit(PIN_A3, 0);
actualiza();
}
else { output_bit(PIN_A3, 1); }
}
}While(TRUE);
}
void cargaEEPROM (void) { // Funcion que carga la EEPROM en memoria al iniciarse el micro
if (read_eeprom(DirCen)==0xFF) { write_eeprom(DirCen, 0); } // Si tienen el valor máximo con el que vienen cuando no
if (read_eeprom(DirDec)==0xFF) { write_eeprom(DirDec, 0); } // tienen datos en la EEPROM, lo que indica que no hay datos
if (read_eeprom(DirUds)==0xFF) { write_eeprom(DirUds, 0); } // grabados (situacion inicial), los reiniciamos a 0
Uds = read_eeprom(DirUds);
Dec = read_eeprom(DirDec);
Cen=read_eeprom(DirCen);
}
void Cuentauno (void) { // Funcion que suma uno a la cuenta y lo guarda en EEPROM
if (Uds == 9) {
Uds = 0;
Dec++;
if (Dec > 9) {
Dec = 0;
Cen++;
}
}
else {
Uds++;
}
write_eeprom(DirCen, Cen); // Guardado de las variables en la EEPROM
write_eeprom(DirDec, Dec); // Funcion de seguridad por si se queda sin alimentación
write_eeprom(DirUds, Uds);
}
void actualiza(void) {
printf(lcd_putc,"\fContando...\n %i%i%i", Cen Dec Uds);
}
void clear(void) {
write_eeprom(DirCen, 0); // Guardamos 0 en las centenas
write_eeprom(DirDec, 0); // Guardamos 0 en las decenas
write_eeprom(DirUds, 0); // Guardamos 0 en las unidades
Cen = 0; //Vaciamos variables
Dec = 0;
Uds = 0;
actualiza(); // Refrescamos los displays
}