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

Re: DS 1302

Пт июн 30, 2017 14:01:31

Да, на время обмена CE=1, после обмена CE=0. Причем, в таташите указаны ВСЕ времена: пауза после CE=1, после CE=0 и т.д. и т.п.
И эти времена необходимо выдерживать.

НУ ТАК НА ДИАГРАММЕ МЕЖДУ командным байтом и приемом я не выставил СЕ в 0...

Добавлено after 11 minutes 49 seconds:
Теперь реши загадку, почему передача байта в часы у тебя с каждым тактом всё медленнее. :))

я с самого начала это заметил, пока думаю)) из-за сдвигового регистра, который сдвигает маску идет торможение?

Re: DS 1302

Пт июн 30, 2017 14:04:39

из-за сдвигового регистра, который сдвигает маску идет торможение?
Правильно.
Следующий вопрос - а зачем так делать? Посмотри на пример от Zhuk72.

Re: DS 1302

Пт июн 30, 2017 14:09:55

Следующий вопрос - а зачем так делать? Посмотри на пример от Zhuk72.
ну он сдвигает сам байт команды я так понял. у него не меняется количество тактов в цикле вот и все, вот и диаграмма у него более ровная

Re: DS 1302

Сб июл 01, 2017 09:05:29

Приветствую!
ни в какую не могу запустить часы.... пробую СЕ опустить в 0 после комбайта, и не опуская, часы мне не отвечают. пробовал и с подтяжкой и без.... может часы неисправны....:cry:
вот код последней версии:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define DDR_ds1302 DDRA
#define PORT_ds1302 PORTA
#define PIN_ds1302 PINA
#define CE 7
#define SCLK 6
#define DATA 5

void READ (void)
{
DDR_ds1302&=~(1<<DDR_ds1302);
PORT_ds1302|=1<<DATA;

PORT_ds1302|=1<<CE;
_delay_us(1);

for(char i=0;i<8;i++)
{
PORT_ds1302|=1<<SCLK;
PORT_ds1302&=~(1<<SCLK);
}
PORT_ds1302&=~(1<<CE);
}

void WRITE_ds1302(char comdata)

{

PORT_ds1302|=1<<CE; //выставляем строб

_delay_us(1);

for(char i=0;i<8;i++)
{

if(comdata&1)
PORT_ds1302|=1<<DATA;
else
PORT_ds1302&=~(1<<DATA);

PORT_ds1302|=1<<SCLK;
_delay_us(1);
PORT_ds1302&=~(1<<DATA);
PORT_ds1302&=~(1<<SCLK);
comdata>>=1;
}
PORT_ds1302&=~(1<<CE);
READ();
}


int main(void)
{
DDR_ds1302|=1<<CE;
DDR_ds1302|=1<<SCLK;
DDR_ds1302|=1<<DATA;


PORT_ds1302&=~(1<<CE);
PORT_ds1302&=~(1<<SCLK);
PORT_ds1302&=~(1<<DATA);

WRITE_ds1302(0x83);

}
Вложения
диаграмма.rar
(682 байт) Скачиваний: 290

Re: DS 1302

Вс июл 02, 2017 07:26:01

Единственное решение - это снимать диаграмму общения МК с 1302, сравнивать с требуемой по ДШ и подгонять по необходимости.

Re: DS 1302

Вс июл 02, 2017 08:33:47

Могу еще для анализа предложить свой код... это было давно под MSP430G2xxx:
Спойлер
Код:
#include "io430.h"

#define DATA            P1OUT_bit.P1
#define DATA_DIR        P1DIR_bit.P1
#define DATA_IN         P1IN_bit.P1
#define SCLK            P1OUT_bit.P0
#define CE              P1OUT_bit.P2

