|
|
  |
SAM7X + DS1340 |
|
|
|
Jun 28 2010, 06:37
|

Частый гость
 
Группа: Свой
Сообщений: 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
Эскизы прикрепленных изображений
--------------------
Руслан
|
|
|
|
|
Jun 28 2010, 07:37
|

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

|
Цитата(aaarrr @ Jun 28 2010, 12:56)  Если коротко, то есть два пути: 1. Всеми правдами и неправдами заставить работать TWI (еррату, аппноты почитать, поэкспериментировать и т.п.) 2. Использовать программный I2C
Советую выбрать второй. Боюсь программный I2C - не вариант. Устройство должно каждые 2.5мс опрашивать очередной модуль и в фоне вести кучу рассчётов и формировать ответы в ком-порты максимально быстро  Пробую читать разное количество регистров, все значения те же, что и при считывании пачкой, ну кроме секунд и минут которые уже натикали. Ощущение что глюк не с I2C связан. Вопрос: Если случайно записать в регистр (скажем по адресу 0x04H (день месяца) байт 0xFF), при чтении этого регистра будет читаться 0xFF до истечения суток по часам?
--------------------
Руслан
|
|
|
|
|
Jun 28 2010, 11:25
|

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

|
Цитата(aaarrr @ Jun 28 2010, 14:24)  Ну, смотрите. Наше дело предупредить   Обидно просто что со всеми другими модулями сделать обмен получилось, а с RTC запара Цитата(aaarrr @ Jun 28 2010, 14:24)  Насколько я помню, он моментально урезается в этом случае, т.е. лишних бит нет физически. Видимо нет. Взял такую же плату с SAM7X512 и DS1340, но без батарейки. После каждого сброса питания и до попытки синхронизировать время дата и время в RTC корректные 00:00:00 01.01.00. После записи в RTC - 45:85:85 45.25.2145, хотя судя по осциллограммам (если отключить весь остальной обмен и оставить только запись в RTC) запись проходит верно. Запутался в общем
Сообщение отредактировал athlon64 - Jun 28 2010, 11:27
--------------------
Руслан
|
|
|
|
|
Jun 29 2010, 06:01
|

Частый гость
 
Группа: Свой
Сообщений: 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 будет выполняться не чаще чем раз в час, можно и пинодрыганием сделать. Может у кого нибудь есть пример? Как реализовать задержки?
Эскизы прикрепленных изображений
--------------------
Руслан
|
|
|
|
|
Jun 29 2010, 06:54
|

Профессионал
    
Группа: Свой
Сообщений: 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 как-то так
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Jun 29 2010, 07:59
|

Частый гость
 
Группа: Свой
Сообщений: 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, это ничего не изменило, к сожалению
--------------------
Руслан
|
|
|
|
|
Jun 29 2010, 09:15
|

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

|
Цитата У меня просто адреса i2c устройств везде в программе 8-битные. Смещением на 1 вправо я убираю лишний бит, после чего пишу его в TWI_MMR Slave DS1340 1101000+bit R/W Зачем смещение ? Задайте его как константу , а при чтении прибавляйте 1 и пишите в TWI_MMR. Цитата Оставлял часы тикать на ночь, читая с RTC 3 раза в секунду время-дату и передавая в ком-порт. На утро часы верно насчитали прошедшие 15 часов, дата осталась корректной Уточните - часы Вы инициализировали или они считали с нулей. Т.е после сброса Вы не писали ни время ни даты
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|