Hola foro. Veran, tengo un RTC (DS1307) y una memoia serial (24LC512). Ambos, cmo sabran se comunican por i2c. Tambien (y cmo maestro) tengo al 18F2550 usando su i2c por hardware para comunicarme con esos dispositivos esclavos.
Lo que sucede, es que el RTC, su velocidad de trabajo (su linea de clock), alcanza como maximo a 100khz; mientras que la de la memoria llega hasta los 400khz. Pues cmo necesito la mayor velocidad en la memoria y cmo el hardware i2c del pic solo puede generar en su pin SCL una sola frecuncia, termine haciendo dos buses i2c: uno por hardware (para la memoria) y el otro por software (para el RTC). Eso hasta que me dijieron que se puede setear la velocidad o baudaje y ver cmo habia ejemplos que usaban varios #use i2c o rs232, etc (Si, estoy usando el CCS xD (el 4.023 porsiak =D)).
Asique me decidi por probar y, viendo unos ejemplos de lo mismo pero con rs232, pense que podria lograr hacerlo funcionar, ocea: hacar trabajar dos dispositovos (en este caso un RTC y una memoria EEPROM) con diferentes velocidad de trabajo (100khz y 400khz respectivamente segun el parentesis anterior xD) en un solo bus i2c por el hardware de un pic (el 18F2550).
Haciendo este codigo:
#INCLUDE <18F2550.h>
#FUSES XTPLL //Cristal mayor de 4Mhz y usando el PLL interno del pic para modificar aumentarlo/disminuirlo.
#FUSES NOWDT
#FUSES NOPROTECT //No proteger el PIC contra lectura.
#FUSES PUT //El Power Up Timer(PUT) espera unos nilisegundos antes de iniciarse el PIC.
#FUSES NOBROWNOUT //No uso reset automatico cuando se encuentra alguna baja tension especificada.
#FUSES NOLVP //No usare programacion en bajo voltaje.
#FUSES PLL1 //Se divide entre 1 el oscilador(4Mhz) a la entrada del divisor porque el sistema necesita estos 4Mhz para generar 48Mhz para el usb.
#FUSES CPUDIV1 //Esto es para la velocidad conque el PIC trabajara. Esta dividido entre 1, entonces trabajara tambien a 48Mhz.
#USE Delay (Clock = 48 000 000)
#USE RS232 (Baud = 115200, xmit = Pin_C6, rcv = Pin_C7)
#USE I2C (Master, Force_HW, Slow, SDA = Pin_B0, SCL = Pin_B1, Stream = RTC)
#USE I2C (Master, Force_HW, Fast = 400000, SDA = Pin_B0, SCL = Pin_B1, Stream = ExtEEprom)
#INCLUDE "ds1307_modificado.c" //Funciones para el uso del Real Time Clock del integrado DS1307.
#INCLUDE "24512_modificado.c" //Funciones para el uso de la memoria volatil serial eeprom externa 24LC256.
void main(void)
{
unsigned int8 DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA;
unsigned int8 Buffer[256];
unsigned int16 cont, i;
delay_ms(1500);
printf("\r\n\n\n-----------jeremy-----------\r\n\n\n");
ds1307_init(); //inicializamos el RTC (DS1307).
//init_ext_eeprom(); //Inicializo la EEprom externa.
ds1307_set_date_time(29, 5, 8, 4, 11, 8, 0);
cont = 0;
delay_ms(300);
while (TRUE)
{
delay_ms(1000);
/////////////////////////////
ds1307_get_date(DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA);
ds1307_get_time(DS1307HoraA, DS1307MinutoA, DS1307SegundoA);
printf("\n\r%02u/%02u/%02u %u\n\r%02u:%02u:%02u", DS1307DiaA, DS1307MesA, DS1307AnoA, DS1307DSA, DS1307HoraA, DS1307MinutoA, DS1307SegundoA);
printf(" Direcion[%Lu] -> %03u", cont, read_ext_eeprom(cont));
cont++;
//////////////////////////////////
printf("\r\n\nEmpezando lectura secuencial de 24LC512...");
read_ext_eeprom_seq(Buffer, 0, 255);
printf(" Terminada:\r\n");
for (i = 0; i <= 255; i++)
{
printf("%03u ", Buffer[i]);
}
////////////////////////////////////
}
}
Y el problema aqui viene:
Como se ve, lo que es la fecha y hora, esta bien, perfecto. Pero lo que es la lectura secuencial echa a la memoria eeprom... Es una catrastrofe xD! Esos datos son erroneos. Ahora veran porque:
Esta imagen corresponde a un cambio que hice en el codigo anterior y que, ahora si, la lectura a la eeprom (por el modo secuencial (ver datasheet xD)), es correcta, ocea que esos 256 datos leidos si son los que estan ahi. PERO! que esta mal? la fecha y la hora, enrealidad los segundos si avanzan y "el numero del dia" (1 - 7) esta bien tambien, pero en si, esta mal lo que se lee... se entiende?
...Y lo peor de todo... Que lo que cambie del codigo para que pase eso? Pues simplmente los #USE I2C. Ocea que si el "#USE I2C" del RTC esta primero, el es el que funciona bien y la lecuta secuencial de la memoria falla (imagen 1). Si es alraves, es la lectura secuancial de la memoria la que funciona bien y la lectura del dia, mes, año, minuto y segundo del RTC falla (imagen 2).
Algo que agregar esque cuando es "el RTC el que va primero" el modo de lectura secuencial de la memoria falla, PERO su lectura normal o random funciona bien. Que lo muestra un printf del codigo, justo despues de mostrar la fecha y hora del RTC: "Direcion[ x ] -> ABC".
Bueno, espero se entiendo bien todo =D Q dicen? Acaso tiene que ver quien va primero o quien va despues? O si esque eso se puede? Que falta? Q sucede? oO!
Gracias por la leida x)
Un saludo!
PD: Dejo tambien los .c del ds1307 y 24lc512 que cmo bien dicen algo sus nombres, estan algo modificados, aunq enrealidad e agregado solo al 24lc512 lo de lectua secuencial. Bueno, de eso no me preocupo porque eso si funciona bien. Es eso de los #use
xD!