void write_ds1302(unsigned char reg_addr, unsigned char reg_value)
{
  unsigned int i;

  DATA_DIR = 1;
  CE = 0;
  SCLK = 0;
  DATA = 0;
  CE = 1;
  reg_addr &= ~(0x01); // write command
  reg_addr |= 0x80; // must be 1
  DATA = (reg_addr & 0x01);
  for (i=0 ; i<8 ; ++i) {
    SCLK = 1;
    reg_addr >>= 1;
    SCLK = 0;
    DATA = (reg_addr & 0x01);
  }
  DATA = (reg_value & 0x01);
  for (i=0 ; i<8 ; ++i) {
    SCLK = 1;
    reg_value >>= 1;
    SCLK = 0;
    DATA = (reg_value & 0x01);
  }
  DATA = 0;
  SCLK = 0;
  CE = 0;
}

unsigned char read_ds1302(unsigned char reg_addr)
{
  unsigned int i;
  unsigned char result = 0;
 
  CE = 0;
  SCLK = 0;
  DATA = 0;
  CE = 1;
  reg_addr |= 0x81; // must be 1 for read
  DATA = (reg_addr & 0x01);
  for (i=0 ; i<7 ; ++i) {
    SCLK = 1;
    reg_addr >>= 1;
    SCLK = 0;
    DATA = (reg_addr & 0x01);
  }
  SCLK = 1;
  DATA_DIR = 0;
  for (i=0 ; i <8 ; ++i) {
    result >>= 1;
    SCLK = 0;
    result |= (DATA_IN == 1) ? 0x80 : 0x00 ;
    SCLK = 1;
  }
  SCLK = 0;
  DATA = 0;
  DATA_DIR = 1;
  CE = 0;
  return result;
}


задержки на 1мкс не вставлял, так как пока проинициализируются переменные цикла времени может пройти гораздо больше.

Код:
      current_time.seconds = read_ds1302(0x81);
      if (current_time.seconds != last_second) {
        last_second = current_time.seconds;
        current_time.seconds = utc_time.seconds = read_ds1302(0x81);
        current_time.minutes = utc_time.minutes = read_ds1302(0x83);
        current_time.hours   = utc_time.hours   = read_ds1302(0x85);
        current_time.date    = utc_time.date    = read_ds1302(0x87);
        current_time.month   = utc_time.month   = read_ds1302(0x89);
        current_time.weekday = utc_time.weekday = read_ds1302(0x8b);
        current_time.year    = utc_time.year    = read_ds1302(0x8d);


Как-то у меня с этой ds1302 проблем не было. Прочитал даташит, написал и всё заработало.
Был еще один проект на пике pic12f629 - но там на ассемблере и дата/клок там были объединены в шину со сдвиговым регистром для отображения.

Re: DS 1302

Вс июл 02, 2017 09:08:31

Проверил кварц на часах осцлографом, диаграмму не наблюдаю,пойду попробую перепаяю...одно меня смущает,в даташите про бит ch упоминается, мол не выставишь его часы не пойдут...на кварц же он не должен никакого влияния оказывать?

Re: DS 1302

Вс июл 02, 2017 09:21:04

Скорее, подключая осциллограф, генерация просто срывается. Там очень маломощный генератор. И вы обратили внимание, что для 1302 надо кварц расчитанный на ёмкость всего 6пФ? Хотя, нет. Можно и больше, просто снаружи надо будет навесить дополнительные ёмкости.

Re: DS 1302

Вс июл 02, 2017 13:18:36

uldemir
перепаял, результатов нет...собрался было бежать за новой микросхемой. да рашил прогнать свой код в протеусе, что там я увижу...так там осцилограф улавливает обратную связь и время правильно кодируется. интересный момент то, что после передачи комбайта я сбрасываю ножку DATA в 0, а часы возвращают ее в 2 В. это так понимаю уровень лог.0 у часов.СЕ после комбайта не сбрасываю а подтяжку на DATA подключаю. завожу свой код на железе диаграмма с анализатора при обратке показывает только синхронные импульсы с SCLK.

Добавлено after 25 minutes 4 seconds:
Скорее, подключая осциллограф, генерация просто срывается.
Вы были правы.Щуп с кондером дал результат.Теперь хоть знаю, что кварц исправен.Допустим, что микросхема исправна,Какие еще могут быть нюансы?
На логическом анализаторе могут быть какие либо искажения?и в следствии этого я не вижу обратную связь?

Re: DS 1302

Вс июл 02, 2017 13:43:04

Контрольные тесты устройств с протоколом реального времени точно можно только под ассемблером сделать/протестировать.
А под СИ предпочтительно уже готовыми результатами пользоваться.
8)

