реклама на сайте
подробности

 
 
> DS1338 + XMEGA
Pavel_Bor
сообщение Jul 6 2011, 12:14
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



В даташите на эти часики указаны 2 режима работы: Fast mode(400КГц), Standart mode(100КГц).
В меге инициализирован RC на 32Мгц.
Как между собой связать скорости. или какое время нужно давать при задержке.

При коде следующего вида никаких изменений не происходит..

CODE
void rtc_init()
{
RTC_DATA_DIR_SET;
RTC_DATA_SET;
RTC_SCL_UP;
delay_us(1);
}

void rtc_start()
{
RTC_DATA_CLR;
delay_us(1);
RTC_SCL_DOWN;
delay_us(1);
}

void rtc_stop()
{

RTC_SCL_UP;
delay_ms(1);
RTC_DATA_DIR_SET;
RTC_DATA_SET;
delay_ms(1);
}

void rtc_write (unsigned char buffer)
{
unsigned char MASK;
RTC_DATA_DIR_SET;
for(i=8;i>=0;--i)
{
if(buffer&&MASK )
RTC_DATA_SET;
else
RTC_DATA_CLR;
RTC_SCL_UP;
delay_ms(1);
RTC_SCL_DOWN;
delay_ms(1);
MASK>>1;
}

RTC_SCL_UP;
delay_ms(1);
RTC_SCL_DOWN;
delay_ms(1);
}

unsigned char read_rtc()
{
unsigned char buffer=0;

RTC_DATA_DIR_CLR;
for(i=8;i>=0;--i)
{
buffer|=((buffer<<1)||(PORTE.IN&PIN3_bm));
RTC_SCL_UP;
delay_ms(1);
RTC_SCL_DOWN;
delay_ms(1);
}
return buffer;
}

void RTC_ACKNOWLEGDGE_0()
{
RTC_DATA_DIR_SET;
RTC_DATA_SET;
delay_ms(1);
RTC_SCL_UP;
delay_ms(1);
RTC_SCL_DOWN;
delay_ms(1);
}

void RTC_ACKNOWLEGDGE_1()
{
RTC_DATA_DIR_SET;
RTC_DATA_CLR;
delay_ms(1);
RTC_SCL_UP;
delay_ms(1);
RTC_SCL_DOWN;
delay_ms(1);
}


Сообщение отредактировал IgorKossak - Jul 6 2011, 20:08
Причина редактирования: [codebox]!!!
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 24)
alexeyv
сообщение Jul 7 2011, 04:55
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Код
void rtc_write (unsigned char buffer)
{
    unsigned char MASK;
    RTC_DATA_DIR_SET;
    for(i=8;i>=0;--i)
                  {
                     ...
                   MASK>>1;
                     ....
                  }
.............
.............
}


1. Где первоначальное задание значения MASK ?? (по умолчанию=0)
2. MASK>>1; - переменная сдвигается (ноль сдвинуть влево!!) , но никуда не записывается, надо "MASK>>=1;"

Код
unsigned char read_rtc()
{
    unsigned char buffer=0;
    RTC_DATA_DIR_CLR;
    for(i=8;i>=0;--i)
   {
        buffer|=((buffer<<1)||(PORTE.IN&PIN3_bm));
        RTC_SCL_UP;
        delay_ms(1);      
        RTC_SCL_DOWN;
        delay_ms(1);    
    }    
    return buffer;
}


Значение с шины надо считывать ПОСЛЕ подачи тактового сигнала!


И вообще, где код вызывающий эти функции, сами они никогда не исполнятся?
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 06:04
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата
Значение с шины надо считывать ПОСЛЕ подачи тактового сигнала!

Это пропустил.

Цитата
unsigned char MASK;
ошибка при копировании. unsigned char MASK=0х80

Цитата
И вообще, где код вызывающий эти функции, сами они никогда не исполнятся?



Собственно код
Код
    rtc_start();                           //старт
    rtc_write (DS1338W);           // адрес устройства, + запись. DS1338W=0xD0
    rtc_write (SecondsReg);       // Регистр секунд
    rtc_write (0x7f);
    rtc_write (0x3f);
    rtc_write (0xff);  
    rtc_write (0xff);
    rtc_write (0xff);
    rtc_write (0xff);
    rtc_write (0xff);
    rtc_stop();

