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

 
 
 
Reply to this topicStart new topic
> SAM7X + DS1340
athlon64
сообщение Jun 28 2010, 06:37
Сообщение #1


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Реализую чтение и запись даты и времени, на SAM7X512 в IAR 5.4.
Сначала чтение сделал за один проход как чтение из микросхемы с внутренним адресом. Т.е. устанавливал внутренний адрес 0x08 и читал 9 байт.
Считывалась последовательность байт: 0xA9 0x80 0x13 0x19 0x00 0xFF 0xFF 0x00 0x00. Причём секунды и минуты (0x13 и 0x19) тикают и изменяются верно, часы и дату пока проверить не успел. Но с датой какая то ерунда - читается 45.00.0000.
Пробовал сделать чтение регистров как сказано в даташите на ds1340, т.е. сначала запись 1 байта адреса регистра, а затем повторный старт на чтение. Считывается та же последовательность байт. Осциллограммы обоих вариантов в приложении. Смутило на осциллограммах что нет межбайтовых интервалов, при обмене с другими модулями (на меге8, меге32) интервалы присутствуют.
В чём может быть подвох?

В основной программе:
Код
StateTWI=ReadRTC;
EndDataInTWI=9;
PtrDataInTWI=0;    // Будет прочитан ответ 9 байт
AT91C_BASE_TWI->TWI_MMR = (1 << 8) | AT91C_TWI_MREAD | ((CntAddrTWI >> 1) << 16); // 1-байтовый внутренний адрес
AT91C_BASE_TWI->TWI_IADR = 0x08;                                        // Начальный адрес регистров RTC
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;                               // START
AT91C_BASE_TWI->TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_TXCOMP;           // Ловить будем получение байта и окончание обмена по NACK на адрес

В обработчике прерывания от TWI:
Код
unsigned int status = AT91C_BASE_TWI->TWI_SR;    // читаем статус TWI

if (status & AT91C_TWI_RXRDY)       // Сначала был получен байт от модуля (до окончания обмена)  // Устройство отправило в CPU байт
{
DataInTWI[PtrDataInTWI]=AT91C_BASE_TWI->TWI_RHR;    // Прочитали очередной байт
if (++PtrDataInTWI >= (EndDataInTWI-1))           // Если принят предпоследний байт
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;        // STOP. После этого будет принят последний байт по событию TWI_TXCOMP
}
    
if (status & AT91C_TWI_TXCOMP)      // Пришёл последний байт от  устройства
{
DataInTWI[PtrDataInTWI] = AT91C_BASE_TWI->TWI_RHR;
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;          // STOP
AT91C_BASE_TWI->TWI_IDR = 0xFFFFFF;               // Выключаем все прерывания от TWI
StateTWI=255;                                     // Ставим признак свободного TWI

//////------- Отладочный вывод в COM-порт принятого пакета --------
      unsigned char i;
      for (i=0;i<(EndDataInTWI+1);i++)
        AddToRS(DataInTWI[i]);
      AddToRS(0x7E);
//////--------------------------------------------------------------------------
PoiskTWI |= fPoiskTWIData;                        // Ставим флаг - Есть пакет на обработку
}


Сообщение отредактировал athlon64 - Jun 28 2010, 06:48
Эскизы прикрепленных изображений
Прикрепленное изображение
Прикрепленное изображение
 


--------------------
Руслан
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 28 2010, 06:56
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Если коротко, то есть два пути:
1. Всеми правдами и неправдами заставить работать TWI (еррату, аппноты почитать, поэкспериментировать и т.п.)
2. Использовать программный I2C

Советую выбрать второй.
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 28 2010, 07:37
Сообщение #3


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Цитата(aaarrr @ Jun 28 2010, 12:56) *
Если коротко, то есть два пути:
1. Всеми правдами и неправдами заставить работать TWI (еррату, аппноты почитать, поэкспериментировать и т.п.)
2. Использовать программный I2C

Советую выбрать второй.

Боюсь программный I2C - не вариант.
Устройство должно каждые 2.5мс опрашивать очередной модуль и в фоне вести кучу рассчётов и формировать ответы в ком-порты максимально быстро sad.gif


Пробую читать разное количество регистров, все значения те же, что и при считывании пачкой, ну кроме секунд и минут которые уже натикали.
Ощущение что глюк не с I2C связан.
Вопрос:
Если случайно записать в регистр (скажем по адресу 0x04H (день месяца) байт 0xFF), при чтении этого регистра будет читаться 0xFF до истечения суток по часам?