Re: DS 1302

Вс июл 02, 2017 15:24:25

За ассемблер в перспективе собираюсь браться, пока С/С++...
Микросхема мне чет не нравится, надо с другой попробовать думаю... С ds18b20 гораздо проще было... часики эти меня очень вымотали

Re: DS 1302

Вс июл 02, 2017 15:34:35

Поставь "всеми вылизанную" DS1307 - и не имей проблем!
8)

Re: DS 1302

Вс июл 02, 2017 15:38:41

Подумываю над этим! :tea: :cry: ну как то обидно потратив кучу времени и усилии бросить не разобравшись до конца... Скорее поставлю 1307...но за 1302 я еще возьмусь :write: :kill:

Re: DS 1302

Пн июл 03, 2017 01:24:59

Контрольные тесты устройств с протоколом реального времени точно можно только под ассемблером сделать/протестировать.
Не надо настолько опрометчиво заявлять подобные глупости. :)

Добавлено after 1 hour 34 minutes 56 seconds:
часы мне не отвечают.
Скажу одно - нужно строго выполнять даташит и всё будет работать.
За часок быстренько прочитал даташит и сделал тест - и часы тикают, и читаются и пишутся в них. (Хорошо, что в заначке были эти часы)
может часы неисправны....:cry:
Мелкосхема, походу, аццки живучая.
Я по дурости вначале перепутал у неё питание - горячая была, аж пальцы обожгла. И ничего - работает. 8)
бит ch упоминается, мол не выставишь его часы не пойдут...на кварц же он не должен никакого влияния оказывать?
Пока бит "ch" не обнулён - м/с в области ячеек RTC работает как обычная память. Какие дату/время запишешь - те и будет постоянно показывать.
Забей пока на кварт с часами, отладь диаграмму - пиши/читай в RAM-область часов (от 0xC0 и далее)

Re: DS 1302

Вс авг 27, 2017 13:37:11

Добрый день форумчане!!! Снова возвращаюсь к данной проблеме т.к. она все еще не решена мною. Было испробованы новые МС, новый модуль,но ничего нового это не дало.Часы не отвечают на запросы Меги16, т.е. я не могу считать информацию с них. Я не знаю уже где собака зарыта. Вроде делаю все согласно даташиту.... Может это звучит беспардонно,но хотелось бы, чтоб мне уже ткнули пальцем на мои ошибки и ясно сказали где я заблуждаюсь.Ну или привели пример рабочего кода,хотя бы функцию записи и чтения...а там разберусь сам.Кстати код в протеусе показывает свою работоспособность. Парадокс какой-то.

Re: DS 1302

Вс авг 27, 2017 15:01:26

Вроде делаю все согласно даташиту....
"Вроде" или "точно"?
Осциллографом сравнивались генерируемая диаграмма с даташитовой?
а там разберусь сам
Ой, не факт....

Код, писаный два месяца назад за час времени.
Код некрасивый, а в паре мест - жутко некрасивый. И ни одного комментария. Сам себя за это ругаю теперь. :kill:
Моё единственное оправдание - время написания кода. 8)

Контроллер: ATmega328.
Частота генератора: 16 МГц.
Подключение: PC0 (DS1302_CS), PC2 (DS1302_CLK), PC1 (DS1302_DATA)
Компилятор: IAR.
========= main.c =========
Спойлер
Код:
void ReadAllDS()
{
    char i, cData, cAddr;
    for(i=0; i<10; i++)
    {
        cAddr = (i << 1);
        cAddr |= 0x81;
       
        uartPrintChar('(');   
        uartHex(cAddr);
        uartPrintChar(')');   
        uartPrintChar('=');   
       
        cData = ds1302_readData(cAddr);
        uartHex(cData);
       
        uartPrintChar(' ');   
        uartPrintChar(' ');   
    }
    uartPrintChar('\r');   
    uartPrintChar('\n');   
}