//При чтении
rtc_start();
    rtc_write (DS1338R);            // адрес устройства, + чтение DS1338R=0xD1
    RTC_ACKNOWLEGDGE_1();
    rtc_write (SecondsReg);
    RTC_ACKNOWLEGDGE_1();  
    rtcTime.seconds=read_rtc();
    RTC_ACKNOWLEGDGE_1();
    rtcTime.minutes=read_rtc();  
    RTC_ACKNOWLEGDGE_1();  
    rtcTime.hours=read_rtc();
    RTC_ACKNOWLEGDGE_1();
    rtcTime.day=read_rtc();;
    RTC_ACKNOWLEGDGE_1();  
    rtcTime.date=read_rtc();
    RTC_ACKNOWLEGDGE_1();
    rtcTime.month=read_rtc();
    RTC_ACKNOWLEGDGE_1();
    rtcTime.year=read_rtc();
    RTC_ACKNOWLEGDGE_0();
    rtc_stop();


Сообщение отредактировал Pavel_Bor - Jul 7 2011, 06:06
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 06:39
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



1. А это исправил?
Цитата
2. MASK>>1; - переменная сдвигается (ноль сдвинуть влево!!) , но никуда не записывается, надо "MASK>>=1;"


2. Посмотри осциллографом сигналы на шине, в частности наличие сигнала АСК от часов

3. Формат записи в регистры не правильный
Код
    rtc_write (SecondsReg);       // Регистр секунд
    rtc_write (0x7f);
    rtc_write (0x3f);
    rtc_write (0xff);  
    rtc_write (0xff);
    rtc_write (0xff);
    rtc_write (0xff);


Из даташита:
Прикрепленное изображение


то есть время/дата записывается в формате BCD

4. Общие замечания: имена макросов - прописными буквами, локальных переменных - строчными, глобальных переменных и функций - не полностью прописными

5. Где объявлены переменные i в rtc_write и read_rtc? По сути они должны быть локальные, а не глобальные


Сообщение отредактировал alexeyv - Jul 7 2011, 06:46
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 07:18
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата
1. А это исправил?

написал по другому

if(buffer&&0x80)
....
buffer=buffer<<1;


Цитата
2. Посмотри осциллографом сигналы на шине, в частности наличие сигнала АСК от часов

Нету высокого уровня сигнала тактирования

Цитата
Формат записи в регистры не правильный

Знаю, но щас смысл передать хоть что-то

Цитата
4. Общие замечания: имена макросов - прописными буквами, локальных переменных - строчными, глобальных переменных и функций - не полностью прописными

кто как привык..

Цитата
5. Где объявлены переменные i в rtc_write и read_rtc? По сути они должны быть локальные, а не глобальные

Перевел в локальную. Была глобальная

Сообщение отредактировал Pavel_Bor - Jul 7 2011, 07:37
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 07:52
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



1. А не забыл в rtc_init что-то типа RTC_SCL_DIR_SET; ??

2. Не правильно!!

Цитата
написал по другому

if(buffer&&0x80)


Это у тебя логическое выражение, а тебе надо битовое, вместо "&&" надо использовать "&"

3.
Цитата
кто как привык..


Судя по коду, ты еще не привык. Так что привыкай использовать принятые соглашения. Почитай книжку Ален И. Голуб. "ВЕРЕВКА ДОСТАТОЧНОЙ ДЛИНЫ, ЧТОБЫ…" Москва 2001г. Будет интересно.

Сообщение отредактировал alexeyv - Jul 7 2011, 08:03
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 08:11
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



RTC_SCL_DIR_SET; в инициализации портов

Цитата
Это у тебя логическое выражение, а тебе надо битовое, вместо "&&" надо использовать "&"

"&"="*"
"&&"="и"

За книжку отдельное спасибо.

Сообщение отредактировал Pavel_Bor - Jul 7 2011, 08:18
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 08:36
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
"&"="*"
"&&"="и"


Неужели!!!!

Почитай еще книгу "Д. Ричи. Б. Керниган. Язык Си." Желательно 2-е издание.

"&" == порязрядное "И"
"&&" == логическое "И"

можешь проверить:
Код
0x02 & 0x04   == 0x00;
0x06 & 0x04   == 0x04;
0x02 && 0x04 == 0x01;
0x02 * 0x04   == 0x08;



