Witajcie.
Muszę się podzielić z wami pewnym spostrzeżeniem układ PCF8563 coś nie działa za prawidłowo. Do tej porty używałem układu PCF8583 i wszystko było pięknie ale cena czyni cuda i zastosowałem PCF8563 i lipa. Nie umiem opanować tego układu, na dobę potrafi opóźniać nawet do 5 minut absurd totalny, dodatkowo co jakiś czas w miejscu godziny pojawia mi się np z godziny 19 robi się godzina 59 z godziny 20 robi się 60 itd. Przeczytałem całego pdf-a układu ze strony philipsa, teoretycznie nie widzę błędu czemu na PCF8583 działało a na tym jest jakaś lipa. Nie umiem zrozumieć co powoduje tak wielkie opóźnienia. Na elektrodzie jest kilka postów na ten temat ale mocno nie precyzyjnych. Używam I2C softwarowego, wszystkie podwieszenia układu zgodnie z ideologią do SDA i SCL 3.3k. Bateryjka z Vcc przez diody wszystko extra. Podtrzymywanie jest ok po zaniku zasilania i ponownym włączeniu jest ok. Tylko, że czasem pojawi się godzina 60 np. Poniżej zamieszczam fragmenty kodu. Proszę pomóżcie bo się zapłaczę siedzę i siedzę itd.
Wartość stałej OPOZNIENIE nic nie wnosi znaczącego.
Proszę umieszczać listingi programów w znacznikach "Code". [c_p]
Muszę się podzielić z wami pewnym spostrzeżeniem układ PCF8563 coś nie działa za prawidłowo. Do tej porty używałem układu PCF8583 i wszystko było pięknie ale cena czyni cuda i zastosowałem PCF8563 i lipa. Nie umiem opanować tego układu, na dobę potrafi opóźniać nawet do 5 minut absurd totalny, dodatkowo co jakiś czas w miejscu godziny pojawia mi się np z godziny 19 robi się godzina 59 z godziny 20 robi się 60 itd. Przeczytałem całego pdf-a układu ze strony philipsa, teoretycznie nie widzę błędu czemu na PCF8583 działało a na tym jest jakaś lipa. Nie umiem zrozumieć co powoduje tak wielkie opóźnienia. Na elektrodzie jest kilka postów na ten temat ale mocno nie precyzyjnych. Używam I2C softwarowego, wszystkie podwieszenia układu zgodnie z ideologią do SDA i SCL 3.3k. Bateryjka z Vcc przez diody wszystko extra. Podtrzymywanie jest ok po zaniku zasilania i ponownym włączeniu jest ok. Tylko, że czasem pojawi się godzina 60 np. Poniżej zamieszczam fragmenty kodu. Proszę pomóżcie bo się zapłaczę siedzę i siedzę itd.
//
#define I2CDir DDRA // Dobrać
#define I2COut PORTA // Dobrać
#define I2CIn PINA // Dobrać
//
#define SDA 6 // Dobrać
#define SCL 7 // Dobrać
//
#define SET_SDA I2COut |= (1 << SDA)
#define CLR_SDA I2COut &= ~(1 << SDA)
//
#define SET_SCL I2COut |= (1 << SCL)
#define CLR_SCL I2COut &= ~(1 << SCL)
//
#define SDA_OUT I2CDir |= (1 << SDA)
#define SDA_IN I2CDir &= ~(1 << SDA)
//
#define SCL_OUT I2CDir |= (1 << SCL)
#define SCL_IN I2CDir &= ~(1 << SDA)
//
#define GET_SDA (I2CIn & (1 << SDA))
//
#define ACK 0
#define NOACK 1
#define OPOZNIENIE 2
void ZapisI2c(unsigned char byte ,unsigned int a_start,unsigned int a_end,
unsigned char device_adres)
{
volatile unsigned int i, j=0x00;
for(i=a_start; i < a_end; i++)
{
i2c_start(); //rozpoczecie transmisji i2c
i2c_send(device_adres); //adres fizyczny pamieci
i2c_send(i); //komórka pamieci
i2c_send(byte); //dana do zapisu
i2c_stop(); //zakończenie transmisji
for(j=0; j<(5*OPOZNIENIE); j++); // Dobrać tą wartość //xxx (53 ms)
}
}
void OdczytI2c(unsigned char adress, unsigned char device_adress,
unsigned int liczba_bajtow, unsigned char *buff)
{
unsigned int i = 0x00;
i2c_start(); //inicjalizacja magistrali
i2c_send(device_adress); //adres fizyczny ukladu do zapisu danej
i2c_send(adress); //adres rejestru od ktorego rozpoczyna sie odczytywanie
for(i=0; i<liczba_bajtow; i++)
{
i2c_start(); //inicjalizacja magistrali
i2c_send(device_adress+1); //adres fizyczny ukladu do odczytu danej
buff[i] = i2c_read(i); //odczyt danej i umieszczenie w kolejnych elementach tablicy
i2c_stop();
}
//xxx for(i=0; i<(5*OPOZNIENIE); i++); // Dobrać tą wartość //xxx (53 ms)
}
unsigned char i2c_read(unsigned char ack) //Odebranie danej z I2C
{
unsigned char bitcount=8, temp = 0;
volatile unsigned int i = 0x00;
SET_SDA;
SDA_IN; // Ustaw SDA na pin wejściowy
do
{
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
SET_SCL;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
temp <<= 1;
if(GET_SDA)
temp++;
CLR_SCL;
}while(--bitcount);
if(ack)
SET_SDA;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
SET_SCL;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
CLR_SCL;
return (temp);
}
void i2c_send(unsigned char byte) //Wysylanie bitu na magistralŕ I2C
{
unsigned char bitcount = 9;
volatile unsigned int i = 0x00;
do
{
CLR_SCL;
if(byte&0x80)
SET_SDA;
else
CLR_SDA;
byte <<=1;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
SET_SCL;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
}while(--bitcount);
CLR_SCL;
}
void i2c_start(void) // Pod AVR OK #!
{
volatile unsigned int i = 0x00;
// Załącz linie Sda i Scl
SDA_OUT;
SCL_OUT;
SET_SDA;
SET_SCL;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
CLR_SDA;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
CLR_SCL;
}
void i2c_stop(void) //Wysłanie sekwencji Stop na I2C
{
volatile unsigned int i = 0x00;
CLR_SDA;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
SET_SCL;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
SET_SDA;
for(i=0; i<OPOZNIENIE; i++); // Dobrać tą wartość //xxx (1 ms)
}
//-------------------------------------------------------------
Wartość stałej OPOZNIENIE nic nie wnosi znaczącego.
Proszę umieszczać listingi programów w znacznikach "Code". [c_p]