__noreturn void main(void)
{
    SPCR = 0;
    SPSR = 0;

    sei();
    UartInit();
    ds1302_init();

// !!! Вот так делать нельзя.
// Прошла пара месяцев, а я уже не помню что означают эти числа, а тем более зачем паузы - надо даташит смотреть.
    ds1302_writeData(0x80, 0x03);
     __delay_cycles(DELAY_10ms);
    ds1302_writeData(0x82, 0x45);
     __delay_cycles(DELAY_10ms);
    ds1302_writeData(0x84, 0x55);
   
    while(1)
    {
        ReadAllDS();   
        __delay_cycles(DELAY_1000ms);
    };
}

=========== ds1302.c =============
Спойлер
Код:
#include "main.h"
#include "ds1302.h"

#define DS1302_DDR      DDRC
#define DS1302_PORT     PORTC
#define DS1302_PIN      PINC

#define DS1302_CS       PC0
#define DS1302_CLK      PC2
#define DS1302_DATA     PC1

void ds1302_init()
{
    DS1302_DDR |= (1<<DS1302_CS) | (1<<DS1302_CLK) | (1<<DS1302_DATA);
    DS1302_PORT &= ~( (1<<DS1302_CS) | (1<<DS1302_CLK) | (1<<DS1302_DATA) );
}

static void ds1302_write(char cData)
{
    char i = 8;
    do
    {
        DS1302_PORT &= ~(1<<DS1302_CLK);    // 250 ns == 4 такта
       
        asm ("nop");
        DS1302_PORT &= ~(1<<DS1302_DATA);
        if( cData & 0x01 )
            DS1302_PORT |= (1<<DS1302_DATA);
        asm ("nop");
        asm ("nop");  // tDC = 50 ns
       
        DS1302_PORT |= (1<<DS1302_CLK);  // 250 ns == 4 такта
        cData >>= 1;
        asm ("nop");
        asm ("nop");
        asm ("nop");
       
    }while( --i );
}

static char ds1302_read()
{
    char cData;
    char i = 8;
    DS1302_PORT &= ~(1<<DS1302_DATA);
    DS1302_DDR &= ~(1<<DS1302_DATA);
    do
    {
        DS1302_PORT &= ~(1<<DS1302_CLK);
        // 200 ns  - мин. 3 такта!
        cData >>= 1;
        asm ("nop");
        asm ("nop");
        asm ("nop");
        asm ("nop");
       
        if( DS1302_PIN & (1<<DS1302_DATA) )
            cData |= 0x80;
       
        DS1302_PORT |= (1<<DS1302_CLK);
        asm ("nop");
        asm ("nop");
        asm ("nop");
        asm ("nop");
        asm ("nop");
       
    }while( --i );
    DS1302_DDR |= (1<<DS1302_DATA);
    return cData;
}

void ds1302_writeData(char cAddr, char cData)
{
    DS1302_PORT |= (1<<DS1302_CS);
    DS1302_PORT &= ~(1<<DS1302_CLK);
    __delay_cycles(DELAY_1mks);
   
    ds1302_write(cAddr);
    ds1302_write(cData);
    DS1302_PORT &= ~(1<<DS1302_CLK);
    asm ("nop");
    DS1302_PORT &= ~(1<<DS1302_CS);
}

char ds1302_readData(char cAddr)
{
    char cData;
    DS1302_PORT |= (1<<DS1302_CS);
    DS1302_PORT &= ~(1<<DS1302_CLK);
    __delay_cycles(DELAY_1mks);
   
    ds1302_write(cAddr);
    cData = ds1302_read();
   
    DS1302_PORT &= ~(1<<DS1302_CLK);
    asm ("nop");
    DS1302_PORT &= ~(1<<DS1302_CS);
    return cData;
}

Re: DS 1302

Вс авг 27, 2017 16:26:23

Попробовал прочесть RAM как мне рекомендовали выше, читается довольно таки стабильно, пытаюсь прочесть минуты часики уходят в игнор...че за баг не пойму?!
Ответить