TODOPIC
Simuladores, editores de PCB, etc => Simuladores de circuitos => Proteus ISIS => Mensaje iniciado por: venerable13 en 29 de Diciembre de 2009, 17:28:12
-
Hola es mi primer mensaje en este foro y estoy desesperado, después de indagar hice un programa con el DS1302 pero necesitaba una salida de 1Hz para otro circuito con lo que simulé también el DS1307 y lo que hice fue cambiar las instrucciones y aplicar las de la librería del DS1307.
El programa saca la fecha y hora y al principio se configura, cuando se pone ok se visualiza la hora configurada, el problema es que con el ds1302 me va perfecto, pero con el ds1307 el proteus se me vuelve loco. He utilizado la libreria flex_lcd y todo lo demás es normal Adjunto link de los programas y simulaciones en el proteus. DAVID 1 será DS1302 ok Y DAVID 2 será DS1307 que necesito que vaya bien y no va. De todas formas pego tb el código y a ver si logran decirme por qué no me va. Como ven comento las líneas del ds1302 para que vean donde pongo las del DS1307, ok? los pines del ds1307 están puestos en su librería, lo inicializo y pongo las instrucciones pertinentes que verán a continuación, no hagan caso de algunos comentarios que están incorrectos, sólo fijense en el código que además tiene instrucciones que están relacionadas con otro circuito pero ahi no me falla:
DS1302 QUE VA OK
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR'05
// 09/Septiembre/05
// vszener@gmail.com
// Programa: Reloj-Calendario DS1302
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la fecha y hora obtenida mediante la
// lectura del DS1302. Pudiendose modificar mediante los botones Conf/Ok y up.
// Se utiliza variables globales:
// ·day-> dia ds1302
// ·mth -> mes ds1302
// ·year -> año ds1302
// ·hour -> hora ds1302
// ·min -> minutos ds1302
// ·sec-> segundos ds1302
// ·menu -> variable que muestra opcion del menu configurar
// ·flag -> variable que cuenta hasta 130ms aprox.
// ·var -> ajuste fino para que desborde cada 130ms aprox.
// Se carga el TMR0 con 0 por lo tanto se desborda en 65ms aprox, queremos
// visualizar y restaurar valores cogidos del ds1302 cada 130ms aprox por lo tanto
// utilizamos una variable llamada flag que sera la encargada de dicha tarea.
// Al inicio del programa debe ser configurado el reloj, siendo el boton 'up' el
// encargado de ir moviendose mediante las opciones del menu:hora,minutos,....
// y el boton 'Conf/Ok' el encargado de configurar el reloj(cuando estemos en modo ver
// hora y fecha) o el encargado de salir de la configuracion de las opciones(cuando
// estemos en formato de configurar fecha y hora).
// Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida.
// Conexiones: A0 -> RST DS1302
// A1 -> SCLK DS1302
// A2 -> I/O DS1302
// A3 -> Boton 'up'
// A5 -> Boton 'Conf/Ok'
// B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// B3 -> Zumbador(beep)
//////////////////////////////////////////////////////////////////////////////////
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#use delay(clock=4000000) /// declara la frecuencia del cristal, era de 8 Mhz
#include <string.h> //PARA USAR LOS STRING (TEXTOS)
#include <stdlib.h>
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT //comandos para el programador
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
#use standard_io(e)
#define use_portb_lcd TRUE //utilizar el port b para lcd
#define RTC_SCLK PIN_C3 //definimos pin's...
#define RTC_IO PIN_C5
#define RTC_RST PIN_C4 //...de conexion de la rtc ds1302
#include <ds1302.c> //libreria de rtc ds1302
//#include <ds1307.c>
#include <flex_lcd.c> //libreria de lcd
///VARIABLES GLOBALES
byte day=1,mth=1,year=9,dow,hour=0,min=0,sec=0; //variabes para ds1302-ds1307
byte menu=0,flag=0,var=2; //variables para menu configurar
//variables GLOBALES para los textos
char mestxt[3]; //le cambio el nombre porque existe una función con el mismo nombre
//char am_pm[2]; //la quito porque el pow no se utiliza
///DEFINICION DE FUNCIONES
void configurar(void);
void horas(void);
void minutos(void);
void dia(void);
void dia_sem(void);
void mes(void);
void anio(void);
void beep(void);
void convierte_mes(void);
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 130ms aprox?
var--; //SI -> decremento var...
if(var==0)
var=2; //...ajuste fino de 130ms aprox
flag=0; //reset flag para contar 130ms aprox
//ds1307_get_date(day,mth,year,dow); //coge dia,mes,año ///
//ds1307_get_time(hour,min,sec); //coge hora,minuto,segundo
rtc_get_date(day,mth,year,dow);
rtc_get_time(hour,min,sec);
convierte_mes();
printf(lcd_putc,"\f%2d %s %2d\nHora: %2d:%2d:%2d",day,mestxt,year,hour,min,sec); //lcd
}
set_timer0(0); //reset TMR0
flag++; //incremento variable flag
}
///PROGRAMA
void main(void){
set_tris_a (0x28) ;
set_tris_d (0x00) ;
//set_tris_b (0xff) ;
//set_tris_c (0x04) ;
//set_tris_e (0x01) ;
output_low(PIN_A0);
output_low(PIN_A1);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_D4);
output_low(PIN_D5);
output_low(PIN_D6);
output_low(PIN_D7);
enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
set_timer0(0); //carga TMR0
lcd_init(); //inicializa lcd
rtc_init(); //inicializa rtc
//ds1307_init(); //inicializa el ds1307
lcd_putc("Reloj en BCD\nI.E.S.CABANYAL"); //presentacion...
delay_ms(1500);
lcd_gotoxy(1,1);
lcd_putc("\fToni Gellida\nD.P.E.2");
delay_ms(2000); //...inicial
configurar(); //ve a menu configurar
enable_interrupts(GLOBAL); //activadas interrupciones
while(1){ //bucle...
if(input(PIN_A5)==0){ //Si se pulsa Conf....
while(!input(PIN_A5)){} //elimina rebotes
beep();
configurar();
} //ve a menu configurar
} //...infinito
}
///FUNCION CONFIGURAR
void configurar(void){
disable_interrupts(GLOBAL); //desactivadas interrupciones
output_high(PIN_A0); //CONFIGURAR CONTADORES
do{
switch(menu){
case 0: lcd_putc("\fConfigurar\nhoras?"); //horas
output_high(PIN_D0); //CONTADOR HORAS
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
horas();
menu=1; //apunta siguiente opcion
}
break;
case 1: lcd_putc("\fConfigurar\nminutos?"); //minutos
output_low(PIN_D0); //CONTADOR HORAS FUERA
output_high(PIN_D2); //CONTADOR MINUTOS
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
minutos();
menu=2; //apunta siguiente opcion
}
break;
case 2: lcd_putc("\fConfigurar\ndia semana?"); //dia semana/no inc lcd
output_low(PIN_D2); //CONTADOR MINUTOS FUERA
output_high(PIN_D4); //CONTADOR DIA SEM
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia_sem();
menu=3; //apunta siguiente opcion
}
break;
case 4: lcd_putc("\fConfigurar\ndia?"); //dias
output_low(PIN_D4); //CONTADOR DIA SEM FUERA
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia();
menu=5; //apunta siguiente opcion
}
break;
case 3: lcd_putc("\fConfigurar\nmes?"); //mes
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
mes();
menu=4; //apunta siguiente opcion
}
break;
case 5: lcd_putc("\fConfigurar\nanio?"); //años
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
anio();
menu=6; //apunta siguiente opcion
}
break;
case 6: lcd_putc("\fSalir\nconfigurar?"); //salir configuracion
if(!input(PIN_A5)){
menu=7;
beep();
output_low(PIN_A0); //CONTADORES EN FUNCIONAMIENTO
lcd_putc("\fHora\nConfigurada"); //salir configuracion
delay_ms(2500);
}
}
if(!input(PIN_A3)){ //controla el boton up...
while(!input(PIN_A3)){}
menu++;
if(menu>6)
menu=0;
} //...para mostrar menu por lcd
delay_ms(130); //retardo para ver lcd
}while(menu<7);
menu=0; //actualiza indices menu
//ds1307_set_date_time(day,mth,year,dow,hour,min,sec);//nueva hora,minuto,...
rtc_set_datetime(day,mth,year,dow,hour,min);
enable_interrupts(GLOBAL); //activadas interrupciones
set_timer0(0); //carga TMR0
}
///FUNCION CONFIGURA HORAS
void horas(void){
printf(lcd_putc,"\fConf.Horas:\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
hour++; //SI -> incremento hour
output_high(PIN_D1); //CONTADOR UP HORAS
delay_ms(500);
output_low(PIN_D1); //CONTADOR UP HORAS BAJA
if(hour>23) hour=0;
printf(lcd_putc,"\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd hour
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA MINUTOS
void minutos(void){
printf(lcd_putc,"\fConf.Minutos:\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
min++; //SI -> incremento min
output_high(PIN_D3); //CONTADOR UP HORAS
delay_ms(500);
output_low(PIN_D3); //CONTADOR UP HORAS BAJA
if (min>59) min =0;
printf(lcd_putc,"\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd min
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA DIA SEMANA
void dia_sem(void){
printf(lcd_putc,"\fConf.Dia\nsemana"); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
output_high(PIN_D5); //CONTADOR UP DIA SEM
delay_ms(500);
output_low(PIN_D5); //CONTADOR UP DIA SEM BAJA
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA DIAS
void dia(void){
convierte_mes();
printf(lcd_putc,"\fConf.Dias:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
day++; //SI -> incremento day
if(((mth==1)||(mth==3)||(mth==5)||(mth==7)||(mth==8)||(mth==10)||(mth==12))&&(day>31)) day=1;
if((mth==2)&&(day>28)) day=1; //fallaría en los años bisiestos
if((mth==4)||(mth==6)||(mth==9)||(mth==11)&&(day>30)) day=1;
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Dias:\n%2d %s %2d",day,mestxt,year); //muestra por lcd day
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA MES
void mes(void){
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Mes:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
mth++; //SI -> incremento mth
if(mth>12) mth=1;
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Mes:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA AÑOS
void anio(void){
convierte_mes();
printf(lcd_putc,"\fConf.Anio:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
year++; //SI -> incremento mth
if(year>99) year=0; //años hasta el 2099, si no me equivoco
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Anio:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION BEEP
void beep(void){
output_high(PIN_B3); //activa zumbador
delay_ms(50);
output_low(PIN_B3); //desactiva zumbador
}
//CONVERSION DE LOS MESES A TEXTO
void convierte_mes(void)//todo con variables globales
{
switch(mth)
{
case 1: strcpy(mestxt,"ene");
break;
case 2: strcpy(mestxt,"feb");
break;
case 3: strcpy(mestxt,"mar");
break;
case 4: strcpy(mestxt,"abr");
break;
case 5: strcpy(mestxt,"may");
break;
case 6: strcpy(mestxt,"jun");
break;
case 7: strcpy(mestxt,"jul");
break;
case 8: strcpy(mestxt,"ago");
break;
case 9: strcpy(mestxt,"sep");
break;
case 10: strcpy(mestxt,"oct");
break;
case 11: strcpy(mestxt,"nov");
break;
case 12: strcpy(mestxt,"dic");
break;
default: strcpy(mestxt,"otr");
}
}
DS1307 QUE NO VA Y NECESITO QUE ME DIGAN POR QUE
////////////////////////////////////////////////////////////////////////////////////
// VsZeNeR'05
// 09/Septiembre/05
// vszener@gmail.com
// Programa: Reloj-Calendario DS1302
// Version: 0.0
//
// Dispositivo: PIC 16F648A Compilador: CCS vs3.227
// Entorno IDE: MPLAB IDE v7.21 Simulador: Proteus 6.7sp3
//
// Notas: Se muestra por pantalla de lcd(LM016L) la fecha y hora obtenida mediante la
// lectura del DS1302. Pudiendose modificar mediante los botones Conf/Ok y up.
// Se utiliza variables globales:
// ·day-> dia ds1302
// ·mth -> mes ds1302
// ·year -> año ds1302
// ·hour -> hora ds1302
// ·min -> minutos ds1302
// ·sec-> segundos ds1302
// ·menu -> variable que muestra opcion del menu configurar
// ·flag -> variable que cuenta hasta 130ms aprox.
// ·var -> ajuste fino para que desborde cada 130ms aprox.
// Se carga el TMR0 con 0 por lo tanto se desborda en 65ms aprox, queremos
// visualizar y restaurar valores cogidos del ds1302 cada 130ms aprox por lo tanto
// utilizamos una variable llamada flag que sera la encargada de dicha tarea.
// Al inicio del programa debe ser configurado el reloj, siendo el boton 'up' el
// encargado de ir moviendose mediante las opciones del menu:hora,minutos,....
// y el boton 'Conf/Ok' el encargado de configurar el reloj(cuando estemos en modo ver
// hora y fecha) o el encargado de salir de la configuracion de las opciones(cuando
// estemos en formato de configurar fecha y hora).
// Tener en cuenta que hay que poner la directiva NOLVP para que el pin B4 sea de
// salida.
// Conexiones: A0 -> RST DS1302
// A1 -> SCLK DS1302
// A2 -> I/O DS1302
// A3 -> Boton 'up'
// A5 -> Boton 'Conf/Ok'
// B0 -> E
// B1 -> RS
// B2 -> RW
// B4 -> D4
// B5 -> D5
// B6 -> D6
// B7 -> D7
// B3 -> Zumbador(beep)
//////////////////////////////////////////////////////////////////////////////////
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#use delay(clock=8000000) /// declara la frecuencia del cristal, era de 8 Mhz
#include <string.h> //PARA USAR LOS STRING (TEXTOS)
#include <stdlib.h>
#fuses HS,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOWDT //comandos para el programador
#use standard_io(A)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#use standard_io(E)
#define use_portb_lcd TRUE //utilizar el port b para lcd
//#define RTC_SCLK PIN_C3 //definimos pin's...
//#define RTC_IO PIN_C5
//#define RTC_RST PIN_C4 //...de conexion de la rtc ds1302
//#include <ds1302.c> //libreria de rtc ds1302
#include <ds1307.c>
#include <flex_lcd.c> //libreria de lcd
///VARIABLES GLOBALES
byte day=1,mth=1,year=9,dow,hour=0,min=0,sec=0; //variabes para ds1302-ds1307
byte menu=0,flag=0,var=2; //variables para menu configurar
//variables GLOBALES para los textos
char mestxt[3]; //le cambio el nombre porque existe una función con el mismo nombre
//char am_pm[2]; //la quito porque el pow no se utiliza
///DEFINICION DE FUNCIONES
void configurar(void);
void horas(void);
void minutos(void);
void dia(void);
void dia_sem(void);
void mes(void);
void anio(void);
void beep(void);
void convierte_mes(void);
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion()
{
if(flag>var){ //¿ya es 130ms aprox?
var--; //SI -> decremento var...
if(var==0)
var=2; //...ajuste fino de 130ms aprox
flag=0; //reset flag para contar 130ms aprox
ds1307_get_date(day,mth,year,dow); //coge dia,mes,año ///
ds1307_get_time(hour,min,sec); //coge hora,minuto,segundo
//rtc_get_date(day,mth,year,dow);
//rtc_get_time(hour,min,sec);
convierte_mes();
printf(lcd_putc,"\f%2d %s %2d\nHora: %2d:%2d:%2d",day,mestxt,year,hour,min,sec); //lcd
}
set_timer0(0); //reset TMR0
flag++; //incremento variable flag
}
///PROGRAMA
void main(void){
set_tris_A (0x28) ;
set_tris_D (0x00) ;
set_tris_B (0x00) ;
set_tris_C (0x04) ;
set_tris_E (0x01) ;
output_low(PIN_A0);
output_low(PIN_A1);
output_low(PIN_D0);
output_low(PIN_D1);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_D4);
output_low(PIN_D5);
output_low(PIN_D6);
output_low(PIN_D7);
enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
set_timer0(0); //carga TMR0
lcd_init(); //inicializa lcd
//rtc_init(); //inicializa rtc
ds1307_init(); //inicializa el ds1307
lcd_putc("Reloj en BCD\nI.E.S.CABANYAL"); //presentacion...
delay_ms(1500);
lcd_gotoxy(1,1);
lcd_putc("\fToni Gellida\nD.P.E.2");
delay_ms(2000); //...inicial
configurar(); //ve a menu configurar
enable_interrupts(GLOBAL); //activadas interrupciones
while(1){ //bucle...
if(input(PIN_A5)==0){ //Si se pulsa Conf....
while(!input(PIN_A5)){} //elimina rebotes
beep();
configurar();
} //ve a menu configurar
} //...infinito
}
///FUNCION CONFIGURAR
void configurar(void){
disable_interrupts(GLOBAL); //desactivadas interrupciones
output_high(PIN_A0); //CONFIGURAR CONTADORES
do{
switch(menu){
case 0: lcd_putc("\fConfigurar\nhoras?"); //horas
output_high(PIN_D0); //CONTADOR HORAS
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
horas();
menu=1; //apunta siguiente opcion
}
break;
case 1: lcd_putc("\fConfigurar\nminutos?"); //minutos
output_low(PIN_D0); //CONTADOR HORAS FUERA
output_high(PIN_D2); //CONTADOR MINUTOS
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
minutos();
menu=2; //apunta siguiente opcion
}
break;
case 2: lcd_putc("\fConfigurar\ndia semana?"); //dia semana/no inc lcd
output_low(PIN_D2); //CONTADOR MINUTOS FUERA
output_high(PIN_D4); //CONTADOR DIA SEM
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia_sem();
menu=3; //apunta siguiente opcion
}
break;
case 4: lcd_putc("\fConfigurar\ndia?"); //dias
output_low(PIN_D4); //CONTADOR DIA SEM FUERA
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
dia();
menu=5; //apunta siguiente opcion
}
break;
case 3: lcd_putc("\fConfigurar\nmes?"); //mes
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
mes();
menu=4; //apunta siguiente opcion
}
break;
case 5: lcd_putc("\fConfigurar\nanio?"); //años
if(!input(PIN_A5)){
while(!input(PIN_A5)){}
beep();
anio();
menu=6; //apunta siguiente opcion
}
break;
case 6: lcd_putc("\fSalir\nconfigurar?"); //salir configuracion
if(!input(PIN_A5)){
menu=7;
beep();
output_low(PIN_A0); //CONTADORES EN FUNCIONAMIENTO
lcd_putc("\fHora\nConfigurada"); //salir configuracion
delay_ms(2500);
}
}
if(!input(PIN_A3)){ //controla el boton up...
while(!input(PIN_A3)){}
menu++;
if(menu>6)
menu=0;
} //...para mostrar menu por lcd
delay_ms(130); //retardo para ver lcd
}while(menu<7);
menu=0; //actualiza indices menu
ds1307_set_date_time(day,mth,year,dow,hour,min,sec);//nueva hora,minuto,...
//rtc_set_datetime(day,mth,year,dow,hour,min);
enable_interrupts(GLOBAL); //activadas interrupciones
set_timer0(0); //carga TMR0
}
///FUNCION CONFIGURA HORAS
void horas(void){
printf(lcd_putc,"\fConf.Horas:\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
hour++; //SI -> incremento hour
output_high(PIN_D1); //CONTADOR UP HORAS
delay_ms(500);
output_low(PIN_D1); //CONTADOR UP HORAS BAJA
if(hour>23) hour=0;
printf(lcd_putc,"\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd hour
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA MINUTOS
void minutos(void){
printf(lcd_putc,"\fConf.Minutos:\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
min++; //SI -> incremento min
output_high(PIN_D3); //CONTADOR UP HORAS
delay_ms(500);
output_low(PIN_D3); //CONTADOR UP HORAS BAJA
if (min>59) min =0;
printf(lcd_putc,"\nHora: %2d:%2d:%2d",hour,min,sec); //muestra por lcd min
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA DIA SEMANA
void dia_sem(void){
printf(lcd_putc,"\fConf.Dia\nsemana"); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
output_high(PIN_D5); //CONTADOR UP DIA SEM
delay_ms(500);
output_low(PIN_D5); //CONTADOR UP DIA SEM BAJA
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA DIAS
void dia(void){
convierte_mes();
printf(lcd_putc,"\fConf.Dias:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
day++; //SI -> incremento day
if(((mth==1)||(mth==3)||(mth==5)||(mth==7)||(mth==8)||(mth==10)||(mth==12))&&(day>31)) day=1;
if((mth==2)&&(day>28)) day=1; //fallaría en los años bisiestos
if((mth==4)||(mth==6)||(mth==9)||(mth==11)&&(day>30)) day=1;
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Dias:\n%2d %s %2d",day,mestxt,year); //muestra por lcd day
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA MES
void mes(void){
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Mes:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
mth++; //SI -> incremento mth
if(mth>12) mth=1;
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Mes:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION CONFIGURA AÑOS
void anio(void){
convierte_mes();
printf(lcd_putc,"\fConf.Anio:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
do{
if(!input(PIN_A3)){ //¿se ha pulsado up?
while(!input(PIN_A3)){} //elimina rebotes
year++; //SI -> incremento mth
if(year>99) year=0; //años hasta el 2099, si no me equivoco
convierte_mes(); //devuelve el resultado en mestxt
printf(lcd_putc,"\fConf.Anio:\n%2d %s %2d",day,mestxt,year); //muestra por lcd
}
}while(input(PIN_A5));
while(!input(PIN_A5)){} //elimina rebotes
}
///FUNCION BEEP
void beep(void){
output_high(PIN_B3); //activa zumbador
delay_ms(50);
output_low(PIN_B3); //desactiva zumbador
}
//CONVERSION DE LOS MESES A TEXTO
void convierte_mes(void)//todo con variables globales
{
switch(mth)
{
case 1: strcpy(mestxt,"ene");
break;
case 2: strcpy(mestxt,"feb");
break;
case 3: strcpy(mestxt,"mar");
break;
case 4: strcpy(mestxt,"abr");
break;
case 5: strcpy(mestxt,"may");
break;
case 6: strcpy(mestxt,"jun");
break;
case 7: strcpy(mestxt,"jul");
break;
case 8: strcpy(mestxt,"ago");
break;
case 9: strcpy(mestxt,"sep");
break;
case 10: strcpy(mestxt,"oct");
break;
case 11: strcpy(mestxt,"nov");
break;
case 12: strcpy(mestxt,"dic");
break;
default: strcpy(mestxt,"otr");
}
}
De todas formas todo está aquí:
http://www.megaupload.com/?d=B0WZKY8X
Muchísimas grácias por su atención, no recurriría a ustedes si no hubiera recurrido a todo lo que se para sanarlo, mi sospecha es que el proteus se ralla
-
Hola Venerable13, yo realicé una aplicación con el DS1307 y no tuve ningún inconveniente, revise este artículo Aquí (http://www.todopic.com.ar/foros/index.php?topic=28166.0)
Saludos.
-
MUCHISIMAS GRACIAS, lo unico que hice fue copiar el diseño del ds con sus resistencias y cambiarlo y voilá, cuenta perfecto, lo que tengo que solucionar es ahora otra cosa, pero la comunicación pic-lcd-ds va correctamente, grácias, grácias, parecía ser q era el proteus con las ressitencias de pull up que no las detectaba bien, es raro, raro porque con 330 no va ok pero si no le pongo valor si va y en el datasheet pone 330!!
-
weno, volvemos a las andadas porque simulado va ok este diagrama, pero a la hora de montarlo nanai, me sale la hora que le pongo por defecto, pero no cuenta el ds1307, qué tengo mal?? NO CUENTA!
(http://s04.imageupper.com/1_t/6/E265668186572845_1.jpg) (http://imageupper.com/i/?S0400010060011E265668186572845)
Esto es lo que tengo puesto, le puse la batería con y como dice en el datasheet, también puse resistencias de pull up de 4k7 y quité los condensadores del reloj de 32768 Hz, he hecho muchas cosas pero ya véis que no va.
os adjunto todo aquí pongo el código
CÓDIGO FUENTE
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////ESTE PROGRAMA UTILZA EL CIRCUITO DS1307 PARA MOSTRAR LA //////////////
//////////HORA EN TIEMPO REAL A TRAVEZ DE UN UNA LCD DE 2 POR 16 CARACTERES/////
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#use delay(clock=4000000) /// declara la frecuencia del cristal
#fuses XT,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#include <flex_lcd.c>
#include "ds1307.c"
#use fast_io(A)
#use fast_io(B)
#use fast_io(C) /// con esta instruccion evitamos que
#use fast_io(D) /// se este configurando cada vez que usamos
#use fast_io(E) /// alguna instruccion de entrada o salida
#byte portc = 7 /// se definen direcciones de memoria
#byte portd = 8
int sec;
int min;
int hrs;
int day;
int month;
int yr;
int dow;
///////////////////////////////////////////////////////////////////////////////////
//////////////////////Comienzo de la funcion principal//////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void main(){
ds1307_init (); ///se inicializa el ds1307
set_tris_a (0xff) ;
set_tris_d (0x00) ;
set_tris_b (0x00) ;
set_tris_c (0x04) ;
set_tris_e (0x01) ;
lcd_init (); /// inicializamos lcd
// Set date FOR - > 15 June 2005 Tuesday
// Set time FOR - > 15:20:55 (9:49:00 am)
ds1307_set_date_time (8, 11, 7, 2, 9, 49, 00); /// se escribe en el displositivo
/// el tiempo deseado
WHILE (1){
delay_ms (100) ;
ds1307_get_date (day, month, yr, dow); /// se obtiene la fecha
ds1307_get_time (hrs, min, sec); /// se obtiene la hora
lcd_gotoxy (1, 2) ;
printf (lcd_putc, " %02d: %02d: %02d ", hrs,min,sec); ///se despliegan los datos
lcd_gotoxy (1, 1) ;
lcd_putc ("XXXXXX") ;
}
}
LIBRERÍA LCD
// flex_lcd.c
// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.
#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
//
#define LCD_RS PIN_B1
#define LCD_RW PIN_B2
#define LCD_E PIN_B0
// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.
#define USE_LCD_RW 1
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif
void lcd_setcursor_vb(short visible, short blink) {
lcd_send_byte(0, 0xC|(visible<<1)|blink);
}
LIBRERÍA DS1307
////////////////////////////////////////////////////////////////////////////////
/// DS1307.C ///
/// Driver for Real Time Clock ///
/// ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
/// used when PIC loses power and DS1307 run from 3V BAT ///
/// - Disable squarewave output ///
/// ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec) Set the date/time ///
/// ///
/// ds1307_get_date(day,mth,year,dow) Get the date ///
/// ///
/// ds1307_get_time(hr,min,sec) Get the time ///
/// ///
////////////////////////////////////////////////////////////////////////////////
#define RTC_SDA PIN_C4
#define RTC_SCL PIN_C3
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL, SLOW)
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);
void ds1307_init(void)
{
BYTE seconds = 0;
i2c_start();
i2c_write(0xD0); // SELECCIONA RTC CON ORDEN WR
i2c_write(0x00); // REG 0
i2c_start();
i2c_write(0xD1); // RD from RTC
seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
i2c_stop();
seconds = bin2bcd(seconds & 0x7F);
delay_us(3);
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x00); // REG 0
i2c_write(seconds); // Start oscillator with current "seconds value
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x07); // Control Register
i2c_write(0x10); // Enable squarewave output pin
i2c_stop();
}
void ds1307_OUT(void){
i2c_start();
i2c_write(0xD0); // WR to RTC
i2c_write(0x07); // WR to RTC
i2c_write(0x10); // Enable squarewave output pin
i2c_stop();
}
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_write(bin2bcd(sec)); // REG 0
i2c_write(bin2bcd(min)); // REG 1
i2c_write(bin2bcd(hr)); // REG 2
i2c_write(bin2bcd(dow)); // REG 3
i2c_write(bin2bcd(day)); // REG 4
i2c_write(bin2bcd(mth)); // REG 5
i2c_write(bin2bcd(year)); // REG 6
//i2c_write(0x80); // REG 7 - Disable squarewave output pin
i2c_write(0x10); // Enable squarewave output pin
i2c_stop();
}
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x03); // Start at REG 3 - Day of week
i2c_start();
i2c_write(0xD1);
dow = bcd2bin(i2c_read() & 0x7f); // REG 3
day = bcd2bin(i2c_read() & 0x3f); // REG 4
mth = bcd2bin(i2c_read() & 0x1f); // REG 5
year = bcd2bin(i2c_read(0)); // REG 6
i2c_stop();
}
void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
i2c_start();
i2c_write(0xD0);
i2c_write(0x00); // Start at REG 0 - Seconds
i2c_start();
i2c_write(0xD1);
sec = bcd2bin(i2c_read() & 0x7f);
min = bcd2bin(i2c_read() & 0x7f);
hr = bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
}
BYTE bin2bcd(BYTE binary_value)
{
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying by 8.
temp >>= 1;
// Isolate the bits for the upper digit.
temp &= 0x78;
// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
-
por cierto a la hora de configurar los puertos con set_trisa y todos cómo debo poner la lcd y el ds1307?? la lcd está como salida, pero son pines d in/out como el ds, o a la hora de configurar los pines en cada libreria ya los configurar con los defines?
muchas grácias a los que me ayuden de esta comunidad tan grande de pics, es una de las mejores
-
os paso el programa original y el que modifiqué yo, lo que hice sólo fue poner el oscilador a XT 4MHZ, poner la lcd en el puerto b, quitar las resistnecias de pull up por programación y la librería lcd ponerle la flex_lcd que va de lujo con otro programa.
os los adjunto, HECHOS CON EL PROTEUS 7.6
muchas grácias!
PROGRAMA Y SIMULACIÓN DS1307 (http://www.megaupload.com/?d=WDSGCMSE) CLICKA AQUÍ
-
ah en la pata VBAT, la dejé tb al aire y al final la acabé conectando a masa y sigue sin ir.
-
Hola venerable13, recuerda que el bit 7 del registro 0 (segundos) es el encargado de habilitar el oscilador del DS1307, la verdad las veces que yo lo he trabajado he realizado directamente la rutina no he utilizado la librería y nunca he tenido problemas, no sé como se habilita este bit en la librería, revisa bien si verdaderamente está habilitado este bit.
saludos.
-
muchísimas grácias, ahora probaré
-
VALE, me cuenta, pero 1 seg son 20 seg, le puse un reloj de 12 mhz para el pic en modo HS por si es de relevancia q lo sepáis. Leí algo en el foro de que a alguien le contaba un seg pero cada 40, así que mientras me contestáis investigo y ya os digo.
-
no he mirado lo de los segundos, pero utilizo la librería de aquí, la utilizada en ds1307 desatado, me paso al tema en lenguaje de programación c, que creo que es más oportuno, ya que en la simulación funciona perfectamente.
-
Bueno puedes hacer una cosa solamente para descartar posibilidades, una cosa que puedes hacer es montar el circuito que haya por el foro en protoboard y intentar descargar el hex en el pic y probar si funciona. Si no funciona podrás deducir que es problema de hardware, si funciona será problema de software.
Un saludo.