@Regan_3000
Czy któraś z sugestii powyżej rozwiązała Twój problem?
Mam identyczny problem. (Jestem na Atmedze16/8MHz)
Pisze w C, zegar działa poprawnie gdyż obsersuję na oscyloskopie transmisję danych (zauważam zmianę dziesiątek sekund/sekund/minut w bcd na linii SDA), zapewne coś siedzi w kodzie.
(PCF8583 podpięcie: SCL,SDA -> przez rezystory podciągające 5,6k do Atmegi16 /wykorzystuję twi Atmegi/, A0->masa, /INT -> N/C, OSCI i OSCO do kwarcu 32kHz, dodatkowo OSCI przez 33pF do Vcc /5V/ )
plik "i2c.h":
#include <avr/io.h>
#define SCL PC0
#define SDA PC1
#define uDLY 5
#define SDA_0 PORTC&=~_BV(SDA)
#define SDA_1 PORTC|=_BV(SDA)
#define SCL_0 PORTC&=~_BV(SCL)
#define SCL_1 PORTC|=_BV(SCL)
#define R_SDA bit_is_set(PINC,7)
//unsigned char i2cflag;
void i2c_delay(unsigned int p);
void i2c_writebyte(unsigned char byte);
unsigned char i2c_readbyte(void);
void i2c_write(unsigned char deviceaddr, unsigned char address, unsigned char data);
unsigned char i2c_read(unsigned char deviceaddr, unsigned char address);
plik "i2c.c":
#include "i2c.h"
void i2c_delay(unsigned int p)
{
unsigned int i;
unsigned char j;
for(i=0;i<p;i++)
for (j=0;j<10;j++);
}
void i2c_writebyte(unsigned char byte)
{
unsigned char i;
for (i=0;i<8;i++) {
if (byte>127) SDA_1; else SDA_0;
i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY);
SCL_0; i2c_delay(uDLY);
byte<<=1;
}
SDA_1; i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY);
DDRC&=~_BV(DDC4);
//if (R_SDA) i2cflag=0; else i2cflag=1;
SCL_0; i2c_delay(uDLY);
DDRC|=_BV(DDC4);
}
unsigned char i2c_readbyte(void)
{
unsigned char i,byte=0;
DDRC&=~_BV(DDC4);
for (i=0;i<8;i++) {
byte<<=1;
if (R_SDA) byte|=1;
i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY);
SCL_0; i2c_delay(uDLY);
}
DDRC|=_BV(DDC4);
SDA_1; i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY);
SCL_0; i2c_delay(uDLY);
return(byte);
}
void i2c_write(unsigned char deviceaddr, unsigned char address, unsigned char data)
{
unsigned char byte;
SDA_1; SCL_1; i2c_delay(uDLY);
SDA_0; i2c_delay(uDLY);
SCL_0; i2c_delay(uDLY);
byte=deviceaddr;
i2c_writebyte(byte);
byte=address;
i2c_writebyte(byte);
byte=data;
i2c_writebyte(byte);
SDA_0; i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY);
SDA_1; i2c_delay(uDLY);
for (byte=0;byte<255;byte++) {
SCL_0; i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY);
}
}
unsigned char i2c_read(unsigned char deviceaddr, unsigned char address)
{
unsigned char byte;
SDA_1; SCL_1; i2c_delay(uDLY);
SDA_0; i2c_delay(uDLY); //
SCL_0; i2c_delay(uDLY); //
byte=deviceaddr;
i2c_writebyte(byte);
byte=address;
i2c_writebyte(byte);
SCL_1; i2c_delay(uDLY);
SDA_0; i2c_delay(uDLY);
SCL_0; i2c_delay(uDLY);
byte=deviceaddr+1;
i2c_writebyte(byte);
byte=i2c_readbyte();
SDA_0; i2c_delay(uDLY);
SCL_1; i2c_delay(uDLY); //
SDA_1; i2c_delay(uDLY); //
return(byte);
}
przykładowy main.c:
#include <avr/io.h>
#include <avr/delay.h>
#include <stdlib.h>
#include "i2c.h"
#include "lcd.h"
char bufor[10],bufor2[10];
#define RTCAddress 0xa0
#define ControlReg 0
void SetRTC (unsigned char *p)
{ unsigned char i;
for (i=1;i<=6;i++)
i2c_write(RTCAddress, i, *p++);
i2c_write(RTCAddress, ControlReg, 0x00);
}
void GetRTC (unsigned char *p)
{ unsigned char i;
for (i=1;i<=6;i++)
*p++=(i2c_read(RTCAddress, i));
i2c_write(RTCAddress, ControlReg, 0x00);
}
void i2c_init()
{
DDRC|=_BV(SDA);
DDRC|=_BV(SCL);
}
int main(void)
{
unsigned char RtcBuffer[6];
unsigned char hours, minutes, seconds, hundredths;
unsigned char year, month, day;
i2c_init();
/* sample how to set clock (see PDF for registers)
RtcBuffer[0] = 0x78;
RtcBuffer[1] = 0x56;
RtcBuffer[2] = 0x34;
RtcBuffer[3] = 0x12;
RtcBuffer[4] = 0x30;
RtcBuffer[5] = 0x12;
SetRTC (&RtcBuffer);
*/
lcdinit();
lcdcls();
while (1)
{
GetRTC(RtcBuffer);
hours=10*(RtcBuffer[3] >> 4 & 0x3) + (RtcBuffer[3] & 0xf);
minutes=10*(RtcBuffer[2] >> 4) + (RtcBuffer[2] & 0xf);
seconds=10*(RtcBuffer[1] >> 4) + (RtcBuffer[1] & 0xf);
hundredths=10*(RtcBuffer[0] >> 4) + (RtcBuffer[0] & 0xf);
year=99;
month=10*(RtcBuffer[5] >> 4 & 0x1) + (RtcBuffer[5] & 0xf);
day=10*(RtcBuffer[4] >> 4 & 0x3) + (RtcBuffer[4] & 0xf);
itoa(seconds,bufor,10);
lcdxy(0,0);
lcdwrite(bufor);
itoa(hundredths,bufor,10);
lcdxy(0,0);
lcdwrite(bufor);
itoa(month,bufor,10);
lcdxy(0,0);
lcdwrite(bufor);
itoa(day,bufor,10);
lcdxy(0,0);
lcdwrite(bufor);
itoa(year,bufor,10);
lcdxy(0,0);
lcdwrite(bufor);
}
return 0;
}
Czytam o tym i2c już trochę, na forum są podobne tematy ale nikt nie pisze jak to rozwiązać, i w czym siedzi problem. Nie mogę wymyślić co jest nie tak, a czas nagli. Gdyby ktoś miał chwilkę czasu aby sprawdzić, lub chociaż naprowadzić mnie na właściwy trop byłbym niezmiernie wdzięczny
//biblioteki ściągnąłem chyba z forum... ale szukałem tego tematu i nie potrafię na niego trafić ponownie