Hola, como dije queria mudar un codigo del ds1307 al ds3231 y al parecer estoy mas cerca de ello. el problema es que cuando mando los comandos a la usart del pic a veces me responde y a a veces tengo que repetir los comando varias veces para lograr la respuesta, esto no me pasaba antes con el ds1307. Por ejemplo si mando el comando "hora" por la usart, me tiene que decir la hora del reloj. Aqui el codigo un poco precario. Este es el codigo editado.Ojala me ayuden a resolver este problema.
/* Real time clock using PIC16F887 & DS3231 (DS3232) CCS C code
Read DS3231 RTC datasheet to understand the code!
Internal oscillator used @ 8MHz
http://ccspicc.blogspot.com/
electronnote@gmail.com
*/
////COMANDOS:
///set:22:21 ///pone hour en 22:21
///hour ///muestra la hour
///tiempo muestra el tiempo de activacion grabado en dir 0x00
///ta:10;//ajusta tiempo activacion en eeprom 0x00
////ver ///muestra los programas
///de:1///borra programa 1
//pr1:23:45 ///setea programa en 23:45
///los programas estan en las posiciones:
///t1=0x20, m1=0x21
//t2=0x30, m2=0x31
//t3=0x41, m3=0x041
///t4=0x50, m4=0x51
//t5=0x60; m5=0x61
#include <16F887.h>
#include <stdlib.h>////para poder hacer las conversiones a entero
#include <string.h>
#fuses MCLR NOBROWNOUT NOLVP INTRC_IO PROTECT
#use delay(clock = 4MHz)
#use I2C(master, I2C1, SLOW)
#use rs232(uart1, baud=9600)//usart1 -->ajuste de XMIT y RCV para la USART 1
unsigned int8 i, second, minute, hour, date=1, month=5, year=19,DHora,DMinutos,UHora,UMinutos,TActivacion=10;
int8 t1,t2,t3,t4,t5;
int8 m1,m2,m3,m4,m5;
// CONSTANTES /////////////////////////////////////////////////////////////////
int const lenbuff=32; // Longitud de buffer, Ajustar
// a lo que desees (o te sea posible)
// VARIABLES EN RAM ///////////////////////////////////////////////////////////
int xbuff=0x00; // Índice: siguiente char en cbuff
char cbuff[lenbuff]; // Buffer
char rcvchar=0x00; // último caracter recibido
char strHoras[3];
char strMinutos[3];
char strTa[3];
int1 flagcommand=0; // Flag para indicar comando disponible
int1 EsNumero=0;
int1 EsHora=0;
int8 CantidadNumeros=0;
int1 Activar=0;//me dice si tengo que activar la salida
// Declaración de Funciones ///////////////////////////////////////////////////
void inicbuff(void); // Borra buffer
int addcbuff(char c); // añade caracter recibido al buffer
void echos(char c); // Eco
// Desarrollo de Funciones ////////////////////////////////////////////////////
void inicbuff(void){ // Inicia a cbuff -------------------
int i;
for(i=0;i<lenbuff;i++){ // Bucle que pone a 0 todos los
cbuff[ i ]=0x00; // caracteres en el buffer
}
xbuff=0x00; // Inicializo el indice de siguiente
// caracter
}
int addcbuff(char c)
{ // Añade a cbuff -----------------------
cbuff[xbuff++]=c; // Añade caracter recibido al Buffer
}
// INTERRUPCIONES /////////////////////////////////////////////////////////////
#int_rda
void serial_isr() { // Interrupción recepción serie USART
///restart_wdt();
rcvchar=0x00; // Inicializo caracter recibido
if(kbhit()){ // Si hay algo pendiente de recibir ...
rcvchar=getc(); // lo descargo y ...
addcbuff(rcvchar); // lo añado al buffer y ...
///echos(rcvchar); // hago eco (si procede).
}
}
ImprimirPlantillaReloj(void)
{
printf("%u",DHora);
printf("%u",UHora);
printf(":");
printf("%u",DMinutos);
printf("%u\r\n",UMinutos);//salto de linea
}
ObtenerHoraActual(void)
{
// read current time and date from the RTC chip}
i2c_start(); // Start I2C protocol
i2c_write(0xD0); // DS3231 address
i2c_write(0); // Send register address
i2c_start(); // Restart I2C
i2c_write(0xD1); // Initialize data read
second = i2c_read(1); // Read seconds from register 0
minute = i2c_read(1); // Read minuts from register 1
hour = i2c_read(1); // Read hour from register 2
i2c_read(1); // Read day from register 3 (not used)
date = i2c_read(1); // Read date from register 4
month = i2c_read(1); // Read month from register 5
year = i2c_read(0); // Read year from register 6
i2c_stop();
}
ModificarPrograma(int8 DirHora,DirMin)
{
write_eeprom(DirHora,hour);
delay_ms(5);
write_eeprom(DirMin,minute);
delay_ms(5);
}
int8 LeerTActivacion(void)
{
TActivacion=read_eeprom(0x00);///lee la memoria
if(TActivacion==0xFF)TActivacion=10;///valor por defecto
delay_ms(5);
return(TActivacion);
}
GuardarTActivacion(void)
{
write_eeprom(0x00,TActivacion);///guardo el tiempo de activacion
delay_ms(5);
}
int1 comprobarSiNumero()
{
EsNumero=0;
CantidadNumeros=0;
for (i=4;i<=8;++i)
if((cbuff[i]=='0')||(cbuff[i]=='1')||(cbuff[i]=='2')||(cbuff[i]=='3')||(cbuff[i]=='4')||(cbuff[i]=='5')||(cbuff[i]=='6')||(cbuff[i]=='7')||(cbuff[i]=='8')||(cbuff[i]=='9'))CantidadNumeros=CantidadNumeros+1;
if(CantidadNumeros==4)EsNumero=1;
else EsNumero=0;
return(EsNumero);
}
int1 comprobarTActivacion()
{
CantidadNumeros=0;//inicalizo la cuenta
if((cbuff[4]=='0')||(cbuff[4]=='1')||(cbuff[4]=='2')||(cbuff[4]=='3')||(cbuff[4]=='4')||(cbuff[4]=='5')||(cbuff[4]=='6')||(cbuff[4]=='7')||(cbuff[4]=='8')||(cbuff[4]=='9'))CantidadNumeros=CantidadNumeros+1; if(CantidadNumeros==4)EsNumero=1;
if((cbuff[3]=='0')||(cbuff[3]=='1')||(cbuff[3]=='2')||(cbuff[3]=='3')||(cbuff[3]=='4')||(cbuff[3]=='5')||(cbuff[3]=='6')||(cbuff[3]=='7')||(cbuff[3]=='8')||(cbuff[3]=='9'))CantidadNumeros=CantidadNumeros+1; if(CantidadNumeros==4)EsNumero=1;
if(CantidadNumeros==2) return(1);
else return(0);
}
CargarProgramas(void)//cargo los tiempos de programacion
{
///los programas estan en las posiciones:
///t1=0x20, m1=0x21
//t2=0x30, m2=0x31
//t3=0x41, m3=0x041
///t4=0x50, m4=0x51
//t5=0x60; m5=0x61
t1=read_eeprom(0x20);///lee la memoria
delay_ms(5);
t2=read_eeprom(0x30);///lee la memoria
delay_ms(5);
t3=read_eeprom(0x40);///lee la memoria
delay_ms(5);
t4=read_eeprom(0x50);///lee la memoria
delay_ms(5);
t5=read_eeprom(0x60);///lee la memoria
delay_ms(5);
m1=read_eeprom(0x21);///lee la memoria
delay_ms(5);
m2=read_eeprom(0x31);///lee la memoria
delay_ms(5);
m3=read_eeprom(0x41);///lee la memoria
delay_ms(5);
m4=read_eeprom(0x51);///lee la memoria
delay_ms(5);
m5=read_eeprom(0x61);///lee la memoria
delay_ms(5);
}
MostrarProgramas(void)
{
printf("Los Horarios programados son:\r\n");
if(t1==0xFF) printf("vacio:\r\n");
else
{
DHora=t1/10;///descompongo hora actual
UHora=t1%10;
DMinutos=m1/10;
UMinutos=m1%10;
ImprimirPlantillaReloj();
}
if(t2==0xFF) printf("vacio:\r\n");
else
{
DHora=t2/10;///descompongo hora actual
UHora=t2%10;
DMinutos=m2/10;
UMinutos=m2%10;
ImprimirPlantillaReloj();
}
if(t3==0xFF) printf("vacio:\r\n");
else
{
DHora=t3/10;///descompongo hora actual
UHora=t3%10;
DMinutos=m3/10;
UMinutos=m3%10;
ImprimirPlantillaReloj();
}
if(t4==0xFF) printf("vacio:\r\n");
else
{
DHora=t4/10;///descompongo hora actual
UHora=t4%10;
DMinutos=m4/10;
UMinutos=m4%10;
ImprimirPlantillaReloj();
}
if(t5==0xFF) printf("vacio:\r\n");
else
{
DHora=t5/10;///descompongo hora actual
UHora=t5%10;
DMinutos=m5/10;
UMinutos=m5%10;
ImprimirPlantillaReloj();
}
}
int1 ComprobarSiHora()
{
EsHora=0;
if((comprobarSiNumero()==1)&&(cbuff[6]==':'))
{
strHoras[0]=cbuff[4];
strHoras[1]=cbuff[5];
hour=atol(strHoras);
strMinutos[0]=cbuff[7];
strMinutos[1]=cbuff[8];
minute=atol(strMinutos);
if((hour<24)&&(minute<60))EsHora=1;
else EsHora=0;
}
return(EsHora);
}
ModificarSalida(void)
{
ObtenerHoraActual();//obtiene la hora
if(((t1==hour)&&(m1==minute))||((t2==hour)&&(m2==minute))||((t3==hour)&&(m3==minute))||((t4==hour)&&(m4==minute))|((t5==hour)&&(m5==minute)))Activar=1;
else Activar=0;
while((second<TActivacion)&&(Activar==1))
{
//restart_wdt();
ObtenerHoraActual();//obtiene la hora
output_high(PIN_B3);
delay_ms(1000);///espera que pase el tiempo
}
output_Low(PIN_B3);///salida rele
Activar=0;
}
void SetDateTime(){
// Convert decimal to BCD
minute = ((minute / 10) << 4) + (minute % 10);
hour = ((hour / 10) << 4) + (hour % 10);
date = ((date / 10) << 4) + (date % 10);
month = ((month / 10) << 4) + (month % 10);
year = ((year / 10) << 4) + (year % 10);
// End conversion
// Write data to DS3231 RTC
i2c_start(); // Start I2C protocol
i2c_write(0xD0); // DS3231 address
i2c_write(0);
i2c_write(0); // Reset sesonds and start oscillator
i2c_write(minute); // Write minute value to DS3231
i2c_write(hour); // Write hour value to DS3231
i2c_write(1); // Write day value (not used)
i2c_write(date); // Write date value to DS3231
i2c_write(month); // Write month value to DS3231
i2c_write(year); // Write year value to DS3231
delay_ms(200); // Wait 200ms
}
void DS3231_display(){
// Convert BCD to decimal
second = (second >> 4) * 10 + (second & 0x0F);
minute = (minute >> 4) * 10 + (minute & 0x0F);
hour = (hour >> 4) * 10 + (hour & 0x0F);
date = (date >> 4) * 10 + (date & 0x0F);
month = (month >> 4) * 10 + (month & 0x0F);
year = (year >> 4) * 10 + (year & 0x0F);
// End conversion
DHora=hour/10;///descompongo hora actual
UHora=hour%10;
DMinutos=minute/10;
UMinutos=minute%10;
printf("%u",DHora);
printf("%u",UHora);
printf(":");
printf("%u",DMinutos);
printf("%u\r\n",UMinutos);//salto de linea
}
void main(){
setup_oscillator(OSC_4MHZ); // Set internal oscillator to 8MHz
enable_interrupts(int_rda);
enable_interrupts(global);
set_tris_b (0x00);///todos Salidas
inicbuff(); // Borra buffer al inicio
output_Low(PIN_B3);///salida rele en bajo
CargarProgramas();///Cargo los programas
while(TRUE){
flagcommand=0;///todavia no recibi un comando
inicbuff(); ///borra buffer
ModificarSalida();///modifica la salida segun los programas
delay_ms(1000);///espera que pase el tiempo
if((cbuff[0]=='h')&&(cbuff[1]=='o')&&(cbuff[2]=='r')&&(cbuff[3]=='a'))///comando para ver la hour
{
flagcommand=1; ///me dice que recibio un comando
printf("%s\r\n",cbuff);//salto de linea
printf("La hora Actual es: ");
ObtenerHoraActual();////me da la hora actual
DS3231_display();///muestra la hour
inicbuff(); ///borra buffer
}
if((cbuff[0]=='t')&&(cbuff[1]=='i')&&(cbuff[2]=='e')&&(cbuff[3]=='m')&&(cbuff[4]=='p')&&(cbuff[5]=='o'))///comando para ver tiempo activacion
{
flagcommand=1; ///me dice que recibio un comando
TActivacion=LeerTActivacion();
printf("El tiempo de activacion es: ");
printf("%d\r\n",TActivacion);//salto de lineaTactivacion
inicbuff(); ///borra buffer
}
if(flagcommand==0) inicbuff(); ///borra buffer
delay_ms(1000);
}
}