Цитата
RTC_SCL_DIR_SET; в инициализации портов


В первом листинге не было!!!

Сообщение отредактировал alexeyv - Jul 7 2011, 08:39
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 08:51
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата
В первом листинге не было!!!


я в листинг не включал.
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 09:01
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
я в листинг не включал.


Так может ошибки в тех местах, которых нет в листинге? Весь код относящийся к одному определенному объекту нужно держать в одном месте, а не размазывать по всей программе
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 09:09
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(alexeyv @ Jul 7 2011, 12:01) *
Так может ошибки в тех местах, которых нет в листинге? Весь код относящийся к одному определенному объекту нужно держать в одном месте, а не размазывать по всей программе


Есть первый шаг. Получил ответ от часиков в виде данных: 248 из все регистров. (я так понимаю что это 0xff или пустое место памяти)

Сообщение отредактировал Pavel_Bor - Jul 7 2011, 09:14
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 09:17
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Поздравляю!
Только 248=0xF8, а 0xFF=255.

Сообщение отредактировал alexeyv - Jul 7 2011, 09:19
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 09:29
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(alexeyv @ Jul 7 2011, 12:17) *
Только 248=0xF8, а 0xFF=255.

))
Это пустое место?

по поводу Acknowledge.
При записи между байтами необходимо ждать 0 в DATA
А при чтении отправлять?

Сообщение отредактировал Pavel_Bor - Jul 7 2011, 10:16
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 10:23
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



В функции rtc_write после цикла выставления байта на шину, необходимо выставить данные=1, для того, что бы после дополнительного клока проанализировать принятый от часов бит АСК

Цитата
А при чтении отправлять?


Да. Бит АСК всегда формирует приемник. При записи - это часы, при чтении - проц. При чтении последнего байта - формирование NACK

Сообщение отредактировал alexeyv - Jul 7 2011, 10:25
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 10:36
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Код

bool RTC_ACKW()
{
    RTC_DATA_DIR_CLR;          
    RTC_SCL_DOWN;
    delay_us(100);
    RTC_SCL_UP;
    while(PORTE.IN&PIN3_bm!=0);
    delay_us(100);      
    RTC_SCL_DOWN;
    delay_us(100);
    return 1;
              
}

void RTC_ACKR()
{
    RTC_DATA_DIR_SET;
    RTC_DATA_SET;
    delay_us(100);          
    RTC_SCL_UP;
    delay_us(100);          
    RTC_SCL_DOWN;
    delay_us(100);          
}


так пойдет?

Сообщение отредактировал Pavel_Bor - Jul 7 2011, 10:43
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 10:56
Сообщение #16


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



функцию контроля АСК проще сделать не отдельно, а в rtc_write - выдавать как результат работы функции
функцию посылки АСК проще сделать не отдельно, а в read_rtc - принимать как параметр 1= выдача АСК, 0 - выдача НАК

Маленький вопрос. Подтягивающие резисторы на линиях SCL и SDA есть?

Посмотри здесь

Оссобенно изучи пост №18.

Сообщение отредактировал alexeyv - Jul 7 2011, 11:05
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 11:04
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата
Маленький вопрос. Подтягивающие резисторы на линиях SCL и SDA есть?

Подтяжек нет.



Цитата
Маленький вопрос. Подтягивающие резисторы на линиях SCL и SDA есть?

Подтяжек нет.

Цитата
В функции rtc_write после цикла выставления байта на шину, необходимо выставить данные=1, для того, что бы после дополнительного клока проанализировать принятый от часов бит АСК

Направление порта должно быть входом иначе не видно будет АСК. Но какой тогда смысл выставлять данные в 1?
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 7 2011, 11:09
Сообщение #18


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
Направление порта должно быть входом иначе не видно будет АСК. Но какой тогда смысл выставлять данные в 1?


В смысле необходимо переключить порт (DDR_X) как вход, но перед этим записать в PORT_X единицу - этим включаются подтягивающие резисторы на порту

посмотри пост №18

в архиве - исходники
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 7 2011, 11:21
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Цитата(alexeyv @ Jul 7 2011, 14:09) *
В смысле необходимо переключить порт (DDR_X) как вход, но перед этим записать в PORT_X единицу - этим включаются подтягивающие резисторы на порту

