Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Всё по DS1307 и прочим часам Dallas (Maxim)

Пт янв 11, 2013 13:30:50

Предлагаю по аналогии с viewtopic.php?f=20&t=64022 скидывать наработки сюда. Блин, нужна чья-то помощь. Есть у кого код для Иара? А то свой написал, проверил 100500 раз, а ни на один байт ACK не могу получить. Делал в соответствии со спецификацией, проверял.

Re: Все по DS1307.

Пт янв 11, 2013 13:50:36

Ах, да, вот код(CBI-ClearBit,SBI-SetBit).
Спойлер
Код:
define I2C_DELAY 40  //ms
#define debug

//*** Формирование старт-бита
// <-- если 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;
 
  CBI(I2C_DDR, I2C_SDA);
  CBI(I2C_PORT, I2C_SDA);
 
  for(u8 x=0; x<8; x++)
  {
    Res <<= 1;
    CBI(I2C_DDR, I2C_SCL);
    delay_us(I2C_DELAY);

    if(GBI(I2C_PIN, I2C_SDA))
      Res |= 1;
   
    SBI(I2C_DDR, I2C_SCL);
    delay_us(I2C_DELAY);
  }
 
  if(Ack)
    SBI(I2C_DDR, I2C_SDA);
  else
    CBI(I2C_DDR, I2C_SDA);
 
  delay_us(I2C_DELAY);
 
  CBI(I2C_DDR, I2C_SCL);
  delay_us(I2C_DELAY);

  SBI(I2C_DDR, I2C_SCL);
  CBI(I2C_DDR, I2C_SCL);
  return Res;
}

//*** Инициализация интерфейса I2C
void i2c_init( void )
{
  CBI(I2C_DDR, I2C_SDA);
  CBI(I2C_DDR, I2C_SCL);
 
  CBI(I2C_PORT, I2C_SDA);
  CBI(I2C_PORT, I2C_SCL);
}

Re: Все по DS1307.

Пт янв 11, 2013 14:24:22

Не знаю насколько подойдет иар авр
Часы.rar
(113.09 KiB) Скачиваний: 1011

Re: Все по DS1307.

Пт янв 11, 2013 14:25:07

А вот как я юзаю DS1307, только для WINAVR.....
Код:
//#######################################################################################################################
//#
//#    ФУНКЦИИ РАБОТЫ С ЧАСАМИ 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;

        //вызов процедур 1 раз\сек
        ClockMiliSecond = 0;                    //обнулить милисекунды
    }

    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*/

//#######################################################################################################################
//#
//# ФУНКЦИИ ОБСЛУЖИВАНИЯ ИНТЕРФЕЙСА I2C (софтовый вариант)
//#
//#######################################################################################################################

//задержка 2 микросекунды для формированя временных задержек IIC
NOINLINE void Delay2Mks (void)
{
    _delay_us (2);
}


//ФУНКЦИЯ ФОРМИРОВАНИЯ СОСТОЯНИЯ 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);

    byte = 0x80;                                
    return IICBit 
(byte);                        //возвращаем бит подтверждения (0-есть бит подтверждения, 1-нет)
}


//ФУНКЦИЯ ЧТЕНИЯ БАЙТА ПО ИНТЕРФЕЙСУ 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();

    char temp;    
    if 
(IICPIN & IICData)                    //принимаем бит
        temp = 1;
    else
        temp 
= 0;
    IICDDR |= IICClc;                        //завершить строб

    byte <<= 1;
    byte |= temp;
    return byte;
}
 

Re: Все по DS1307.

Пт янв 11, 2013 14:28:09

Спасибо, буду разбираться, у вас, видимо, используется аппаратный TWI? Ну тогда сначала попытаюсь хоть от TWI завести)

Re: Все по DS1307.

Пт янв 11, 2013 14:33:30

shads, огромное спасибо!!!!!!!!!!!!!!!!! Пойду пробовать) А темку предлагаю закрепить))По аналогии с ds18b20 )

Re: Все по DS1307.

Пт янв 11, 2013 15:23:31

Блин, подключение 100500 раз перепроверил, кварц есть(с материнки,на 32768Гц), биты в дефайнах, ес-но, поменял. Неа, ACK нету :cry:

Re: Все по DS1307.

Пт янв 11, 2013 15:32:29

:dont_know: DS1307 требует подключения батарейки +3V.

