Pues resulta que he acabado la parte teórica del ciclo formativo de grado superior: "Desarrollo de productos electrónicos". Ahora estoy con las FCTs. Y para una de las asignaturas nos plantearon un proyecto para el fin de curso:
Se trata de un programador de riego: Poder especificar a que hora se debe empezar a regar y a qué hora debe acabar (ajustable con precisión de minutos), en cada uno de los 7 dias de la semana.
Empleando los siguientes componentes:

"Display LCD 2x16 carácteres"

"Microcontrolador PIC 16F876"
Se debe programar en C

"Reloj de tiempo real i2c DS1307"
Mas los pulsadores/interruptores que consideráramos necesarios para su control.
Se debía diseñar la interfaz de usuario. Y puntuaba en consideración la facilidad de uso y el minimo coste en componentes (pulsadores e interruptores).
Resumen de funcionalidades de mi versión final:
- Configurable de Lunes a Domingo una hora de inicio y de fin (con precisión de minutos).
- Software controlable desde 2 botones (Up & Right) hasta 4 (Up, Right, Down, Left).
- Interfaz intuitiva.
- Configuración guardada en memoria EEPROM.
- Testeo de hardware / memoria (con comprobación contra corrupción de configuración) al inicio.
- Ajuste del reloj.
- Información del riego de hoy en la pantalla de espera.
entre otras...
Lo publicaré en otro momento que ahora se me ha hecho tarde. Será una versión digital en formato para el programa "Proteus ISIS". Sólo os digo que el programa está escrito en C y son 1456 líneas de código.
A ver si con esto consigo inspirar a varios de por aqui
![brindis [beer]](/images/smilies/nuevos2/brindando.gif)
y así hablamos un poco mas de electrónica.
EDIT:
De momento os dejo con el archivo de proteus y el archivo *.hex del programa para que podais simularlo.
Mirror:
http://www.megaupload.com/?d=H0RPOK9SEDIT2:
Os pongo un resumen del funcionamiento del programa:
Uso de la interfaz:
Manteniendo pulsado cualquier botón, se envian sucesivas pulsaciones automáticamente.
--------------------------------------------------------------------------------------
PANTALLA DE INFORMACIÓN:
+----------------+
|12:33 20/02/2009| - Hora y fecha actual.
|prox.riego 12:33| - Información sobre el riego de hoy.
+----------------+
Acciones:
- Pulsando los botones de la Derecha o el de la Izquierda se entra en la pantalla de Confirguración.
- Pulsando el botón de Arriba se entra en la pantalla de ajuste del reloj.
--------------------------------------------------------------------------------------
PANTALLA DE CONFIGURACION:
+----------------+
|LUN 12:50 a15:30| - Dia de la semana, hora de inicio de riego y hora de fin de riego.
| ^ | - Cursor
+----------------+
Acciones:
- Pulsando los botones de la Derecha o el de la Izquierda se mueve el cursor. Si se sale por la derecha o la izquierda se vuelve a la pantalla de Información.
- Pulsando el botón de Arriba se incrementa el valor que está encima del cursor.
- Pulsando el botón de Abajo se decrementa el valor que está encima del cursor.
- Si no se pulsa ningun botón durante un tiempo, se vuelve a la pantalla de Información.
--------------------------------------------------------------------------------------
PANTALLA DE AJUSTE DEL RELOJ:
+----------------+
|L 11/04/09 12:57| - Dia de la semana, Dia del mes, Mes, Año, Hora, Minuto.
|^ | - Cursor
+----------------+
Acciones:
- Pulsando los botones de la Derecha o el de la Izquierda se mueve el cursor. Si se sale por la derecha o la izquierda se vuelve a la pantalla de Información.
- Pulsando el botón de Arriba se incrementa el valor que está encima del cursor.
- Pulsando el botón de Abajo se decrementa el valor que está encima del cursor.
- Si no se pulsa ningun botón durante un tiempo, se vuelve a la pantalla de Información.
- Cada vez que se modifica un valor, los segundos se ponen a 0.
EDIT3:
Os dejo con el código fuente, hecho y compilado con el programa CCS C (demo 30 dias:
http://www.ccsinfo.com/ccsfreedemo.php)
Mirror:
http://www.megaupload.com/?d=KF5GHKKD (contraseña para el enlace: "demonh3x", contraseña para el archivo *.rar: "demonh3x")
//OPCIONES MODIFICABLES POR EL USUARIO/////////////////////////////////////////
#define KEY_INPUT_DELAY -40 //AJUSTE DEL RETASO DE REPETICION TECLAS
#define KEY_REPEAT_TIME 15 //AJUSTE DE VELOCIDAD DE REPETICION
#define INACTIVITY_CICLES 1000 //NUMERO DE COMPROBACIONES DE ENTRADAS EN VALOR DE REPOSO
//PARA DETERMINAR QUE HA HABIDO INACTIVIDAD
#define EXTRA_DELAY 0 //AJUSTE DE RETRASO EN LA COMUNICAION CON EL LCD (us)
#define CLOCK_POLLING_DIV 10 //AJUSTE DEL MULTIPLICADOR DE TIEMPO ENTRE MUESTREOS DEL RELOJ
///////////////////////////////////////////////////////////////////////////////
#include <16F876.h>
#use delay(clock=4000000)
#use i2c(Master,Slow,sda=PIN_A4,scl=PIN_A5)
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage programing, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use standard_io(a)
#use fast_io(b)
#use fast_io(c)
//CONEXIONES DEL LCD AL PIC////////////////////////////////////////////////////
// LCD PIC
#define RS PIN_C0
#define E PIN_C1
#define DB4 PIN_B0
#define DB5 PIN_B1
#define DB6 PIN_B2
#define DB7 PIN_B3
//CONEXIONES DE LOS PULSADORES/////////////////////////////////////////////////
// PULS PIC
#define PULS_UP PIN_B4
#define PULS_DOWN PIN_B6
#define PULS_RIGHT PIN_B5
#define PULS_LEFT PIN_B7
//#define PULS_OK PIN_??
//CONEXIONES DEL RIEGO/////////////////////////////////////////////////////////
#define PIN_RIEGO PIN_C2
//CONSTANTES GENERALES/////////////////////////////////////////////////////////
//POSICIONES LCD LINEA COL
#define LCD_POS_0_0 0x00
#define LCD_POS_0_1 0x01
#define LCD_POS_0_2 0x02
#define LCD_POS_0_3 0x03
#define LCD_POS_0_4 0x04
#define LCD_POS_0_5 0x05
#define LCD_POS_0_6 0x06
#define LCD_POS_0_7 0x07
#define LCD_POS_0_8 0x08
#define LCD_POS_0_9 0x09
#define LCD_POS_0_10 0x0A
#define LCD_POS_0_11 0x0B
#define LCD_POS_0_12 0x0C
#define LCD_POS_0_13 0x0D
#define LCD_POS_0_14 0x0E
#define LCD_POS_0_15 0x0F
/*
#define LCD_POS_0_16 0x10
#define LCD_POS_0_17 0x11
#define LCD_POS_0_18 0x12
#define LCD_POS_0_19 0x13
*/
#define LCD_POS_1_0 0x40
#define LCD_POS_1_1 0x41
#define LCD_POS_1_2 0x42
#define LCD_POS_1_3 0x43
#define LCD_POS_1_4 0x44
#define LCD_POS_1_5 0x45
#define LCD_POS_1_6 0x46
#define LCD_POS_1_7 0x47
#define LCD_POS_1_8 0x48
#define LCD_POS_1_9 0x49
#define LCD_POS_1_10 0x4A
#define LCD_POS_1_11 0x4B
#define LCD_POS_1_12 0x4C
#define LCD_POS_1_13 0x4D
#define LCD_POS_1_14 0x4E
#define LCD_POS_1_15 0x4F
/*
#define LCD_POS_1_16 0X50
#define LCD_POS_1_17 0x51
#define LCD_POS_1_18 0x52
#define LCD_POS_1_19 0x53
*/
#define LIMIT_HORAS_INC 0x24
#define LIMIT_MINS_INC 0x60
#define LIMIT_HORAS_DEC 0x23
#define LIMIT_MINS_DEC 0x59
//PROTOTIPOS///////////////////////////////////////////////////////////////////
void leer_reloj();
void actualiza_riego();
void scan_io();
void actualizar_interfaz();
void actualizar_pantalla();
void actualizar_cursor_pantalla();
short comp_tiempos(int, int, int, int);
short comprobar_datos_config();
void pulse_out(int);
short test_reloj();
void inicializa_reloj();
void ajusta_reloj();
void inicializa_LCD();
void transmite_caracter(char);
void transmite_comando(int);
//void lcd_settings(short, short, short, short, short, short, short, short);
void lcd_clear_display();
void lcd_return_home();
void lcd_ac_set(int);
void lcd_print_nom_dia_sem(int);
void lcd_print_2num_bcd(int);
void lcd_print_1num_bcd(int, short);
short inc_2bcd(int*, int, short);
short dec_2bcd(int*, int, short);
short cargar_eeprom();
void guardar_eeprom();
//VARIABLES GLOBALES///////////////////////////////////////////////////////////
int temp;
signed int cont_lectura_reloj = 0;
unsigned int32 cont_inactividad = 0;
//VARIABLES PARA LA INTERFAZ
int pantalla_actual = 0; //indice del menu en el que se encuentra el programa
int config_dia_actual = 1; //indice del dia en el que se encuentra en la config
int config_cursor_actual = 0; //indice de la posicion del cursor en la config
//CONFIGURACION DE LOS RIEGOS
int config_hora_inicio[7];
int config_minuto_inicio[7];
int config_hora_fin[7];
int config_minuto_fin[7];
//VALORES LEIDOS DEL RELOJ
int dia_sem = 1; //0 = DOM, 1 = LUN, ... , 6 = SAB
int dia = 1; //numero de dia del mes en BCD
int mes = 1; //numero del mes en BCD
int anyo = 0x09; //numero del año en BCD
int hora = 0; //numero de la hora del dia (formato 24h) en BCD
int min = 0; //numero del minuto en BCD
//REGISTROS DE LAS ENTRADAS
short puls_up_act;
short puls_up_ant;
short puls_up_fs;
//Contador de ciclos de mantenido para enviar repeticiones de pulsacion
signed int puls_up_cont_mant = KEY_INPUT_DELAY;
short puls_down_act;
short puls_down_ant;
short puls_down_fs;
//Contador de ciclos de mantenido para enviar repeticiones de pulsacion
signed int puls_down_cont_mant = KEY_INPUT_DELAY;
short puls_right_act;
short puls_right_ant;
short puls_right_fs;
//Contador de ciclos de mantenido para enviar repeticiones de pulsacion
signed int puls_right_cont_mant = KEY_INPUT_DELAY;
short puls_left_act;
short puls_left_ant;
short puls_left_fs;
//Contador de ciclos de mantenido para enviar repeticiones de pulsacion
signed int puls_left_cont_mant = KEY_INPUT_DELAY;
//short puls_ok_act;
//short puls_ok_ant;
//short puls_ok_fs;
//Contador de ciclos de mantenido para enviar repeticiones de pulsacion
//signed int puls_ok_cont_mant = KEY_INPUT_DELAY;
///////////////////////////////////////////////////////////////////////////////
void main()
{
setup_adc_ports(NO_ANALOGS);
set_tris_b(0b11110000);
port_b_pullups(TRUE);
set_tris_c(0x00);
output_low(RS); //RS=0
output_low(E); //E=0
//inicializar variables de las entradas
puls_up_act = puls_up_ant = !input(PULS_UP);
puls_down_act = puls_down_ant = !input(PULS_DOWN);
puls_right_act = puls_right_ant = !input(PULS_RIGHT);
puls_left_act = puls_left_ant = !input(PULS_LEFT);
//puls_ok_act = puls_ok_ant = !input(PULS_OK);
//inicializar hardware
inicializa_LCD();
//"Init Clock"
transmite_caracter('I');transmite_caracter('n');transmite_caracter('i');
transmite_caracter('t');transmite_caracter(' ');transmite_caracter('C');
transmite_caracter('l');transmite_caracter('o');transmite_caracter('c');
transmite_caracter('k');
//lcd_clear_display();
//"- Test "
lcd_ac_set(LCD_POS_1_0);
transmite_caracter('-');transmite_caracter(' ');transmite_caracter('T');
transmite_caracter('e');transmite_caracter('s');transmite_caracter('t');
transmite_caracter(' ');
while(TRUE)
{
delay_ms(100);
lcd_ac_set(LCD_POS_1_7);
if (test_reloj()){ //Si funciona bien
//"OK"
transmite_caracter('O');transmite_caracter('K');transmite_caracter(' ');
transmite_caracter(' ');transmite_caracter(' ');
break;
}else{ //Si ha habido un error
//"ERROR"
transmite_caracter('E');transmite_caracter('R');transmite_caracter('R');
transmite_caracter('O');transmite_caracter('R');
}
}
inicializa_reloj();
//"- Init Done "
//lcd_clear_display();
lcd_ac_set(LCD_POS_1_0);
transmite_caracter('-');transmite_caracter(' ');transmite_caracter('I');
transmite_caracter('n');transmite_caracter('i');transmite_caracter('t');
transmite_caracter(' ');transmite_caracter('D');transmite_caracter('o');
transmite_caracter('n');transmite_caracter('e');transmite_caracter(' ');
delay_ms(500);
lcd_clear_display();
//"Load EEPROM"
transmite_caracter('L');transmite_caracter('o');transmite_caracter('a');
transmite_caracter('d');transmite_caracter(' ');transmite_caracter('E');
transmite_caracter('E');transmite_caracter('P');transmite_caracter('R');
transmite_caracter('O');transmite_caracter('M');
if (cargar_eeprom())
{
//"- BROKEN Data"
//lcd_clear_display();
lcd_ac_set(LCD_POS_1_0);
transmite_caracter('-');transmite_caracter(' ');transmite_caracter('B');
transmite_caracter('R');transmite_caracter('O');transmite_caracter('K');
transmite_caracter('E');transmite_caracter('N');transmite_caracter(' ');
transmite_caracter('D');transmite_caracter('a');transmite_caracter('t');
transmite_caracter('a');
guardar_eeprom(); //Inicializar Datos
delay_ms(500);
}
else
{
//"- Done"
//lcd_clear_display();
lcd_ac_set(LCD_POS_1_0);
transmite_caracter('-');transmite_caracter(' ');
transmite_caracter('D');transmite_caracter('o');transmite_caracter('n');
transmite_caracter('e');
delay_ms(500);
}
lcd_clear_display();
//Programa Principal
while(TRUE)
{
if (++cont_lectura_reloj > 0)
{
leer_reloj();
actualiza_riego();
cont_lectura_reloj = -CLOCK_POLLING_DIV;
}
scan_io();
actualizar_interfaz();
actualizar_pantalla();
}
}
///////////////////////////////////////////////////////////////////////////////
void actualiza_riego()
{
//Tiempo actual >= tiempo de inicio?
if (comp_tiempos(hora, min, config_hora_inicio[dia_sem], config_minuto_inicio[dia_sem]))
{
//Tiempo fin > Tiempo actual? -> !(Tiempo actual >= tiempo fin)?
if (!(comp_tiempos(hora, min, config_hora_fin[dia_sem], config_minuto_fin[dia_sem])))
{
output_high(PIN_RIEGO);
return;
}
}
output_low(PIN_RIEGO);
}
//-----------------------------------------------------------------------------
void scan_io()
{
//ACTUALIZAR VALORES DE LAS ENTRADAS
//MOVER A LOS REGISTROS DE VALORES ANTERIORES
puls_up_ant = puls_up_act;
puls_down_ant = puls_down_act;
puls_right_ant = puls_right_act;
puls_left_ant = puls_left_act;
//puls_ok_ant = puls_ok_ant;
//LEER LAS ENTRADAS
puls_up_act = !input(PULS_UP);
puls_down_act = !input(PULS_DOWN);
puls_right_act = !input(PULS_RIGHT);
puls_left_act = !input(PULS_LEFT);
//puls_ok_act = !input(PULS_OK);
//CALCULAR LOS FLANCOS DE SUBIDA
puls_up_fs = puls_up_act && !puls_up_ant;
puls_down_fs = puls_down_act && !puls_down_ant;
puls_right_fs = puls_right_act && !puls_right_ant;
puls_left_fs = puls_left_act && !puls_left_ant;
//puls_ok_fs = puls_ok_act && !puls_ok_ant;
//ACTUALIZAR CICLOS PARA REPETICIONES
if (puls_up_act) puls_up_cont_mant++;
else puls_up_cont_mant = KEY_INPUT_DELAY;
if (puls_down_act) puls_down_cont_mant++;
else puls_down_cont_mant = KEY_INPUT_DELAY;
if (puls_right_act) puls_right_cont_mant++;
else puls_right_cont_mant = KEY_INPUT_DELAY;
if (puls_left_act) puls_left_cont_mant++;
else puls_left_cont_mant = KEY_INPUT_DELAY;
//if (puls_ok_act) puls_ok_cont_mant++;
//else puls_ok_cont_mant = KEY_INPUT_DELAY;
//ACTUALIZAR CICLOS PARA REPETICIONES
if (puls_up_cont_mant >= KEY_REPEAT_TIME)
{
puls_up_fs = 1;
puls_up_cont_mant = 0;
}
if (puls_down_cont_mant >= KEY_REPEAT_TIME)
{
puls_down_fs = 1;
puls_down_cont_mant = 0;
}
if (puls_right_cont_mant >= KEY_REPEAT_TIME)
{
puls_right_fs = 1;
puls_right_cont_mant = 0;
}
if (puls_left_cont_mant >= KEY_REPEAT_TIME)
{
puls_left_fs = 1;
puls_left_cont_mant = 0;
}
//if (puls_ok_cont_mant >= KEY_REPEAT_TIME)
//{
// puls_ok_fs = 1;
// puls_ok_cont_mant = 0;
//}
//ACTUALIZAR ESTADO DE INACTIVIDAD
//SI NO HAY NINGUN PULSADOR APRETADO
if (!(puls_up_act | puls_down_act | puls_right_act | puls_left_act /*| puls_ok_act*/))
{
//COMPROBAR LOS CICLOS QUE LLEVA, INCREMENTAR SI NO HA LLEGADO AL LIMITE
//Y VOLVER A LA PANTALLA DE INFO SI SE HA LLEGADO AL LIMITE
if (cont_inactividad == INACTIVITY_CICLES)
{
//INACTIVO
if (pantalla_actual == 1)
{
if (comprobar_datos_config())
{
config_cursor_actual = 0;
actualizar_pantalla();
guardar_eeprom();
}
}
pantalla_actual = 0;
}
else
cont_inactividad++;
}
else
//SI HAY ALGO APRETADO
cont_inactividad = 0;
}
//-----------------------------------------------------------------------------
void actualizar_interfaz()
{
//HACER LOS CAMBIOS APROPIADOS SEGUN LAS ENTRADAS
switch (pantalla_actual)
{
//PANTALLA DE INFO
case 0:
//Si se ha presionado cualquier tecla
if (puls_right_fs /*|| puls_ok_fs*/)
{
pantalla_actual = 1; //pasar a la pantalla de configuracion
config_cursor_actual = 0;
config_dia_actual = dia_sem;
actualizar_cursor_pantalla();
}
if (puls_left_fs)
{
pantalla_actual = 1; //pasar a la pantalla de configuracion
config_cursor_actual = 8;
config_dia_actual = dia_sem;
actualizar_cursor_pantalla();
}
if (puls_up_fs){
pantalla_actual = 2; //pasar a la pantalla de ajuste del reloj
config_cursor_actual = 0;
actualizar_cursor_pantalla();
}
//-------------------------
break;
//PANTALLA DE CONFIGURACION
case 1:
switch (config_cursor_actual)
{
//CURSOR EN DIA DE LA SEMANA
case 0:
if (puls_up_fs && comprobar_datos_config())
{
if (++config_dia_actual == 7) config_dia_actual = 0;
}
if (puls_down_fs && comprobar_datos_config())
{
if (--config_dia_actual == -1) config_dia_actual = 6;
}
//-------------------------
break;
//CURSOR EN DECENAS HORA INICIO
case 1:
if (puls_up_fs)
{
inc_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_INC, 1);
}
if (puls_down_fs)
{
dec_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_DEC, 1);
}
//-------------------------
break;
//CURSOR EN UNIDADES HORA INICIO
case 2:
if (puls_up_fs)
{
inc_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_INC, 0);
}
if (puls_down_fs)
{
dec_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_DEC, 0);
}
//-------------------------
break;
//CURSOR EN DECENAS MINUTOS INICIO
case 3:
if (puls_up_fs){
if (inc_2bcd(&config_minuto_inicio[config_dia_actual],
LIMIT_MINS_INC, 1))
{
inc_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_INC, 0);
}
}
if (puls_down_fs){
if (dec_2bcd(&config_minuto_inicio[config_dia_actual],
LIMIT_MINS_DEC, 1))
{
dec_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_DEC, 0);
}
}
//-------------------------
break;
//CURSOR EN UNIDADES MINUTOS INICIO
case 4:
if (puls_up_fs){
if (inc_2bcd(&config_minuto_inicio[config_dia_actual],
LIMIT_MINS_INC, 0))
{
inc_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_INC, 0);
}
}
if (puls_down_fs){
if (dec_2bcd(&config_minuto_inicio[config_dia_actual],
LIMIT_MINS_DEC, 0))
{
dec_2bcd(&config_hora_inicio[config_dia_actual],
LIMIT_HORAS_DEC, 0);
}
}
//-------------------------
break;
//CURSOR EN DECENAS HORA FIN
case 5:
if (puls_up_fs)
{
inc_2bcd(&config_hora_fin[config_dia_actual],
(config_minuto_fin[config_dia_actual] == 0)? 0x25 : LIMIT_HORAS_INC, 1);
/*
inc_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_INC, 1);
*/
}
if (puls_down_fs)
{
dec_2bcd(&config_hora_fin[config_dia_actual],
(config_minuto_fin[config_dia_actual] == 0)? 0x24 : LIMIT_HORAS_DEC, 1);
/*
dec_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_DEC, 1);
*/
}
//-------------------------
break;
//CURSOR EN UNIDADES HORA FIN
case 6:
if (puls_up_fs)
{
inc_2bcd(&config_hora_fin[config_dia_actual],
(config_minuto_fin[config_dia_actual] == 0)? 0x25 : LIMIT_HORAS_INC, 0);
/*
inc_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_INC, 0);
*/
}
if (puls_down_fs)
{
dec_2bcd(&config_hora_fin[config_dia_actual],
(config_minuto_fin[config_dia_actual] == 0)? 0x24 : LIMIT_HORAS_DEC, 0);
/*
dec_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_DEC, 0);
*/
}
//-------------------------
break;
//CURSOR EN DECENAS MINUTOS FIN
case 7:
if (puls_up_fs)
{
if (config_hora_fin[config_dia_actual] == 0x24)
config_hora_fin[config_dia_actual] = 0;
if (inc_2bcd(&config_minuto_fin[config_dia_actual], LIMIT_MINS_INC, 1))
inc_2bcd(&config_hora_fin[config_dia_actual],
(config_minuto_fin[config_dia_actual] == 0x00)? 0x25 : LIMIT_HORAS_INC, 0);
/*
if (inc_2bcd(&config_minuto_fin[config_dia_actual],
LIMIT_MINS_INC, 1))
{
inc_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_INC, 0);
}
*/
}
if (puls_down_fs)
{
if (dec_2bcd(&config_minuto_fin[config_dia_actual], LIMIT_MINS_DEC, 1))
dec_2bcd(&config_hora_fin[config_dia_actual], LIMIT_HORAS_DEC, 0);
/*
if (dec_2bcd(&config_minuto_fin[config_dia_actual],
LIMIT_MINS_DEC, 1))
{
dec_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_DEC, 0);
}
*/
}
//-------------------------
break;
//CURSOR EN UNIDADES MINUTOS FIN
case 8:
if (puls_up_fs)
{
if (config_hora_fin[config_dia_actual] == 0x24)
config_hora_fin[config_dia_actual] = 0;
if (inc_2bcd(&config_minuto_fin[config_dia_actual], LIMIT_MINS_INC, 0))
inc_2bcd(&config_hora_fin[config_dia_actual], 0x25, 0);
/*
if (inc_2bcd(&config_minuto_fin[config_dia_actual],
LIMIT_MINS_INC, 0))
{
inc_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_INC, 0);
}
*/
}
if (puls_down_fs)
{
if (dec_2bcd(&config_minuto_fin[config_dia_actual], LIMIT_MINS_DEC, 0))
dec_2bcd(&config_hora_fin[config_dia_actual], LIMIT_HORAS_DEC, 0);
/*
if (dec_2bcd(&config_minuto_fin[config_dia_actual],
LIMIT_MINS_DEC, 0))
{
dec_2bcd(&config_hora_fin[config_dia_actual],
LIMIT_HORAS_DEC, 0);
}
*/
}
//-------------------------
break;
}
if (puls_right_fs)
{
//Mover Cursor a la derecha y dar la vuelta
//if (++config_cursor_actual == 9) config_cursor_actual = 0;
//Volver a pantalla de info si se sale por la derecha
//config_cursor_actual = 0;
//pantalla_actual = 0;
//Mover Cursor a la derecha
if (++config_cursor_actual == 9)
{
//Volver a pantalla de info si se sale por la derecha
if (comprobar_datos_config())
{
pantalla_actual = 0;
config_cursor_actual = 0;
actualizar_pantalla();
guardar_eeprom();
}
else config_cursor_actual = 8;
}
}
if (puls_left_fs)
{
//Mover Cursor a la izquierda y dar la vuelta
//if (--config_cursor_actual == -1) config_cursor_actual = 8;
//Volver a pantalla de info si se sale por la izquierda
//config_cursor_actual = 0;
//pantalla_actual = 0;
//Mover Cursor a la izquierda
if (--config_cursor_actual == -1)
{
//Volver a pantalla de info si se sale por la izquierda
if (comprobar_datos_config())
{
pantalla_actual = 0;
actualizar_pantalla();
guardar_eeprom();
}
config_cursor_actual = 0;
}
}
if (pantalla_actual != 0 && (puls_right_fs || puls_left_fs))
{
actualizar_cursor_pantalla();
}
//-------------------------
break;
//PANTALLA DE AJUSTE DEL RELOJ
case 2:
switch (config_cursor_actual)
{
//CURSOR EN DIA DE LA SEMANA
case 0:
if (puls_up_fs){
if (++dia_sem == 7) dia_sem = 0;
}
if (puls_down_fs){
if (--dia_sem == -1) dia_sem = 6;
}
break;
//CURSOR EN DECENAS DEL DIA
case 1:
if (puls_up_fs){
inc_2bcd(&dia, 0x32, 1);
}
if (puls_down_fs){
dec_2bcd(&dia, 0x31, 1);
}
break;
//CURSOR EN UNIDADES DEL DIA
case 2:
if (puls_up_fs){
inc_2bcd(&dia, 0x32, 0);
}
if (puls_down_fs){
dec_2bcd(&dia, 0x31, 0);
}
break;
//CURSOR EN DECENAS DEL MES
case 3:
if (puls_up_fs){
inc_2bcd(&mes, 0x13, 1);
}
if (puls_down_fs){
dec_2bcd(&mes, 0x12, 1);
}
break;
//CURSOR EN UNIDADES DEL MES
case 4:
if (puls_up_fs){
inc_2bcd(&mes, 0x13, 0);
}
if (puls_down_fs){
dec_2bcd(&mes, 0x12, 0);
}
break;
//CURSOR EN DECENAS DEL ANYO
case 5:
if (puls_up_fs){
inc_2bcd(&anyo, 0xA0, 1);
}
if (puls_down_fs){
dec_2bcd(&anyo, 0x99, 1);
}
break;
//CURSOR EN UNIDADES DEL ANYO
case 6:
if (puls_up_fs){
inc_2bcd(&anyo, 0xA0, 0);
}
if (puls_down_fs){
dec_2bcd(&anyo, 0x99, 0);
}
break;
//CURSOR EN DECENAS DE LA HORA
case 7:
if (puls_up_fs){
inc_2bcd(&hora, 0x24, 1);
}
if (puls_down_fs){
dec_2bcd(&hora, 0x23, 1);
}
break;
//CURSOR EN UNIDADES DE LA HORA
case 8:
if (puls_up_fs){
inc_2bcd(&hora, 0x24, 0);
}
if (puls_down_fs){
dec_2bcd(&hora, 0x23, 0);
}
break;
//CURSOR EN DECENAS DE LOS MINUTOS
case 9:
if (puls_up_fs){
if (inc_2bcd(&min, 0x60, 1)) inc_2bcd(&hora, 0x24, 0);
}
if (puls_down_fs){
if (dec_2bcd(&min, 0x59, 1)) dec_2bcd(&hora, 0x23, 0);
}
break;
//CURSOR EN UNIDADES DE LOS MINUTOS
case 10:
if (puls_up_fs){
if (inc_2bcd(&min, 0x60, 0)) inc_2bcd(&hora, 0x24, 0);
}
if (puls_down_fs){
if (dec_2bcd(&min, 0x59, 0)) dec_2bcd(&hora, 0x23, 0);
}
break;
}
if (puls_up_fs || puls_down_fs) ajusta_reloj();
if (puls_right_fs) ++config_cursor_actual;
if (puls_left_fs) --config_cursor_actual;
if (config_cursor_actual == 11 || config_cursor_actual == -1)
{
pantalla_actual = 0;
config_cursor_actual = 0;
}
if (puls_right_fs || puls_left_fs)
{
actualizar_cursor_pantalla();
}
//-------------------------
break;
}
}
//-----------------------------------------------------------------------------
void actualizar_pantalla()
{
switch (pantalla_actual)
{
//-------------------------
//PANTALLA DE INFO
case 0:
//PREV: [12:33 20/02/2009]
// hh:mm DD/MM/20AA
lcd_return_home();
lcd_print_2num_bcd(hora);
transmite_caracter(':');
lcd_print_2num_bcd(min);
transmite_caracter(' ');
lcd_print_2num_bcd(dia);
transmite_caracter('/');
lcd_print_2num_bcd(mes);
transmite_caracter('/');
transmite_caracter('2');
transmite_caracter('0');
lcd_print_2num_bcd(anyo);
//Linea de información sobre proximo riego y fin de riego
lcd_ac_set(LCD_POS_1_0);
//Si el instante de inicio y de fin no son iguales
if (!(config_hora_inicio[dia_sem] == config_hora_fin[dia_sem] &&
config_minuto_inicio[dia_sem] == config_minuto_fin[dia_sem]))
{
temp = input(PIN_RIEGO);
//PIN_RIEGO == 1?
if (temp)
{
//PREV: [fin riego 12:50]
// hh:mm
transmite_caracter('f'); transmite_caracter('i'); transmite_caracter('n');
transmite_caracter(' '); transmite_caracter('r'); transmite_caracter('i');
transmite_caracter('e'); transmite_caracter('g'); transmite_caracter('o');
transmite_caracter(' '); transmite_caracter(' ');
lcd_print_2num_bcd(config_hora_fin[dia_sem]);
transmite_caracter(':');
lcd_print_2num_bcd(config_minuto_fin[dia_sem]);
}
//PIN_RIEGO == 0?
else
//Si Tiempo actual < Tiempo inicio
if (!(comp_tiempos(hora, min, config_hora_inicio[dia_sem], config_minuto_inicio[dia_sem])))
{
//PREV: [prox.riego 12:33]
// hh:mm
transmite_caracter('p'); transmite_caracter('r'); transmite_caracter('o');
transmite_caracter('x'); transmite_caracter('.'); transmite_caracter('r');
transmite_caracter('i'); transmite_caracter('e'); transmite_caracter('g');
transmite_caracter('o'); transmite_caracter(' ');
lcd_print_2num_bcd(config_hora_inicio[dia_sem]);
transmite_caracter(':');
lcd_print_2num_bcd(config_minuto_inicio[dia_sem]);
}
else
{
//PREV: [ya se ha regado ]
transmite_caracter('y'); transmite_caracter('a'); transmite_caracter(' ');
transmite_caracter('s'); transmite_caracter('e'); transmite_caracter(' ');
transmite_caracter('h'); transmite_caracter('a'); transmite_caracter(' ');
transmite_caracter('r'); transmite_caracter('e'); transmite_caracter('g');
transmite_caracter('a'); transmite_caracter('d'); transmite_caracter('o');
transmite_caracter(' ');
}
}
else
{
//PREV: [hoy no hay riego]
transmite_caracter('h'); transmite_caracter('o'); transmite_caracter('y');
transmite_caracter(' '); transmite_caracter('n'); transmite_caracter('o');
transmite_caracter(' '); transmite_caracter('h'); transmite_caracter('a');
transmite_caracter('y'); transmite_caracter(' '); transmite_caracter('r');
transmite_caracter('i'); transmite_caracter('e'); transmite_caracter('g');
transmite_caracter('o');
}
break;
//-------------------------
//PANTALLA DE CONFIGURACION
case 1:
//lcd_clear_display();
//PREV: [LUN 12:50 a15:30]
// ddd hh:mm aHH:MM
lcd_return_home();
lcd_print_nom_dia_sem(config_dia_actual);
transmite_caracter(' ');
lcd_print_2num_bcd(config_hora_inicio[config_dia_actual]);
transmite_caracter(':');
lcd_print_2num_bcd(config_minuto_inicio[config_dia_actual]);
transmite_caracter(' ');
transmite_caracter('a');
lcd_print_2num_bcd(config_hora_fin[config_dia_actual]);
transmite_caracter(':');
lcd_print_2num_bcd(config_minuto_fin[config_dia_actual]);
break;
//-------------------------
//PANTALLA DE AJUSTE DEL RELOJ
case 2:
//lcd_clear_display();
//PREV: [L 11/04/09 12:57]
// d DD MM AA hh mm
lcd_return_home();
switch (dia_sem){
case 0: transmite_caracter('D'); break;
case 1: transmite_caracter('L'); break;
case 2: transmite_caracter('M'); break;
case 3: transmite_caracter('X'); break;
case 4: transmite_caracter('J'); break;
case 5: transmite_caracter('V'); break;
case 6: transmite_caracter('S'); break;
}
transmite_caracter(' ');
lcd_print_2num_bcd(dia);
transmite_caracter('/');
lcd_print_2num_bcd(mes);
transmite_caracter('/');
lcd_print_2num_bcd(anyo);
transmite_caracter(' ');
lcd_print_2num_bcd(hora);
transmite_caracter(':');
lcd_print_2num_bcd(min);
break;
}
}
//-----------------------------------------------------------------------------
void actualizar_cursor_pantalla()
{
lcd_ac_set(LCD_POS_1_0);
for (temp = 0; temp <= 15; temp++){
transmite_caracter(' ');
}
//-------------------------
//PANTALLA DE CONFIGURACION
if (pantalla_actual == 1)
{
switch (config_cursor_actual)
{
case 0: lcd_ac_set(LCD_POS_1_1); break;
case 1: lcd_ac_set(LCD_POS_1_4); break;
case 2: lcd_ac_set(LCD_POS_1_5); break;
case 3: lcd_ac_set(LCD_POS_1_7); break;
case 4: lcd_ac_set(LCD_POS_1_8); break;
case 5: lcd_ac_set(LCD_POS_1_11); break;
case 6: lcd_ac_set(LCD_POS_1_12); break;
case 7: lcd_ac_set(LCD_POS_1_14); break;
case 8: lcd_ac_set(LCD_POS_1_15); break;
}
transmite_caracter('^');
}
//-------------------------
//PANTALLA DE AJUSTE DEL RELOJ
if (pantalla_actual == 2)
{
switch (config_cursor_actual)
{
case 0: lcd_ac_set(LCD_POS_1_0); break;
case 1: lcd_ac_set(LCD_POS_1_2); break;
case 2: lcd_ac_set(LCD_POS_1_3); break;
case 3: lcd_ac_set(LCD_POS_1_5); break;
case 4: lcd_ac_set(LCD_POS_1_6); break;
case 5: lcd_ac_set(LCD_POS_1_8); break;
case 6: lcd_ac_set(LCD_POS_1_9); break;
case 7: lcd_ac_set(LCD_POS_1_11); break;
case 8: lcd_ac_set(LCD_POS_1_12); break;
case 9: lcd_ac_set(LCD_POS_1_14); break;
case 10: lcd_ac_set(LCD_POS_1_15); break;
}
transmite_caracter('^');
}
}
//-----------------------------------------------------------------------------
short comp_tiempos(int hora_a, int min_a, int hora_b, int min_b)
//Devuelve 1 si A >= B / 0 si A < B
{
if (hora_a > hora_b) return 1;
if ((hora_a == hora_b) && (min_a >= min_b)) return 1;
return 0;
}
//-----------------------------------------------------------------------------
short comprobar_datos_config() //Devuelve 1 si son correctos
{
//Si Tiempo_fin >= Tiempo_inicio : correcto
if (comp_tiempos(config_hora_fin[config_dia_actual],config_minuto_fin[config_dia_actual],
config_hora_inicio[config_dia_actual],config_minuto_inicio[config_dia_actual]))
return 1;
//Sino Tiempo_fin = Tiempo_inicio y mostrar mensaje
config_hora_fin[config_dia_actual] = config_hora_inicio[config_dia_actual];
config_minuto_fin[config_dia_actual] = config_minuto_inicio[config_dia_actual];
lcd_clear_display();
transmite_caracter('!');
transmite_caracter('L');transmite_caracter('a');transmite_caracter(' ');
transmite_caracter('h');transmite_caracter('o');transmite_caracter('r');
transmite_caracter('a');transmite_caracter(' ');transmite_caracter('d');
transmite_caracter('e');transmite_caracter(' ');transmite_caracter('f');
transmite_caracter('i');transmite_caracter('n');
lcd_ac_set(LCD_POS_1_0);
transmite_caracter('n');transmite_caracter('o');transmite_caracter(' ');
transmite_caracter('<');transmite_caracter(' ');transmite_caracter('h');
transmite_caracter('o');transmite_caracter('r');transmite_caracter('a');
transmite_caracter(' ');transmite_caracter('i');transmite_caracter('n');
transmite_caracter('i');transmite_caracter('c');transmite_caracter('i');
transmite_caracter('o');
delay_ms(4000);
actualizar_cursor_pantalla();
return 0;
}
//-----------------------------------------------------------------------------
void pulse_out(int pin)
{
output_high(pin);
delay_us(150);
output_low(pin);
}
//-----------------------------------------------------------------------------
short test_reloj() //devuelve 1 si recibe ACK, 0 error de algun tipo
{
i2c_start();
temp = i2c_write(0b11010000); //ID del reloj, Escribir
i2c_stop();
if (temp == 0){
return 1;
}else{
return 0;
}
}
//-----------------------------------------------------------------------------
void inicializa_reloj()
{
//Set Address 00H
i2c_start();
i2c_write(0b11010000); //ID del reloj, Escribir
i2c_write(0x00); //Direccion 00H
i2c_stop();
//Read Address 00H
i2c_start();
i2c_write(0b11010001); //ID del reloj, Leer
temp = i2c_read(0); //00H - Clock Halt, segundos, NOT ACK
i2c_stop();
if (temp & 0b10000000) //Si Clock Halt == 1
{
//Clear Clock Halt
i2c_start();
i2c_write(0b11010000); //ID del reloj, Escribir
i2c_write(0x00); //Adress 00H
i2c_write(temp & 0b01111111); //Clear CH
i2c_stop();
}
}
//-----------------------------------------------------------------------------
void leer_reloj()
{
//Set Address 01H
i2c_start();
i2c_write(0b11010000); //ID del reloj, Escribir
i2c_write(0x01); //Direccion 01H
i2c_stop();
//Read Address 01H
i2c_start();
i2c_write(0b11010001); //ID del reloj, Leer
min = i2c_read(); //01H - minutos
hora = i2c_read(); //02H - horas
dia_sem = i2c_read() - 1; //03H - dia de la semana
dia = i2c_read(); //04H - dia del mes
mes = i2c_read(); //05H - mes
anyo = i2c_read(0); //06H - año, NOT ACK para terminar lectura
i2c_stop();
}
//-----------------------------------------------------------------------------
void ajusta_reloj()
{
//Set Address 00H
i2c_start();
i2c_write(0b11010000); //ID del reloj, Escribir
i2c_write(0x00); //Direccion 00H
i2c_write(0x00); //seg = 0
i2c_write(min); //minutos
i2c_write(hora); //horas
i2c_write(dia_sem + 1); //dia de la semana
i2c_write(dia); //dia del mes
i2c_write(mes); //mes
i2c_write(anyo); //anyo
// i2c_write(0x10); //OUT = 0, SQWE = 1, RS1 = 0, RS0 = 0 (1Hz)
// i2c_write(0x80); //OUT = 1, SQWE = 0, RS1 = 0, RS0 = 0 (1Hz)
i2c_stop();
}
//-----------------------------------------------------------------------------
void inicializa_LCD()
{
delay_ms(20);
output_b(0b00000011); //LCD Wake Up
pulse_out(E); //"
delay_ms(10);
pulse_out(E); //LCD Wake Up
delay_ms(1);
pulse_out(E); //LCD Wake Up
delay_ms(1);
output_b(0b00000010); //DL (Data Lenght) = 4 hilos de comunicacion
pulse_out(E); //"
delay_ms(10);
transmite_comando(0b00101000); //Function Set: 4bits comm, All lines, 5x8 Font
transmite_comando(0b00001100); //Display Control: Display ON, Cursor OFF, Blink OFF
transmite_comando(0b00000001); //Clear Display
transmite_comando(0b00000110); //Entry Mode Set: Increment AC, Don't move Screen
delay_ms(1);
}
//-----------------------------------------------------------------------------
void transmite_caracter(char caracter)
{
output_high(RS);
output_b(caracter >> 4);
pulse_out(E);
output_b(caracter);
pulse_out(E);
output_low(RS);
delay_us(100 + EXTRA_DELAY);
}
//-----------------------------------------------------------------------------
void transmite_comando(int comando)
{
output_b(comando >> 4);
pulse_out(E);
output_b(comando);
pulse_out(E);
delay_us(100 + EXTRA_DELAY);
}
//-----------------------------------------------------------------------------
void lcd_clear_display(){transmite_comando(0b00000001); delay_ms(1);}
//-----------------------------------------------------------------------------
void lcd_return_home(){transmite_comando(0b00000010); delay_us(900);}
//-----------------------------------------------------------------------------
void lcd_ac_set(int address){transmite_comando(0b10000000 | address);}
//-----------------------------------------------------------------------------
void lcd_print_nom_dia_sem(int num_dia_sem)
{
switch (num_dia_sem)
{
case 1:
transmite_caracter('L');
transmite_caracter('U');
transmite_caracter('N');
break;
case 2:
transmite_caracter('M');
transmite_caracter('A');
transmite_caracter('R');
break;
case 3:
transmite_caracter('M');
transmite_caracter('I');
transmite_caracter('E');
break;
case 4:
transmite_caracter('J');
transmite_caracter('U');
transmite_caracter('E');
break;
case 5:
transmite_caracter('V');
transmite_caracter('I');
transmite_caracter('E');
break;
case 6:
transmite_caracter('S');
transmite_caracter('A');
transmite_caracter('B');
break;
case 0:
transmite_caracter('D');
transmite_caracter('O');
transmite_caracter('M');
break;
}
}
//-----------------------------------------------------------------------------
void lcd_print_2num_bcd(int num_bcd)
{
transmite_caracter((num_bcd >> 4) + 0x30); //DECENAS
transmite_caracter((num_bcd & 0x0F) + 0x30); //UNIDADES
}
//-----------------------------------------------------------------------------
void lcd_print_1num_bcd(int num_bcd, short digito = 0)
//Valores de parametro digito:
// 0 - imprime las unidades (por defecto)
// 1 - imprime las decenas
{
switch (digito)
{
case 0:
transmite_caracter((num_bcd & 0x0F) + 0x30); //UNIDADES
break;
case 1:
transmite_caracter((num_bcd >> 4) + 0x30); //DECENAS
break;
}
}
//-----------------------------------------------------------------------------
short inc_2bcd(int* num_bcd, int bcd_limite = 0x9A, short digito = 0)
//Significado de los parametros:
// num_bcd: numero de 2 cifras en BCD que queremos incrementar
// bcd_limite: valor una vez incrementado el numero BCD que se considera que
// ha habido un desbordamiento, volviendo al valor 0. Los unicos
// valores no BCD aceptables son desde 0x9A hasta 0xA0 que
// equivalen a 100 BCD.
// digito: especifica si se ha de incrementar la cifra de las unidades(0)
// o la de las decenas (1)
//
//Devuelve 1 si desborda por el limite
{
switch (digito)
{
//Incrementar unidades
case 0:
*num_bcd +=1; //Unidades + 1
if ((*num_bcd & 0x0F) > 9) //Unidades > 9?
{
*num_bcd &= 0xF0; //Unidades = 0
*num_bcd += 0x10; //Decenas + 1
}
if (*num_bcd >= bcd_limite)//Desbordamiento?
{
*num_bcd = 0x00; //Numero BCD = 00
return 1; //Devolver desbordamiento
}
break;
//Incrementar decenas
case 1:
*num_bcd += 0x10; //Decenas + 1
if (*num_bcd >= bcd_limite)//Desbordamiento?
{
*num_bcd &= 0x0F; //Decenas = 0
return 1; //Devolver desbordamiento
}
break;
}
return 0;
}
//-----------------------------------------------------------------------------
short dec_2bcd(int* num_bcd, int bcd_limite = 0x99, short digito = 0)
//Significado de los parametros:
// num_bcd: numero de 2 cifras en BCD que queremos decrementar
// bcd_limite: valor que tomará el numero BCD si se ha llegado a numeros
// negativos (desbordamiento).
// digito: especifica si se ha de decrementar la cifra de las unidades(0)
// o la de las decenas (1)
//
//Devuelve 1 si desborda por debajo de 0
{
switch (digito)
{
//Decrementar unidades
case 0:
*num_bcd -= 1; //Unidades - 1
if (*num_bcd == 0xFF) //Desbordamiento?
{
*num_bcd = bcd_limite; //Numero BCD = limite
return 1; //Devolver desbordamiento
}
if ((*num_bcd & 0x0F) == 0x0F)//Desbordamiento de Unidades?
{ //Automaticamente -> Decenas - 1
*num_bcd &= 0xF9;//0b11111001;//Unidades = 9
}
break;
//Decrementar decenas
case 1:
*num_bcd -= 0x10; //Decenas - 1
if ((*num_bcd & 0xF0) == 0xF0)//Desbordamiento?
{
*num_bcd = (*num_bcd & 0x0F) | (bcd_limite & 0xF0); //Decenas = Decenas de limite
if (*num_bcd > bcd_limite){ //Al restaurar las decenas, el numBCD es > limite?
*num_bcd -= 0x10; //Decenas - 1
}
return 1; //Devolver desbordamiento
}
break;
}
return 0;
}
//-----------------------------------------------------------------------------
short cargar_eeprom() //Devuelve 0 si todo correcto / 1 si ha ocurrido algun error
{
short temp_return;
int *array;
int i;
int checksum_calc, checksum_leido;
checksum_calc = 0x4A; //Valor de inicio de la suma de comprobación de errores.
for (i = 0; i < 4; i++){
switch(i)
{
case 0: array = &config_hora_inicio[0]; break;
case 1: array = &config_minuto_inicio[0]; break;
case 2: array = &config_hora_fin[0]; break;
case 3: array = &config_minuto_fin[0]; break;
}
for (temp = 0; temp < 7; temp++){
array[temp] = read_eeprom((i*7) + temp);
if (array[temp] > 0x59) temp_return = 1;
checksum_calc += array[temp];
}
}
//Comprobación de errores
checksum_leido = read_eeprom(0x1C /* =4*7 */);
if (checksum_calc != checksum_leido){
//Reset Data
for (temp = 0; temp < 7; temp++){
config_hora_inicio[temp] = config_minuto_inicio[temp] = 0x00;
config_hora_fin[temp] = config_minuto_fin[temp] = 0x00;
}
return 1;
}else return 0;
}
//-----------------------------------------------------------------------------
void guardar_eeprom()
{
int *array;
int i;
int checksum;
checksum = 0x4A; //Valor de inicio de la suma de comprobación de errores.
for (i = 0; i < 4; i++){
switch(i)
{
case 0: array = &config_hora_inicio[0]; break;
case 1: array = &config_minuto_inicio[0]; break;
case 2: array = &config_hora_fin[0]; break;
case 3: array = &config_minuto_fin[0]; break;
}
for (temp = 0; temp < 7; temp++){
write_eeprom((i*7) + temp, array[temp]);
checksum += array[temp];
}
}
write_eeprom((0x1C /* =4*7 */), checksum);
}
//-----------------------------------------------------------------------------;
Esta obra está bajo una licencia de Creative Commons: (
http://creativecommons.org/licenses/by-sa/3.0/es/)