--------------------
Руслан
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 28 2010, 08:24
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(athlon64 @ Jun 28 2010, 11:37) *
Боюсь программный I2C - не вариант.
Устройство должно каждые 2.5мс опрашивать очередной модуль и в фоне вести кучу рассчётов и формировать ответы в ком-порты максимально быстро sad.gif

Ну, смотрите. Наше дело предупредить wink.gif

Цитата(athlon64 @ Jun 28 2010, 11:37) *
Вопрос:
Если случайно записать в регистр (скажем по адресу 0x04H (день месяца) байт 0xFF), при чтении этого регистра будет читаться 0xFF до истечения суток по часам?

Насколько я помню, он моментально урезается в этом случае, т.е. лишних бит нет физически.
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 28 2010, 11:25
Сообщение #5


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Цитата(aaarrr @ Jun 28 2010, 14:24) *
Ну, смотрите. Наше дело предупредить wink.gif

smile.gif Обидно просто что со всеми другими модулями сделать обмен получилось, а с RTC запара

Цитата(aaarrr @ Jun 28 2010, 14:24) *
Насколько я помню, он моментально урезается в этом случае, т.е. лишних бит нет физически.

Видимо нет. Взял такую же плату с SAM7X512 и DS1340, но без батарейки. После каждого сброса питания и до попытки синхронизировать время дата и время в RTC корректные 00:00:00 01.01.00. После записи в RTC - 45:85:85 45.25.2145, хотя судя по осциллограммам (если отключить весь остальной обмен и оставить только запись в RTC) запись проходит верно. Запутался в общем sad.gif

Сообщение отредактировал athlon64 - Jun 28 2010, 11:27


--------------------
Руслан
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 28 2010, 13:40
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Было , такое правдо не с ARM. Теперь , перед тем как , что -то писать в DS устанавливаю его на нулевой регистр, а эатем пишу. Если регистры прочитать не все , то следущее чтение начнётся с регистра не прочитанного в предыдущем чтении.
И данные Вы записываете в BCD?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 29 2010, 06:01
Сообщение #7


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Цитата(ILYAUL @ Jun 28 2010, 19:40) *
Было , такое правдо не с ARM. Теперь , перед тем как , что -то писать в DS устанавливаю его на нулевой регистр, а эатем пишу. Если регистры прочитать не все , то следущее чтение начнётся с регистра не прочитанного в предыдущем чтении.
И данные Вы записываете в BCD?

Данные записываю, конечно, закодированные в BCD.
Всегда пишу и читаю по предварительно переданному адресу регистра. Пробовал писать отдельные регистры и все 10 регистров пачкой.
Оставлял часы тикать на ночь, читая с RTC 3 раза в секунду время-дату и передавая в ком-порт. На утро часы верно насчитали прошедшие 15 часов, дата осталась корректной. Т.е. с чтением проблем нет.
Снял сегодня осциллограмму записи в RTC пачки 10 регистров начиная с адреса 0x08.

Посылка (на дату-время 10:58:36 29.06.30):
Цитата
0x08(адрес) 0xA9 0x00 0x36 0x58 0x10 0x29 0x29 0x06 0x30 0x00
соответствует осциллограмме, единственное межбайтовых интервалов нет, всё засылается сплошняком. Читается мусор типа 00:14:10 45.00.00.

Код начала записи:
Код
  StateTWI = WriteData;       // Будем писать в модуль
    EndDataOutTWI=11;
    DataOutTWI[0]=0x08;
    DataOutTWI[1]=0xa9;
    DataOutTWI[2]=0;
    DataOutTWI[3]=0x36;
    DataOutTWI[4]=0x58;
    DataOutTWI[5]=0x10;
    DataOutTWI[6]=0x29;
    DataOutTWI[7]=0x29;
    DataOutTWI[8]=0x06;
    DataOutTWI[9]=0x30;
    DataOutTWI[10]=0;

  PtrDataOutTWI=1;                                    // Т.к. 0й байт уже передан, продолжаем с 1
  
  AT91C_BASE_TWI->TWI_MMR = (CntAddrTWI >> 1) << 16;  // Задаём адрес для записи в модуль
  AT91C_BASE_TWI->TWI_IADR = 0;                       // Начальный адрес регистра 0x08
  AT91C_BASE_TWI->TWI_THR = DataOutTWI[0];            // Передаём на запись первый байт буфера
  AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;           // START
  AT91C_BASE_TWI->TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK; // Ловить будем успешные отправки байт и неподтверждённые приёмником посылки