посмотри пост №18

в архиве - исходники


а внешние подтягивающие резисторы в схеме нужны?
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 8 2011, 03:00
Сообщение #20


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата(Pavel_Bor @ Jul 7 2011, 16:21) *
а внешние подтягивающие резисторы в схеме нужны?


Подтягивающие резисторы обычно рекомендуют ставить.

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

Сообщение отредактировал alexeyv - Jul 8 2011, 03:00
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 8 2011, 07:23
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Я так понимаю время задержки между тактами значения не имеет. Главное чтобы оно было больше минимального.
Когда программа получает АСК, пока SCL в "1" ACK никуда не денется до тех пор пока SCL не станет "0"?

Есть шаг №2. Читаю с регистров 0. Пошли часы)

Не получается записать в регистры новые значения.
текущий программа для записи:
Код
void i2c_tx_soft(unsigned char byte)
{
  
  unsigned char count;
  RTC_DATA_DIR_SET;
  if(i2c_error_soft)
    return;
  for(count=0;count<8;count++)
    {
      if(byte&0x80)
        RTC_DATA_SET;
      else
        RTC_DATA_CLR;
      RTC_SCL_UP;
      delay_ms(5);
      RTC_SCL_DOWN;
      delay_ms(5);
      byte<<=1;
    }
  RTC_DATA_DIR_CLR;
  RTC_SCL_UP;
  delay_ms(5);
  while(in_sda());
  delay_ms(5);
  RTC_SCL_DOWN;
  delay_ms(5);
  RTC_DATA_DIR_SET;
}


Вызов ее вот отсюда
Код
void rtc_set_time(unsigned char hours, unsigned char minutes, unsigned char seconds)
{
  i2c_start_soft();
  i2c_tx_soft(DS1338_ADDR|WR);
  i2c_tx_soft(0);
  i2c_tx_soft(dec2bcd(seconds));
  i2c_tx_soft(dec2bcd(minutes));
  i2c_tx_soft(dec2bcd(hours));

  i2c_stop_soft();
}


void rtc_set_date(unsigned char date, unsigned char month, unsigned int year)
{
  i2c_start_soft();
  i2c_tx_soft(DS1338_ADDR|WR);
  i2c_tx_soft(3);
  i2c_tx_soft(dec2bcd(rtcTime.day));
  i2c_tx_soft(dec2bcd(date));
  i2c_tx_soft(dec2bcd(month));
  i2c_tx_soft(dec2bcd(year));
  i2c_stop_soft();
}


Сообщение отредактировал Pavel_Bor - Jul 8 2011, 12:11
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 11 2011, 04:39
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
while(in_sda());


Во время подачи клока, по одному фронту производится выставление данных передатчиком(в данном случае мастером), а по другому фронту - считывание приемником ( в данном случае слейвом)!
Ждать до бесконечности появления нуля на шине SDA (ACK) НЕЛЬЗЯ, т.к. при подаче фронта SCL слейв ОБЯЗАН выставить ACK, иначе это говорит об отсутствии устройства (слейва) на шине!

Посмотри осциллографом физическое наличие сигнала АСК на шине.

Еще вопрос - какие-либо прерывания в программе используются ?

Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 11 2011, 11:37
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



С часами уже все ок)
Значение с внешнего RTC (DS1338) передается на внутренний RTC при включении контроллера. Добавлена проверка на отключение батарейки.
Прерываний будет много но со временем. (клавиатура, АЦП, УАРТ...)

Может системой событий воспользоваться..?
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Jul 11 2011, 12:10
Сообщение #24


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
Прерываний будет много но со временем. (клавиатура, АЦП, УАРТ...)


Тогда желательно в функциях чтения/записи I2C расставить:
1. в начале обмена - сохранение регистра статуса и глобальный запрет прерываний
2. в конце обмена - восстановление регистра статуса

Это необходимо для сохранения временных параметров доступа к шине.
Go to the top of the page
 
+Quote Post
Pavel_Bor
сообщение Jul 11 2011, 13:29
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 115
Регистрация: 15-04-10
Из: Украина
Пользователь №: 56 660



Сделаем. Спасибо

Сообщение отредактировал Pavel_Bor - Jul 11 2011, 13:29
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 13:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01619 секунд с 7
ELECTRONIX ©2004-2016