Hola amigos, un cordial saludo..
tengo un problema con un RTC ds1307 que estoy configurando con un pic18f45550, trabajo con mplabx en lenguaje C y XC8..
nose que pasa pero proteus me muestra unos errores repetidos infinitas veces:
Spurious SCL transition detected at 0.042980s $II2C DEBUGGE
(I2CMEM TIMING) Start hold time violated. Start was at 544.2708007m, hold time is 600n, min. hold time is 500n.
(I2CMEM TIMING) Stop setup time violated. Clock positive edge was at 544.2667014m, setup time is 500.7n, minimun is 600n.
ES PRIMERA VEZ QUE TRABAJO CON PROTOCOLOS DE COMUNICACION
les paso las librerias y el programa que estoy ejecutando:
este es el .H de i2c
#ifndef I2C_T_H
#define I2C_T_H
void I2C_init(void);
void I2C_waitForIdle(void);
void I2C_start(void);
void I2C_repStart(void);
void I2C_stop(void);
char I2C_read(char);
char I2C_write(char);
#endif
este es el .C de I2C:
#include <xc.h>
#include "i2c_T.h"
void I2C_init(void)
{
TRISB1 = 1; //SCL
TRISB0 = 1; //SDA
SSPADD = 0x09;
SMP = 1;
CKE = 1;
SSPCON2 = 0x00;
SSPCON1bits.WCOL = 0;
SSPCON1bits.SSPOV = 0;
SSPCON1bits.SSPM = 0b1000;
SSPCON1bits.SSPEN = 1;
PSPIF = 0;
BCLIF = 0;
}
void I2C_waitForIdle(void)
{
while ((SSPCON2&0x1F) | R_W) {};
}
void I2C_start(void)
{
I2C_waitForIdle();
SEN = 1;
}
void I2C_repStart(void)
{
I2C_waitForIdle();
RSEN = 1;
}
void I2C_stop()
{
I2C_waitForIdle();
PEN = 1;
}
char I2C_read(char ack)
{
char data;
I2C_waitForIdle();
RCEN = 1;
I2C_waitForIdle();
data = SSPBUF;
I2C_waitForIdle();
if (ack)
ACKDT = 0;
else
ACKDT = 1;
ACKEN = 1;
return data;
}
char I2C_write(char data)
{
I2C_waitForIdle();
SSPBUF = data;
return !ACKSTAT;
}
este es el .H del rtc:
#ifndef RTC_H
#define RTC_H
void ds1307_init(void);
void ds1307_set_date_time(char, char, char, char, char, char, char);
void ds1307_get_date(char *, char *, char *, char *);
void ds1307_get_time(char *, char *, char *);
char bin2bcd(char);
char bcd2bin(char);
#endif
este es el .C del rtc.
#include <xc.h>
#include "i2c_T.h"
#include "rtc.h"
#define _XTAL_FREQ 20000000UL //definicion del cristal para poder utilizar los delays
void ds1307_init(void)
{
char seconds = 0;
I2C_start();
I2C_write(0xD0);
I2C_write(0x00);
I2C_repStart();
I2C_write(0xD1);
seconds = bcd2bin(I2C_read(0));
I2C_stop();
seconds &= 0x7F;
__delay_ms(1);
I2C_start();
I2C_write(0xD0);
I2C_write(0x00);
I2C_write(bin2bcd(seconds));
I2C_stop();
__delay_ms(1);
I2C_start();
I2C_write(0xD0);
I2C_write(0x07);
I2C_write(0x10);
I2C_stop();
}
void ds1307_set_date_time(char day, char mth, char year, char dow, char hr, char min, char sec)
{
sec &= 0x7F;
hr &= 0x3F;
I2C_start();
I2C_write(0xD0);
I2C_write(0x00);
I2C_write(bin2bcd(sec));
I2C_write(bin2bcd(min));
I2C_write(bin2bcd(hr));
I2C_write(bin2bcd(dow));
I2C_write(bin2bcd(day));
I2C_write(bin2bcd(mth));
I2C_write(bin2bcd(year));
I2C_write(0x90);
I2C_stop();
}
void ds1307_get_date(char *day, char *mth, char *year, char *dow)
{
I2C_start();
I2C_write(0xD0);
I2C_write(0x03);
I2C_repStart();
I2C_write(0xD1);
*dow = bcd2bin(I2C_read(1) & 0x7F);
*day = bcd2bin(I2C_read(1) & 0x3F);
*mth = bcd2bin(I2C_read(1) & 0x1F);
*year = bcd2bin(I2C_read(0) & 0x3F);
I2C_stop();
}
void ds1307_get_time(char *hr, char *min, char *sec)
{
I2C_start();
I2C_write(0xD0);
I2C_write(0x00);
I2C_repStart();
I2C_write(0xD1);
*sec = bcd2bin(I2C_read(1) & 0x7F);
*min = bcd2bin(I2C_read(1) & 0x7F);
*hr = bcd2bin(I2C_read(0) & 0x3F);
I2C_stop();
}
char bin2bcd(char binary_value)
{
char temp = binary_value / 10;
return (binary_value - temp * 10) + (temp << 4);
}
char bcd2bin(char bcd_value)
{
return((bcd_value >> 4 ) * 10 + (bcd_value & 0x0F));
}
AHORA EN MI PROGRAMA PRINCIPAL:
/*CONFIGURACION INTERRUPCION EN RA4 por timer0 Y EN RB2 PARA EL SOUT DEL RTC*/
T0CON=0xF8; // registro TIMER0
INTCONbits.TMR0IE=1; // habilitamos interrupcion del timer0
INTCONbits.TMR0IF=0; // inicializamos la bandera en 0
RCONbits.IPEN = 1; // Activa modo alta y baja prioridad
INTCONbits.GIEL = 1;// permitimos interrupciones de baja prioridad (Global Interrupt Enable Low)
INTCONbits.GIEH=1; //alto en ultima compuerta
TMR0=0xFF; // le damos el valor inical al timer
INTCON2bits.INTEDG2 = 1;//configura interrupcion por flanco de subida para la interrupcion en RB2
INTCON3bits.INT2IE=1; // activa la interrupción externa por flanco del pin RB2
INTCON3bits.INT2IP=0; // selecciona la interrupción de baja prioridad del pin RB2
/*CONFIGURACION INTERRUPCION EN RA4 por timer0 Y EN RB2 PARA EL SOUT DEL RTC*/
LCD_init();
ADC_init(0x09 | ADC_10bit | ADC_FOSC32 | ADC_02TAD ); // 6 entradas analogicas
I2C_init();
ds1307_init();
LCD_clear();
ACA HABILITTO LAS INTERRUPCIONES E INICIALIZO EL I2C y ds1307
luego tengo esta funcion de interrupcion..
void interrupt low_priority isr1()
{
if(INT2IF)
{
ds1307_get_date(&day, &month, &yr, &dow);
ds1307_get_time(&hrs, &min, &sec);
sprintf(T,"%02d:%02d:%02d %02d/%02d", hrs, min, sec, day, month);
LCD_gotoxy(0,4);
LCD_puts(T);
INT2F = 0;
}
}
bueno eso es basicamente lo que tengo, el mplabx copila bien, pero luego en proteus me arroja esos errores y en la pantalla imprime unos simbolos raros, y nisiquiera en la poscion que le digo...
otra cosa... tambien tengo otra libreria para manejar la eeprom del pic... con estas tres librerias y lo que les puse del programa prncipal, la memoria del programa paso de 33% a 68% =S
una ultima cosa, en proteus segun los apuntes que tengo sobre simulaciones con rtc hay que colocar un I2C DEBUGGER, y tambien aparecia alli conectado un 24lc512 que enrealidad no se lo que hace, lo que si se, es que si lo quito solo me sale el primer error:
Spurious SCL transition detected at 0.042980s $II2C DEBUGGE
adjunto una imagen de una captura de una simulación que me pasaron con un rtc
agradecería mucho su ayuda... siento que estoy un poco perdido....gracias