Отговори на тема  [ 11 мнения ] 
Проблем с четенето на RTC DS1307 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Пет Окт 05, 2007 8:34 pm
Мнения: 76
Местоположение: Русе
Мнение Проблем с четенето на RTC DS1307
Здравейте :) Имам проблем с комуникацията между PIC2520 и DS1307. В самото начало RTC-то въобще ни ми "отговаряше"(не генерираше АСК). След 1 седмица главоблъсканица проблема се оправи (оказа се, че програмата ми не е била написана както трябва :) ). Имам изключително големи съмнения(след още 2 седмици главоблъсканица), че и програмата ми за четене не е направена както трябва, затова Ви моля, ако някой има някаква примерна програма за четене на RTC-то, но да НЕ се използва вградения в PIC-а MSSP модул, ще му бъда много благодарен за помощта.


Сря Дек 12, 2007 5:21 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Нямам програмка за DS1307. А и звучиш малко объркано за да се опита човек да ти помогне.Но... освен софтуерните проблеми търсил ли си и хардуерни? Какви са напреженията на VCC и VBAT измерени директно върху крачетата на чипа?


Сря Дек 12, 2007 5:41 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Чет Дек 02, 2004 7:22 pm
Мнения: 140
Мнение 
eedatap = 0x00; //seconds;
i2cSend(0xD0, 0x00, 1, 1, &eedatap);
ms_spin(5);
eedatap = RtcTime.minutes;
i2cSend(0xD0, 0x01, 1, 1, &eedatap);
ms_spin(5);
eedatap = RtcTime.hours;
i2cSend(0xD0, 0x02, 1, 1, &eedatap);
ms_spin(5);
eedatap = RtcTime.day;
i2cSend(0xD0, 0x04, 1, 1, &eedatap);
ms_spin(5);
eedatap = RtcTime.month;
i2cSend(0xD0, 0x05, 1, 1, &eedatap);
ms_spin(5);
eedatap = (RtcTime.year - 2000);
i2cSend(0xD0, 0x06, 1, 1, &eedatap);

Праща се пакет с два адреса - D0 адрес на DS1307 и веднага след това адрес минути, секунди, те са описани. за данни е ясно какво пращаш.


самото пращане:

//! Send a byte sequence on the I2C bus
void i2cSend(u08 device, u16 subAddr,u08 addrlength, u08 length, u08 *data)
{
I2C_START; // старт кондишън
i2cPutbyte(device); // адрес на устройството
if (addrlength == 2) i2cPutbyte(subAddr >> 8); // and the subaddress ако е 2 байта, а той не е !!!
if (addrlength > 0) i2cPutbyte(subAddr); // and the subaddress low byte
// send the data
while (length--) //докато свършат байтовете данни, пращай
i2cPutbyte(*data++);

I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
}


Старт и стоп кондишън и i2cPutbyte ти ги оставям за домашно. Ако не се справиш ще ти пратя и i2cPutbyte.
Всъщност програмата е за АТМЕГА, но принципа си е същия.

По същия начин четене:

i2cReceive(0xD0, 0x00, 1, 1, &eedatap);
RtcTime.seconds = eedatap;
i2cReceive(0xD0, 0x01, 1, 1, &eedatap);
RtcTime.minutes = eedatap;
i2cReceive(0xD0, 0x02, 1, 1, &eedatap);
RtcTime.hours = eedatap;
i2cReceive(0xD0, 0x04, 1, 1, &eedatap);
RtcTime.day = eedatap;
i2cReceive(0xD0, 0x05, 1, 1, &eedatap);
RtcTime.month = eedatap;
i2cReceive(0xD0, 0x06, 1, 1, &eedatap);
RtcTime.year = eedatap + 2000;


Сря Дек 12, 2007 6:02 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Чет Дек 02, 2004 7:22 pm
Мнения: 140
Мнение 
Ето и путбайт и гетбайт.


UINT i2cPutbyte(u08 b)
{
int i;

for (i=7;i>=0;i--)
{
if ( b & (1<<i) )
I2C_SDL_HI;
else
I2C_SDL_LO; // address bit
I2C_SCL_TOGGLE; // clock HI, delay, then LO
}

I2C_SDL_HI; // leave SDL HI
// added
//cbi(SDADDR, SDA); // change direction to input on SDA line (may not be needed)
//I2C_SDL_HI; // make sure pullups are ativated

HDEL;
I2C_SCL_HI; // clock back up
b = inb(SDAPIN) & (1<<SDA); // get the ACK bit


HDEL;
I2C_SCL_LO; // not really ??
//sbi(SDADDR, SDA); // change direction back to output
HDEL;
return (b == 0); // return ACK value
}


