Предлагаю по аналогии с viewtopic.php?f=20&t=64022 скидывать наработки сюда. Блин, нужна чья-то помощь. Есть у кого код для Иара? А то свой написал, проверил 100500 раз, а ни на один байт ACK не могу получить. Делал в соответствии со спецификацией, проверял.
_________________ Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
//*** Формирование старт-бита // <-- если 0 - линия занята, иначе - передан старт unsigned char i2c_start (void) { unsigned char Res = 1;
CBI(I2C_DDR, I2C_SDA); if (GBI(I2C_PIN, I2C_SDA)) // проверка на ошибку линии { // устанавливаем лог 1 на линии SCL за счет подтягивающих резисторов CBI(I2C_DDR, I2C_SCL); CBI(I2C_PORT, I2C_SCL); delay_us(I2C_DELAY);
// устанавливаем лог 0 на линии SDA за счет защелки SBI(I2C_DDR, I2C_SDA); CBI(I2C_PORT, I2C_SDA); delay_us(I2C_DELAY);
// устанавливаем лог 0 на линии SCL за счет защелки SBI(I2C_DDR, I2C_SCL); delay_us(I2C_DELAY); } else Res = 0;
return Res; }
//*** Формирование стоп-бита void i2c_stop (void) { // устанавливаем лог 0 на линии SDA за счет подтягивающих резисторов SBI(I2C_DDR, I2C_SDA); CBI(I2C_PORT, I2C_SDA); delay_us(I2C_DELAY);
// устанавливаем лог 1 на линии SCL за счет защелки SBI(I2C_DDR, I2C_SCL); CBI(I2C_PORT, I2C_SCL); delay_us(I2C_DELAY);
// устанавливаем лог 1 на линии SDA за счет защелки CBI(I2C_DDR, I2C_SDA); delay_us(I2C_DELAY); } unsigned char i2c_write_byte(u8 Data) { unsigned char Res = 0;
CBI(I2C_PORT, I2C_SCL); CBI(I2C_PORT, I2C_SDA);
for (u8 i = 0; i < 8; i++) { SBI(I2C_DDR, I2C_SDA); if (Data & 0x80) CBI(I2C_DDR, I2C_SDA);
delay_us(I2C_DELAY);
// устанавливаем лог 1 на линии SCL за счет подтягивающих резисторов CBI(I2C_DDR, I2C_SCL); delay_us(I2C_DELAY);
// устанавливаем лог 0 на линии SCL за счет подтягивающих резисторов SBI(I2C_DDR, I2C_SCL); delay_us(I2C_DELAY); Data <<= 1; }
CBI(I2C_DDR, I2C_SDA); delay_us(I2C_DELAY);
// устанавливаем лог 1 на линии SCL за счет подтягивающих резисторов CBI(I2C_DDR, I2C_SCL); delay_us(I2C_DELAY);
Res = GBI(I2C_PIN, I2C_SDA);
// устанавливаем лог 0 на линии SCL за счет подтягивающих резисторов SBI(I2C_DDR, I2C_SCL); delay_us(I2C_DELAY);
SBI(I2C_DDR, I2C_SDA); delay_us(I2C_DELAY);
return Res; }
//*** Чтение байта из I2C // --> Ack > 0 - генерировать, иначе - нет // <-- принятые данные unsigned char i2c_read_byte(u8 Ack) { unsigned char Res=0;
//####################################################################################################################### //# //# ФУНКЦИИ РАБОТЫ С ЧАСАМИ DS1307 //# //#######################################################################################################################
//ФУНКЦИЯ ЧТЕНИЯ БЛОКА ДАННЫХ ИЗ МИКРОСХЕМЫ ЧАСОВ DS1307 //чтение происходит в глобальный массив ClockData[7] //последовательность данных - [0]секунды, [1]минуты, [2]часы, [3]день, [4]дата, [5]месяц, [6]год void IICClockReadData (void) { IICStart(); IICByteWrite (0xD0);//запись данных в DS1307 IICByteWrite (0x00);//сбросить указатель адреса DS1307 на 0
IICStart(); IICByteWrite (0xD1);//команда на чтение данных
char temp = IICByteRead (0);//читсем секунды с выдачей подтверждения (0) if (temp != ClockData[0]){ ClockData[0]= temp;
char* pClockData =&ClockData[1];//указатель на данные часов for (char i = 0; i<5; i++) *pClockData++= IICByteRead (0);//пишем, минуты, часы, день, дата, месяц (с выдачей подтверждением) *pClockData = IICByteRead (1);//пишем год (без подтверждения) IICStop(); }
//ФУНКЦИЯ ЗАПИСИ БЛОКА ДАННЫХ В МИКРОСХЕМУ ЧАСОВ DS1307 //запись происходит из глобального массива ClockData[7] //последовательность данных - [0]секунды, [1]минуты, [2]часы, [3]день, [4]дата, [5]месяц, [6]год void IICClockWriteData (void) { IICStart(); IICByteWrite (0xD0);//запись данных в DS1307 IICByteWrite (0x00);//сбросить указатель адреса DS1307 на 0
for (unsigned char i = 0; i<7; i++) IICByteWrite (ClockData [i]);//пишем, секунды, минуты, часы, день, дата, месяц, год
IICStop(); }
А вот софтовая реализация I2C. Заморочек меньше чем с аппаратной, да и цеплять можно на любые выводы контроллераСпойлер
Код:
#define IICDDR DDRC /*порт управления I2C*/ #define IICPORT PORTC /*порт вывода данных на линию I2C*/ #define IICPIN PINC /*порт ввода данных с линий I2C*/ #define IICData (1<<4) /*линия DATA*/ #define IICClc (1<<5) /*линия CLC*/
//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ START ПО ИНТЕРФЕЙСУ IIC void IICStart (void) { IICDDR &=~(IICData | IICClc); Delay2Mks();
IICDDR |= IICData;//подтяжка data к нулю Delay2Mks();
IICDDR |= IICClc;//подтяжка clc к нулю Delay2Mks(); }
//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ STOP ПО ИНТЕРФЕЙСУ IIC void IICStop (void) { IICDDR |=(IICData | IICClc); Delay2Mks();
IICDDR &=~IICClc;//подтяжка data к нулю Delay2Mks();
IICDDR &=~IICData;//подтяжка clc к нулю Delay2Mks(); }
//ФУНКЦИЯ ЗАПИСИ БАЙТА ПО ИНТЕРФЕЙСУ IIC //АРГУМЕНТ - байт данных для вывода по IIC //ЗНАЧЕНИЕ - флаг подтверждения 0 (есть подтверждение) или 1 (нет подтверждения) char IICByteWrite (char byte) { for (char i = 0; i<8; i++) byte = IICBit (byte);
//ФУНКЦИЯ ЧТЕНИЯ БАЙТА ПО ИНТЕРФЕЙСУ IIC //АРГУМЕНТ - значение бита подтверждения (0 - есть подтверждение, 1 - нет подтверждения) //ЗНАЧЕНИЕ - принятый байт char IICByteRead (char bit) { char byte = 0xFF; for (char i = 0; i<8; i++) byte = IICBit (byte);
bit <<= 7; IICBit (bit);//передать значение бита подтверждения return byte;//возвращаем принятый байт }
//ФУНКЦИЯ ЗАПИСИ\ЧТЕНИЯ БИТА ПО ИНТЕРФЕЙСУ IIC //выводится значение старшего бита аргумента //принятый бит возвращается в младшем бите предварительно сдвинутого влево аргумента char IICBit (char byte) { if (byte & 0x80)//выводимый бит IICDDR &=~IICData;//вывод 1 на линию данных else IICDDR |= IICData;//вывод 0 на линию данных Delay2Mks();
IICDDR &=~IICClc;//старт строб импульса while (!(IICPIN & IICClc)){}//ожидание формирования строба Delay2Mks();
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Еще требуется инициализация микросхемы. rtc_init(0, 0, 0); // при первом запуске DS1307 его регистры не установлены (ручками установим их - биты: rs=0, sqwe=0, out=0) Кажется rs обязательно надо в 0 установить. Давно разбирался. Теперь пользуюсь готовым куском и не парюсь. Но все в CV.
Pika4u - по-моему у Вас ошибка в среднем блоке функции i2c_stop() и комментарии там везде неправильные. Если это не поможет, дайте код обрашения к DS1307 с указанием ее I2C адреса (может он неправильный в программе?) Получаете-ли ACK после отсылки адреса по I2C? Если ДА, то на каком этапе коммуникации с DS получаете NACK?
Итак, добил я все же эту ds1307,посадил ей 3 вывод(батарея) на землю и вышеизложенный код заработал. Но вот в чем трабла-смотрю на дисплее результаты отправки байтов-случайным образом, бывает, ACK не приходит.В случае получения NACK, нужно байт отправить ещё раз?
_________________ Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Как все запущено оказалось... А полазить по сайтам производителей часиков и почитать рекомендации по применению ? Да и правила по обычным микрухам пока не отменялись! Вот на всяк случай манька по PCFам - типовые решения все одинаковые:
А вот так выглядит мое решение макетки часиков на DS1307 как отдельного узла (под схему с акумулятором или ионистором - при литиевой батарее цепочка заряда не ставится!):
Спасибо огромное) просто у меня сейчас отладочная плата на меге8(сделал сам, все по минимуму, разводка питания и все выводы выведены на штыри. Так вот, на плате мега8, дс1307, дс18б20, и жк-дисплей. Все питается от программатора(юсб,5В). Я думал, что конденсатора меги, керамики 18б20 и конденсатора в программаторе хватит... Не хватило)
_________________ Steve Jobs. 1955-2011. Мы помним, как ты преобразовал наш мир....
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 26
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения