TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Arkaedus en 19 de Junio de 2015, 06:44:25
-
Hola me gustaria saber como hacer un reloj con un ds1307 ya que el compilador PIC CCS Compiler no viene con driver ds1307. Así que necesitaré el codigo del driver DS1307
Y me gustaría que se programar la fecha y la hora con unos pulsadores que aumenten o disminuyan la hora, minutos, .... etc
Es decir deberia guardar los datos en la eeprom, no?
Alguien podria echarme una mano porque en esto que estoy perdido y para un proyecto que quiero hacer necesito poder introducir esto.
-
Primero que estas pidiendo todo, cosa que aqui en el foro creo que el ds1307 es uno de los RTC mas tratados y que si buscas vas a encontrar una libreria ( driver)
O de ultima portar alguna que encontres por internet.
Obviamente podes incrementar/decrementar horas,minutos,segundos para setear la hora.
El datasheet del DS1307 explica cuales son los comandos que deben enviarse para:
escribir 1 solo byte
escribir multiples bytes
leer 1 solo byte
leer multiples bytes
Y tambien te indica todos los registros que posee el DS1307
A partir de ahi es facil crear una libreria, por ejemplo para leer creo que era:
i2c_start();
i2c_write(direccion_ds1307 + write); //Esto contiene bit de R/W si no mal recuerdo , aca escritura
i2c_write(direccion_registro);
i2c_start();
i2c_write(direccion_ds1307 +read); //Esto contiene bit de R/W si no mal recuerdo, aca lectura
dato = i2c_read(); // dato es lo que contiene la direccion de memoria (direccion_registro) del DS1307
i2c_stop();
Si lees el datasheet vas a ver que esta igual que la operacion de lectura
Con respecto a tu duda
Es decir deberia guardar los datos en la eeprom, no?
No, no hace falta, el DS1307 tiene unos registros que contienen la hora, al momento de querer saber que hora es, directamente lo lees del DS1307.
Si queres guardar/cambiar la hora, entonces escribis el registro del DS1307 con la nueva hora asi el RTc sigue contando desde ese punto.
Si quisieras cambiar la hora lo que harias es:
Leer la hora del DS1307
Que el usuario mediante botones la cambie ( me refiero tener guardado localmente en la RAM los valores mientras se cambian)
Finalizado todos cambios ( hora,minuto,segundos ) por mas que alguno se deje igual. Actualizas los datos en el DS1307
Fin
-
A ver es que yo he hehco un proyecto y el problema que tengo es que me salen simbolos raros al cabo de un tiempo encendido con el codigo que he puesto para el ds_1307 y no encuentro el problema, la pantalla LCD pro la que se "imprime" los datos es un 4 lineas 20 caracteres LM044L simulada en proteus. Uso el compilador CCS en C llamado PCW. Y como simulador Proteus 7.7 SP2
Alguien podria ayudarme, seria muy amable por su parte
Este es el driver del LCD:
// Flex_LCD420.c
#use delay(clock=4000000)
// These pins are for my Microchip PicDem2-Plus board,
// which I used to test this driver.
// An external 20x4 LCD is connected to these pins.
// Change these pins to match your own board's connections.
#define LCD_DB4 PIN_B0
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_B2
#define LCD_DB7 PIN_B3
#define LCD_RS PIN_D6
//#define LCD_RW PIN_E1
#define LCD_E PIN_D7
/*
// To prove that the driver can be used with random
// pins, I also tested it with these pins:
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_C5
#define LCD_DB7 PIN_B5
#define LCD_RS PIN_E2
#define LCD_RW PIN_B2
#define LCD_E PIN_D6
*/
// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line. Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD. It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit. Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
//#define USE_RW_PIN 1
// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54
// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines(or more)
int8 lcd_line;
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Set mode: 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_RW_PIN
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_us(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);
delay_us(1);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_RW_PIN
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_RW_PIN
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_RW_PIN
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;
lcd_line = 1;
output_low(LCD_RS);
#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif
output_low(LCD_E);
// Some LCDs require 15 ms minimum delay after
// power-up. Others require 30 ms. I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);
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 50 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_RW_PIN
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
switch(y)
{
case 1:
address = LCD_LINE_1_ADDRESS;
break;
case 2:
address = LCD_LINE_2_ADDRESS;
break;
case 3:
address = LCD_LINE_3_ADDRESS;
break;
case 4:
address = LCD_LINE_4_ADDRESS;
break;
default:
address = LCD_LINE_1_ADDRESS;
break;
}
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
lcd_line = 1;
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1, ++lcd_line);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_RW_PIN
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
Este es el codigo que uso para el ds_1307 (hay que decir que este codigo esta dentro del programa principal)
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)
//PROTOTIPOS///////////////////////////////////////////////////////////////////
void leer_reloj();
void pulse_out(int);
short test_reloj();
void inicializa_reloj();
void ajusta_reloj();
//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
//-----------------------------------------------------------------------------
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();
}
Si no es problema de esto sera problema de escritura, o no sé ya. Estoy muy apurado proque no veo el error y me gustaría sacarlo adelante este proyecto.
Adjunto el proyecto por si alguien me peude ayudar o echar una mano con la solución al problema de que con el tiempo encendido salen interrogantes momentaneamente en la pantalla de info y luego vuelve a la normalidad ( como si el Ds_1307 se volviese loco, solo ocurre en la primera linea del LCD que es donde aparecen lso datos del DS_1307 y claro la segunda linea cambia dependiendo de la primera linea pues se basa elñ programa en encender unasa salidas segun la hora)
-
Hola Arkaedus te paso mi proyecto entero que hice con el DS1307 con lo que tuve mas problemas fue con guardar en la eprom y luego leerla pero en el proyecto que te paso quedo resuelto.
http://www.ucontrol.com.ar/forosmf/proyectos-con-pic/reloj-alarmas-para-escuelas/
Saludos!
Nota: Con respuesta a este otro tema: http://www.todopic.com.ar/foros/index.php?topic=39889.0;topicseen
-
Buenos días compañeros:
Mi problema con el DS1307 no es para que arranque sino para que guarde el día del mes, los demás datos como hora, mes, año permanecen intactos al retirar la alimentación de 5V.
He intentado de todo: revisé las resistencias pull-up, medir el voltaje de la batería, cambiar el integrado y cambiar la librería (estoy usando la de acá del foro) pero todas dan el mismo problema. ¿Alguien lo ha tenido?
Adjunto código y librería:
CÓDIGO
#include <16F873.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#BYTE TRISD=0x88
#BYTE PORTD=0x08
#include <math.h>
#include <ds1307todopic.c>
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)
byte day=31;
byte dow=7;
byte year=15;
byte mth=12;
byte hr=23;
byte prehr=0,min=59,copia=0, TIMESET=0;
byte contaseg=0, estado=1,mipre=0,uni=0,dec=0,buni=0,bdec=0,grup1=0,grup2=0,lectoconta=0, daycarrier=0;
byte sec=0;
int1 turnseg=0,setling=0,leeds=0;
byte const num[10]={238,6,220,158,54,186,250,14,254,62};
#define DATA PIN_A1
#define CLOCK PIN_A0
#define RAYA PIN_C1
#define SEGUNDERO PIN_C0
#define HAB1 PIN_C2
#define HAB2 PIN_C5
#define HAB3 PIN_C6
#define HAB4 PIN_C7
#define TS PIN_B0
#define MINSET PIN_B2
#define HORASET PIN_B1
#define DIASET PIN_B3
#define SETMES PIN_B4
#define ANOSET PIN_B5
#define AM PIN_B6
#define PM PIN_B7
//#define DEBUG3 PIN_C3
//#define DEBUG4 PIN_C4
void escribir(int8 aux){ ////////FUNCION ESCRIBIR PARA LOS REGISTROS DE DESPLAZAMIENTO
int i;
for(i=0;i<8;i++)
{
if(bit_test(aux, i)==0)
{
output_low (DATA);
output_low (CLOCK);
output_high(CLOCK);
}
if(bit_test(aux,i)==1)
{
output_high(DATA);
output_low (CLOCK);
output_high(CLOCK);
}
}
} ///////////////////////////////FIN DE FUNCION ESCRIBIR
void bin_bcd(){ /////////////////SEPARA LOS DATOS PARA IMPRIMIR
if (hr==0){
prehr=12;
output_low (PM); //PM OFF
output_high (AM); //AM ON
}
else if (hr==12){
prehr=hr;
output_low (AM); // AM OFF
output_high (PM); //PM ON
}
else if (hr>12){
prehr=hr-12;
output_low (AM); // AM OFF
output_high (PM); //PM ON
}
else{
prehr=hr;
output_low (PM); //PM OFF
output_high (AM); //AM ON
}
if (TIMESET==1){
grup2=20;
grup1=year;
}
if ((TIMESET==2)||(estado==2)){
grup2=day;
grup1=mth;
//grup1=daycarrier;
}
if ((TIMESET==3)||(estado==1)){
grup2=prehr;
grup1=min;
}
copia=grup1;
dec= copia/10;
copia= copia%10;
uni=copia;
copia=grup2;
bdec= copia/10;
copia= copia%10;
buni=copia;
}
void mostrar(){
bin_bcd();
output_low(HAB4);
escribir(num[uni]);
output_high(HAB1);
if (leeds==0){
delay_ms(2);
}
if (leeds==1){
ds1307_get_date(day,mth,year,dow);
}
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribir(num[dec]);
delay_us(10);
output_high(HAB2);
if (leeds==1){
ds1307_get_time(hr,min,sec);
leeds=0;
}
if (leeds==0){
delay_ms(2);
}
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribir(num[buni]);
delay_us(10);
output_high(HAB3);
delay_ms(2);
if((bdec>0))
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribir(num[bdec]);
delay_us(10);
output_high(HAB4);
delay_ms(2);
}
else
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
delay_ms(2);
}
}
#INT_TIMER1
void temp1_isr() {
disable_interrupts(INT_TIMER1);
if (mipre==2){
turnseg=!turnseg;
mipre=0;
}
if (contaseg==20){
contaseg=0;
estado++;
}
if (estado>2){
estado=1;
}
if (lectoconta==0){
lectoconta=20;
leeds=1;
}
contaseg++;
mipre++;
lectoconta--;
set_timer1(3036);
enable_interrupts(INT_TIMER1);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main(){ //INICIO DEL PROGRAMA
set_tris_C(0b00000000);
PORTD=0b00000000;
delay_ms(1000);
disable_interrupts(global);
output_low (SEGUNDERO);
output_low (RAYA);
ds1307_init(DS1307_ALL_DISABLED); //INICIALIZACIÓN DEL DS1307
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
set_timer1(3036);
disable_interrupts(INT_TIMER1);
ds1307_get_date(day,mth,year,dow);//LECTURA INICIAL
ds1307_get_time(hr,min,sec); //LECTURA INICIAL
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
while (1){
mostrar();
if (input(TS)==0){
while (input(TS)==0){
mostrar();
}
TIMESET++;
if (TIMESET>3){
TIMESET=0;
}
}
if (TIMESET>0){ ///INICIO DEL DE LA CONFIGURACIÓN DEL TIEMPO
disable_interrupts(INT_TIMER1);
setling=1;
estado=0;
leeds=0;
if (TIMESET==1){
output_low(SEGUNDERO);
output_low(RAYA);
}
if (TIMESET==2){
output_high (RAYA);
output_low (SEGUNDERO);
}
if (TIMESET==3){
output_high (SEGUNDERO);
output_low (RAYA);
}
if ((input(HORASET)==0)&&(TIMESET==3)){//INICIO CONFIGURACION DE LA HORA
while(input(HORASET)==0){
mostrar();}
if (hr>=23){
hr=0;
}
else{
hr++;
}
}//////////////////FINAL CONFIGURACIÓN DE LA HORA
if((input(MINSET)==0)&&(TIMESET==3)){ //INICIO CONFIGURACIÓN DE LOS MINUTOS
while(input(MINSET)==0){
mostrar();}
if (min>=59){
min=0;
}
else{
min++;
}
} //////////////////FINAL CONFIGURACIÓN DE LOS MINUTOS
if ((input(DIASET)==0)&&(TIMESET==2)){//////INICIO CONFIGURACION DEL DÍA
while(input(DIASET)==0){
mostrar();
}
if (mth==1||mth==3||mth==5||mth==7||mth==8||mth==10||mth==12){
if(day>=31){
day=1;
}
else{
day++;
}
}
else if (mth==4||mth==6||mth==9||mth==11){
if(day>=30){
day=1;
}
else{
day++;
}
}
else if (mth==2){
if(year==16||year==20||year==24||year==28||year==32||year==36||year==40||year==44){
if (day==29){
day=1;
}
else{
day++;
}
}
else if (day==28){
day=1;
}
else{
day++;
}
}
}//////////////////////////FINAL DE CONFIGURACIÓN DEL DÍA
if ((input(SETMES)==0)&&(TIMESET==2)){////INICIO DE CONFIGURACIÓN DEL MES
while(input(SETMES)==0){
mostrar();
}
if (mth>=12){
mth=1;
}
else{
mth++;
}
} //////////////////FIN DE CONFIGURACIÓN DEL MES
if ((input(ANOSET)==0)&&(TIMESET==1)){///INICIO CONFIGURACION DEL AÑO
while(input(ANOSET)==0){
mostrar();
}
if (year>=99){
year=1;
}
else{
year++;
}
}//////////////////////FINAL DE CONFUGURACIÓN DEL AÑO
}////////////////////////////FINAL DEL CICLO IF DE LA CONFIGURACIÓN DEL TIEMPO
if ((TIMESET==0)&&(setling==1)){
setling=0;
sec=0;
daycarrier=day;
delay_ms(200);
ds1307_set_date_time(day,mth,year,dow,hr,min,sec);
delay_ms(200);
estado=1;
set_timer1(3036);
enable_interrupts(INT_TIMER1);
}
if (TIMESET==0){
if ((estado==1)&&(turnseg==1)){
output_high(SEGUNDERO);
}
else {
output_low (SEGUNDERO);
}
if (estado==2){
output_high (RAYA);
}
else{
output_low (RAYA);
}
}
}
}//FINAL DEL PROGRAMA
LIBRERÍA
///////////////////////////////////////////////////////////////////////////////////////
/// DS1307.C ///
/// Driver for Real Time Clock ///
/// modified by Redpic 08/2006 ///
/// http://picmania.garcia-cuervo.com ///
/// ///
/// void ds1307_init(val) ///
/// - Enable oscillator without clearing the seconds register ///
/// used when PIC loses power and DS1307 run from 3V BAT ///
/// - Config Control Register with next parameters: ///
/// DS1307_ALL_DISABLED All disabled ///
/// DS1307_OUT_ON_DISABLED_HIHG Out to Hight on Disable Out ///
/// DS1307_OUT_ENABLED Out Enabled ///
/// DS1307_OUT_1_HZ Freq. Out to 1 Hz ///
/// DS1307_OUT_4_KHZ Freq. Out to 4.096 Khz ///
/// DS1307_OUT_8_KHZ Freq. Out to 8.192 Khz ///
/// DS1307_OUT_32_KHZ Freq. Out to 32.768 Khz ///
/// ///
/// Example init: ///
/// ds1307_init(DS1307_ALL_DISABLED); ///
/// ds1307_init(DS1307_OUT_ENABLED | DS1307_OUT_1_HZ); ///
/// ///
/// void ds1307_set_date_time(day,mth,year,dow,hour,min,sec) - Set the date/time ///
/// ///
/// void ds1307_get_date(day,mth,year,dow) - Get the date ///
/// ///
/// void ds1307_get_time(hr,min,sec) - Get the time ///
/// ///
/// char ds1307_read_nvram_byte(char addr) - Read byte in address ///
/// ///
/// void ds1307_write_nvram_byte(char addr, char value) - Write byte in address ///
/// ///
/// void ds1307_get_day_of_week(char* ptr) - Get string Day Of Week///
/// ///
/// If defined USE_INTERRUPTS all functions disable Global Interrupts on starts and ///
/// enable Global on ends else usar can do it hiself ///
/// ///
///////////////////////////////////////////////////////////////////////////////////////
#ifndef RTC_SDA
#define RTC_SDA PIN_C4
#define RTC_SCL PIN_C3
#endif
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
#define DS1307_ALL_DISABLED 0b00000000 // All disabled
#define DS1307_OUT_ON_DISABLED_HIHG 0b10000000 // Out to Hight on Disable Out
#define DS1307_OUT_ENABLED 0b00010000 // Out Enabled
#define DS1307_OUT_1_HZ 0b00000000 // Freq. Out to 1 Hz
#define DS1307_OUT_4_KHZ 0b00000001 // Freq. Out to 4.096 Khz
#define DS1307_OUT_8_KHZ 0b00000010 // Freq. Out to 8.192 Khz
#define DS1307_OUT_32_KHZ 0b00000011 // Freq. Out to 32.768 Khz
#define Start_user_address_nvram 0x08
#define End_user_address_nvram 0x3f
char days_of_week[7][11]={"Lunes\0","Martes\0","Miércoles\0","Jueves\0","Viernes\0","Sábado\0","Domingo\0"};
byte ds1307_bin2bcd(byte binary_value);
byte ds1307_bcd2bin(byte bcd_value);
void ds1307_init(int val){
byte seconds = 0;
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_start();
i2c_write(0xD1);
seconds = ds1307_bcd2bin(i2c_read(0));
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write(ds1307_bin2bcd(seconds));
i2c_start();
i2c_write(0xD0);
i2c_write(0x07);
i2c_write(val);
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_set_date_time(byte day, byte mth, byte year, byte dow, byte hr, byte min, byte sec){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write(ds1307_bin2bcd(sec));
i2c_write(ds1307_bin2bcd(min));
i2c_write(ds1307_bin2bcd(hr));
i2c_write(ds1307_bin2bcd(dow));
i2c_write(ds1307_bin2bcd(day));
i2c_write(ds1307_bin2bcd(mth));
i2c_write(ds1307_bin2bcd(year));
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_get_date(byte &day, byte &mth, byte &year, byte &dow){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(0x03);
i2c_start();
i2c_write(0xD1);
dow = ds1307_bcd2bin(i2c_read() & 0x7f);
day = ds1307_bcd2bin(i2c_read() & 0x3f);
mth = ds1307_bcd2bin(i2c_read() & 0x1f);
year = ds1307_bcd2bin(i2c_read(0));
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_get_time(byte &hr, byte &min, byte &sec){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_start();
i2c_write(0xD1);
sec = ds1307_bcd2bin(i2c_read() & 0x7f);
min = ds1307_bcd2bin(i2c_read() & 0x7f);
hr = ds1307_bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
char ds1307_read_nvram_byte(char addr){
char retval;
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(addr);
i2c_start();
i2c_write(0xD1);
retval = i2c_read(0);
i2c_stop();
return(retval);
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_write_nvram_byte(char addr, char value){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(addr);
i2c_write(value);
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_get_day_of_week(char* ptr){
byte lday;
byte lmonth;
byte lyr;
byte ldow;
ds1307_get_date(lday,lmonth,lyr,ldow);
sprintf(ptr,"%s",days_of_week[ldow]);
}
///////////////////////////////////////////////////////////////////////////////
byte ds1307_bin2bcd(byte binary_value){
byte temp;
byte retval;
temp = binary_value;
retval = 0;
while(1){
if(temp >= 10){
temp -= 10;
retval += 0x10;
}else{
retval += temp;
break;
}
}
return(retval);
}
byte ds1307_bcd2bin(byte bcd_value){
byte temp;
temp = bcd_value;
temp >>= 1;
temp &= 0x78;
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
Saludos y gracias!
-
la baterria de 3v normalmente la cr2032 o otra sirve se usa para no perder la hora
-
Pues tiene conectada su batería de 3V... Aun sigo sin poder resolver. Me he fijado que lo mismo pasa con la variable dia de la semana. :?
-
Holaq que tal, tengo un dilema cuando modulo el programa en proteus la fecha no cambia solo se queda en lunes y no se como arreglarlo, ya lo intente de diferentes maneras