Код в обработчике прерывания:
Код
  unsigned int status = AT91C_BASE_TWI->TWI_SR;    // Читаем статус TWI
    if (status & AT91C_TWI_TXRDY)                 // Прошлый байт был принят приёмником (получен ACK)
    {
      if (PtrDataOutTWI >= (EndDataOutTWI))                 // Если последний байт
      {
        AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;                  // STOP
        AT91C_BASE_TWI->TWI_IDR = 0xFFFFFF;                       // Выключаем все прерывания от TWI
        StateTWI=255;                                             // Ставим признак свободного TWI
      }
      else
        AT91C_BASE_TWI->TWI_THR = DataOutTWI[PtrDataOutTWI++];    // Передаём очередной байт данных
    }
    
    if (status & AT91C_TWI_NACK)                  // Прошлый байт не был успешно принят приёмником (получен NACK)
    {
      LedErrorOn();                                             // Мигнём индикатором "Ошибка"
      AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP;                  // STOP
      AT91C_BASE_TWI->TWI_IDR = 0xFFFFFF;                       // Выключаем все прерывания от TWI
      StateTWI=255;                                             // Ставим признак свободного TWI
    }


В принципе запись в RTC будет выполняться не чаще чем раз в час, можно и пинодрыганием сделать.
Может у кого нибудь есть пример? Как реализовать задержки?
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Руслан
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 29 2010, 06:54
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



А если попробывать писать не c 0x08 , а с 0x00 т.е сначала секунды. Записать 0x36 0x58 0x10 0x29 0x29 0x06 0x30 И не запуская счёт - прочитать .
Цитата
AT91C_BASE_TWI->TWI_MMR = (CntAddrTWI >> 1) << 16; // Задаём адрес для записи в модуль
И извините я это не понял. Так Вы задаёте Slaveadr?

И почему у Вас день недели 29-ый их всего 7 и год какойто странный? И Вы про него не забываете (день недели), когда декодируете часы
Цитата
Читается мусор типа 00:14:10 45.00.00.
я его здесь не вижу


Цитата
00,$18,$09,$02,$29,$06,$10
как-то так


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 29 2010, 07:59
Сообщение #9


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Цитата(ILYAUL @ Jun 29 2010, 12:54) *
А если попробывать писать не c 0x08 , а с 0x00 т.е сначала секунды. Записать 0x36 0x58 0x10 0x29 0x29 0x06 0x30 И не запуская счёт - прочитать.

Записал с 0 адреса последовательность: 0x36 0x58 0x10 0x02 0x29 0x06 0x30
Сразу читаю с 0 адреса: 0x02 0xFF 0xFF 0x00 0x00 0x14 0x10

Цитата(ILYAUL @ Jun 29 2010, 12:54) *
И извините я это не понял. Так Вы задаёте Slaveadr?

У меня просто адреса i2c устройств везде в программе 8-битные. Смещением на 1 вправо я убираю лишний бит, после чего пишу его в TWI_MMR

Цитата(ILYAUL @ Jun 29 2010, 12:54) *
И почему у Вас день недели 29-ый их всего 7 и год какойто странный? И Вы про него не забываете (день недели), когда декодируете часы я его здесь не вижу

В программе день недели не используется, я в него писал дату, т.к. он всё равно урежется. Выше я вместо дня недели писал 0x02, это ничего не изменило, к сожалению smile.gif


--------------------
Руслан
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jun 29 2010, 09:15
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата
У меня просто адреса i2c устройств везде в программе 8-битные. Смещением на 1 вправо я убираю лишний бит, после чего пишу его в TWI_MMR

Slave DS1340 1101000+bit R/W Зачем смещение ? Задайте его как константу , а при чтении прибавляйте 1 и пишите в TWI_MMR.

Цитата
Оставлял часы тикать на ночь, читая с RTC 3 раза в секунду время-дату и передавая в ком-порт. На утро часы верно насчитали прошедшие 15 часов, дата осталась корректной

Уточните - часы Вы инициализировали или они считали с нулей. Т.е после сброса Вы не писали ни время ни даты


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jul 1 2010, 03:46
Сообщение #11


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

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



В общем разобрался с записью в RTC. Была ошибка в обработчике прерывания, из-за чего последний байт слался мусором.
Убрал всё лишнее, оставил только запись и чтение 1 байта в одном и том же регистре DS1340, снял осциллограммы и всё стало понятно.
Интервалов между байтами при обмене с RTC так и нет, на старой версии платы на меге256 они были и при обмене с другими модулями (слейвами) на мегах интервалы есть. Ну пока в общем всё работает.
Теперь сажусь разбираться с I2C EEPROM


--------------------
Руслан
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:12
Рейтинг@Mail.ru


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