Как я понял из даташита в режиме "ожидания" на DS12887 такие сигналы: AS-0, DS-1, R/W-не имеет значения, CS-1, AD0-AD7-не имеет значения. режим записи: 1. R/W=0 2. DS=0 3. AS=1 4. AD0-AD7 устанавливаем адрес (допустим 02H "минуты") 5. CS=0 6. AS=0 (при переходе с 1 в 0 микросхема считывает с AD0-AD7 информацию об адресе) 7. AD0-AD7 устанавливаем данные 8. DS-1 (при переходе с 0 в 1 микросхема считывает с AD0-AD7 данные) после этого CS, AS и DS возврвщаются на исходную: AS-0, DS-1, CS-1. Если не так поправте пожалуйста. По поводу почему выбор пал именно на эту микросхему: Я ее извлек из старой материнской платы. Просто так получилось, что нужно сделать часы на этой микросхеме. (к сожалению я в выборе ограничен)
Добавлено спустя 2 часа 52 минуты 49 секунд: Я тут навоял немного, но почему то не работает. Я пытаюсь записать, а потом считать из пзу DS12877. Подскажите пожалуйста где я ошибся?
Aptem, твой код вроде должен работать. Я особо полно не пытался разобраться ни в коде, ни в работе этой микросхемы, но ты похоже упустил одну маленькую деталь. DS12887 может работать в 2 режимах - Intel Timing и Motorola Timing. Та последовательность сигналов что ты выдаешь соответствует Motorola Timing, а микросхема по умолчанию находится в режиме Intel Timing. Чтобы перевести в режим Motorola Timing, надо на вход MOT (1 нога) подать логическую 1. И еще - на CS и DS между циклами доступа держи лог. 1 (установи ее там в самом начале программы).
Может всетаки кто нибудь мне обьяснит (на пальцах) как просходит чтение/запись?(в какой последовательности что выставляется) Если конечно это не идет в разрез с вашими принципами?
Тоже попалась эта микросхема, решил поиграться с ней. Так как несилен в английском, даже с гуглом, не мого понять как происходит считывание и запись из/в микросхему. Поискал в интенете, нашел http://zxbyte.ru/rtc.htm на русском про режим общения с ней. Набросал программку на Си. Вот часть её:
while(1){ CTRL_DDR=0b11111111;//DDRD, порт на выход для управления
//RST_SET; PORTD = PORTD | 0b10000000;
PORTD = PORTD | 0b00001000; //CS_SET, disable
PORTD = PORTD & 0b10111111; //DS_CLEAR
PORTD = PORTD & 0b11101111; //AS_CLR;
PORTD = PORTD & 0b11011111; //RW_CLR;
_delay_ms(1);
PORTD = PORTD & 0b11110111; //CS_CLR, enable разрешаем работу
_delay_us(5);
AD_DDR=0xff; //шина адреса-данных на выход
PORTC = 0x00; // адрес ячейки, секунды
PORTD = PORTD | 0b01000000; //DS_SET;
PORTD = PORTD | 0b00010000; //AS_SET;
_delay_us(5);
PORTD = PORTD & 0b11101111; //AS_CLR строб передачи адреса
_delay_us(5);
AD_DDR=0x00; //шина адреса-данных на вход
_delay_us(5);
PORTD = PORTD & 0b10111111; //DS_CLR
_delay_us(5);
PORTD = PORTD | 0b01000000; //DS_SET строб считывания данных с шины
sec=PORTC;
} return 0; }
Итог - считывается то, что и записывается. Даже если микросхему вытащить из панельки - результат не меняется. Не пойму где делаю что-то нет так. То ли микросхема неисправна, то ли я с мультиплексироаной шиной работаю неправильно.
А почему не завести отдельную переменную - теневой регистр порта D ? Меняй все в этом регистре, а потом выводи его в порт. А то на 16 мгц. проца можно словить глюк медленности переключения пинов:
Если это отрабатывается как "чтение - модификация - запись", что очень вероятно, то первая команда сбрасывает бит (4-й), но реально он сбросится где-то хз на каком такте проца. А след. за ней команда сбрасывает 5-й бит, но 4-й еще не сбросился и в результате в 4-й бит запишется "1" : 0bxxx1xxxx & 0b11011111 = 0bxx01xxxx
Надеюсь ни чо не перепутал. Мои слова не нести в банк
Здесь всё так просто я записал чтоб мне наглядней было. Первоначально я изменения битов в порту делал макросами. Микросхема никак не реагировала. Расписал для себя всё развернуто. Команды выдачи управляющих сигналов реализованы согласно (ну насколько я понял) режимам из даташита и того линка что привел. Да, здесь отрабатывается как "чтение - модификация - запись" Да, возможно здесь сыграла роль медленность переключения порта, надо будет поставить задержки. Проц работает на внутреннем генераторе 8 МГц. Но интересно другое, если вынимаю часы из панельки, то потом при чтении порта (который адрес-данные) читается то же, что и записывалось. Может я неправильно работаю с шиной на выход, потом на вход? AD_DDR=0xff; //шина адреса-данных на выход для выдачи адреса ячейки/регистра .... PORTC = 0x00; // адрес ячейки, секунды. Собственно сама выдача .... AD_DDR=0x00; //шина адреса-данных на вход для считывания из часов