Re: Все по DS1307.

Пт янв 11, 2013 15:32:57

Завел через переменник 3 Вольта на него, то же самое)

Re: Все по DS1307.

Пт янв 11, 2013 16:13:22

Еще требуется инициализация микросхемы.
rtc_init(0, 0, 0); // при первом запуске DS1307 его регистры не установлены (ручками установим их - биты: rs=0, sqwe=0, out=0)
Кажется rs обязательно надо в 0 установить. Давно разбирался. Теперь пользуюсь готовым куском и не парюсь. Но все в CV.

Re: Все по DS1307.

Пт янв 11, 2013 16:54:48

До регистров далеко, тут даже ACK не получен(

Re: Все по DS1307.

Пт янв 11, 2013 17:32:30

В протеусе попробуй..... если в проте работает, то тогда в железе можно пробовать.....
Или скинь сюда схемку в протеусе, вместе поморокуем.....

Re: Все по DS1307.

Пт янв 11, 2013 17:50:56

Только в IAR,в CVAVR "религия" не позволяет?

Re: Все по DS1307.

Пт янв 11, 2013 23:13:54

Pika4u - по-моему у Вас ошибка в среднем блоке функции i2c_stop() и комментарии там везде неправильные. Если это не поможет, дайте код обрашения к DS1307 с указанием ее I2C адреса (может он неправильный в программе?) Получаете-ли ACK после отсылки адреса по I2C? Если ДА, то на каком этапе коммуникации с DS получаете NACK?

Re: Все по DS1307.

Сб янв 12, 2013 00:56:19

На асме для mcs51 имеется наработка... DS1307 для побайтовой адресации довольно специфичное решение требует - в даташите только блочный обмен... 8)

Re: Все по DS1307.

Пт янв 18, 2013 17:46:22

Итак, добил я все же эту ds1307,посадил ей 3 вывод(батарея) на землю и вышеизложенный код заработал. Но вот в чем трабла-смотрю на дисплее результаты отправки байтов-случайным образом, бывает, ACK не приходит.В случае получения NACK, нужно байт отправить ещё раз?

Re: Все по DS1307.

Пт янв 18, 2013 19:09:14

Я ж уже говорил - предназначено для блочного обмена.
Ежли хочется побайтовое общение с произвольным начальным адресом см. вот этот листик:
ds1307map.pdf
(13.73 KiB) Скачиваний: 1073

в данном случае имеет место "слэнг" I2C.
Ну и вот эта шпоргалка, когда-то нашкрябаная:
shpora_I2C_1.pdf
(135.75 KiB) Скачиваний: 1086

В случае на сассемблере - помогу, под СИ не работаю...

Re: Все по DS1307.

Сб янв 19, 2013 05:00:23

Как это ни странно, проблема решилась установкой электролита по питанию 1307.

Re: Все по DS1307.

Сб янв 19, 2013 09:58:08

Как все запущено оказалось... :shock:
А полазить по сайтам производителей часиков и почитать рекомендации по применению ? Да и правила по обычным микрухам пока не отменялись!
Вот на всяк случай манька по PCFам - типовые решения все одинаковые:
user.manual.real.time.clocks.pdf
(603.38 KiB) Скачиваний: 1784

А вот так выглядит мое решение макетки часиков на DS1307 как отдельного узла (под схему с акумулятором или ионистором - при литиевой батарее цепочка заряда не ставится!):
1307.pdf
(31.16 KiB) Скачиваний: 1327

8)
А вот для ленивых немышеловов древняя подборка апноток от MAXIM-DALLAS из трех кусочков:
APPNOTES от Maxim-dallas.part1.rar
(488.28 KiB) Скачиваний: 982

APPNOTES от Maxim-dallas.part2.rar
(488.28 KiB) Скачиваний: 879

APPNOTES от Maxim-dallas.part3.rar
(365.14 KiB) Скачиваний: 885

:tea:

Re: Все по DS1307.

Сб янв 19, 2013 14:32:51

Спасибо огромное) просто у меня сейчас отладочная плата на меге8(сделал сам, все по минимуму, разводка питания и все выводы выведены на штыри. Так вот, на плате мега8, дс1307, дс18б20, и жк-дисплей. Все питается от программатора(юсб,5В). Я думал, что конденсатора меги, керамики 18б20 и конденсатора в программаторе хватит... Не хватило)
Ответить