u08 i2cGetbyte(UINT last)
{
int i;
u08 c,b = 0;


cbi(SDADDR, SDA); // change direction to input on SDA line (may not be needed)

for(i=7;i>=0;i--)
{
HDEL;
I2C_SCL_HI; // clock HI
c = inb(SDAPIN) & (1<<SDA);
b <<= 1;
if(c) b |= 1;
HDEL;
I2C_SCL_LO; // clock LO
}


if (last)
I2C_SDL_HI; // set NAK
else
I2C_SDL_LO; // set ACK

I2C_SCL_TOGGLE; // clock pulse
I2C_SDL_HI; // leave with SDL HI
return b; // return received byte
}


#define QDEL us_spin(3); // i2c quarter-bit delay
#define HDEL us_spin(6); // i2c half-bit delay


#define I2C_SDL_LO sbi(SDADDR, SDA)
#define I2C_SDL_HI cbi(SDADDR, SDA)

#define I2C_SCL_LO cbi( SCLPORT, SCL)
#define I2C_SCL_HI sbi( SCLPORT, SCL)

#define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
#define I2C_START I2C_SDL_LO; QDEL; I2C_SCL_LO;
#define I2C_STOP HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL;

дефинетата ще си ги направиш за пик. Напр. sbi(SDADDR, SDA) ти сетва посоката на дата линията която е на крак SDA дефиниран преди това (например крак '0') SDADDR е регистъра за посока на данни на порт SDAPORT, които се дефинират преди това Напр. PORTA i DDRA
освен това да знаеш че разчитам за пулъпа за високо ниво и никога не сетвам дата линията в '1' (само крака го правя вход), така че пулъп няколко колома е задължителен за дата линията, както си е по даташит. SDAPIN е регистъра от който се четат данни когато порта е вход, при пиковетe това го няма, там си четеш от регистъра SDAPORT.


Сря Дек 12, 2007 6:19 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Пет Окт 05, 2007 8:34 pm
Мнения: 76
Местоположение: Русе
Мнение 
Забравих да отбележа, че програмката трябва да е на асемблер(далеч съм от С все още). Напреженията ми са ОК-Vcc е 5V, а крачето за батерията е свързано към маса


Сря Дек 12, 2007 6:19 pm
Профил ICQ
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Чет Дек 02, 2004 7:22 pm
Мнения: 140
Мнение 
Мисля че ако се зачетеш подробно и няколко пъти ще разбереш алгоритъма и ще видиш къде бъркаш, по-важно е да разбреш начина, програмата е по-лесната част.


Сря Дек 12, 2007 6:45 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Пет Окт 05, 2007 8:34 pm
Мнения: 76
Местоположение: Русе
Мнение 
Сега като се зачетох схванах за какво става въпрос, но нещо ме притеснява тази част от кода:


По същия начин четене:

i2cReceive(0xD0, 0x00, 1, 1, &eedatap);
RtcTime.seconds = eedatap;
i2cReceive(0xD0, 0x01, 1, 1, &eedatap);
RtcTime.minutes = eedatap;
i2cReceive(0xD0, 0x02, 1, 1, &eedatap);
RtcTime.hours = eedatap;
i2cReceive(0xD0, 0x04, 1, 1, &eedatap);
RtcTime.day = eedatap;
i2cReceive(0xD0, 0x05, 1, 1, &eedatap);
RtcTime.month = eedatap;
i2cReceive(0xD0, 0x06, 1, 1, &eedatap);
RtcTime.year = eedatap + 2000

При четене не трябва ли контролния байт на RTC-то да е 0xD1?


Сря Дек 12, 2007 9:49 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Окт 07, 2004 1:22 pm
Мнения: 1949
Местоположение: София
Мнение 
Обърни внимание на каква честота е I2C-то, не надхвърляй 100KHz иначе няма да работи


Чет Дек 13, 2007 11:16 am
Профил
Ранг: Новодошъл
Ранг: Новодошъл
Аватар

Регистриран на: Чет Дек 02, 2004 7:22 pm
Мнения: 140
Мнение 
Трябва, да! Но това се прави вътре във функцията i2cReceive.

i2cPutbyte(device | READ); // resend DEVICE, with READ bit set, където READ е 1 и от D0 става D1, "|" e = на лог."OR"


Чет Дек 13, 2007 11:41 am
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Окт 28, 2005 3:24 pm
Мнения: 30
Мнение 
Чипа си работи без проблеми, вече стотици устройства работят с него и нито с един няма проблеми. Документацията е достатъчно ясна, ако имаш проблеми с това какво да се направи, питай. Мога да извадя процедурата за инициализация, да ти сваля времедиаграми от комуникацията с чипа и т.н. Но конкретно с пик (чета) не се занимавам и не мога да помогна.


Чет Дек 13, 2007 6:52 pm
Профил
Ранг: Минаващ
Ранг: Минаващ
Аватар

Регистриран на: Пет Окт 05, 2007 8:34 pm
Мнения: 76
Местоположение: Русе
Мнение 
Голямо благодарско на всички, които се отзоваха! Днес най-после всичко тръгна както трябва! :prayer: :supz:


Чет Дек 13, 2007 8:47 pm
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 11 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни