Гость химик Опубликовано 14 Ноября, 2011 в 17:29 Жалоба Поделиться Опубликовано 14 Ноября, 2011 в 17:29 Я так понимаю, на I2C в твоей реализации сидят 2 слейва - RTC и еще что-то? Конечно, их обоих можно дергать по аппаратной реализации TWI, повесив параллельно на аппаратные выводы SDA и SCL. Надо выбрать частоту шины, поддерживаемую обоими девайсами, и убедиться, что у них разные адреса на шине.Управление аппаратной реализацией очень подробно описано в даташитах на МК. Добавлено после раздумий: Посмотрел исходники из первого поста - там нет i2c.h. Судя по скриншоту из последнего поста, это программная реализация I2C, и её надо удалить из проекта. Из первого поста: My_I2C.h - тоже программная реализация. twi.h - аппаратная реализация, лучше использовать её. Н а i2c у меня сидят 4 слейва. И как я уже писал у меня была проблема, зависание МК. Проблему я нашел в работе шины. А сейчас,как мне кажется проблема найдена в лице DS1307. Она у меня опрашивается в цикле main();, и кажется сбивает шину. Насчет my_i2c.h, так это я ж писал, что пробывал несколько разных библиотек twi, в том числе и i2c, поетому по запарке скинул не тот файл о котором писал. Ниже файл с библиотеками twi и ds1307_twi, там же и хидеры. Для компиляции их нужно поместить в папки программы cvavr inc и lib соответственно. В папке RTC файлы проекта и эмуляции Proteus v7.7. Сейчас компилится нормально, но в Proteus не работает. Получается так, что при запуске эмуляции шина работает 1сек. После обе линии утанавливаются либо в высокий, либо в низкий логический уровень и не с места. Что-то такое я читал про аппаратный twi, что если выскакивает ошибка, появляется бит NACK и вешает шину. Извиняюсь если не правильно высказался. RTC.rar Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость mczarin Опубликовано 14 Ноября, 2011 в 20:29 Жалоба Поделиться Опубликовано 14 Ноября, 2011 в 20:29 (изменено) Увы, никогда не работал в CVAVR, использую IAR, поэтому нюансы, связанные со средой разработки мне недоступны. В ds137_twi.h подключается некий i2c.h, вместо него видимо должен быть twi.h? RTC имеет адреса на запись/чтение 0xD0/0xD1 соотв. Не совпадают ли эти адреса с адресами других устройств на шине? Еще как вариант - какие-нибудь проблемы с таймерами или прерываниями, вдруг они вмешиваются в работу шины. Как-то подозрительно, что шина виснет спустя целую секунду. Хотя вроде бы на PC0 и PC1 висят только TWI и сам порт... Может, попробовать физически отключить от шины все устройства, и затем подключать их по очереди, добиваясь работоспособности поэтапно? Сам когда-то писал работу через аппаратный TWI с RTC PCF8563 и еще одним МК в качестве слейвов, никаких проблем не возникало... Попробую завтра с работы выложить свою библиотеку TWI, если найду. Изменено 14 Ноября, 2011 в 20:29 пользователем mczarin Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость torip3ng Опубликовано 15 Ноября, 2011 в 17:39 Жалоба Поделиться Опубликовано 15 Ноября, 2011 в 17:39 (изменено) Вот самая простаря реализация аппаратного i2c // TWI init TWBR=0x02; TWCR=1<<TWEN; // TWI start TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI write / write addr TWDR = TMP275_adr; TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI read byte TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; temp=TWDR; // TWI stop TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); Смотрим либу цавра ds1307: void rtc_init(unsigned char rs,unsigned char sqwe,unsigned char out) { rs&=3; if (sqwe) rs|=0x10; if (out) rs|=0x80; i2c_start(); i2c_write(0xd0); i2c_write(7); i2c_write(rs); i2c_stop(); } void rtc_get_time(unsigned char *hour,unsigned char *min,unsigned char *sec) { i2c_start(); i2c_write(0xd0); i2c_write(0); i2c_start(); i2c_write(0xd1); *sec=bcd2bin(i2c_read(1)); *min=bcd2bin(i2c_read(1)); *hour=bcd2bin(i2c_read(0)); i2c_stop(); } void rtc_set_time(unsigned char hour,unsigned char min,unsigned char sec) { i2c_start(); i2c_write(0xd0); i2c_write(0); i2c_write(bin2bcd(sec)); i2c_write(bin2bcd(min)); i2c_write(bin2bcd(hour)); i2c_stop(); } void rtc_get_date(unsigned char *date,unsigned char *month,unsigned char *year) { i2c_start(); i2c_write(0xd0); i2c_write(4); i2c_start(); i2c_write(0xd1); *date=bcd2bin(i2c_read(1)); *month=bcd2bin(i2c_read(1)); *year=bcd2bin(i2c_read(0)); i2c_stop(); } void rtc_set_date(unsigned char date,unsigned char month,unsigned char year) { i2c_start(); i2c_write(0xd0); i2c_write(4); i2c_write(bin2bcd(date)); i2c_write(bin2bcd(month)); i2c_write(bin2bcd(year)); i2c_stop(); } И начинаем ее методично переписывать под себя:smile: (приведу пример для одной из ф-ций) void rtc_set_date(unsigned char date,unsigned char month,unsigned char year) { // TWI start TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI write addr TWDR = 0xD0; TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI write TWDR = 4; TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI write TWDR = bin2bcd(date); TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI write TWDR = bin2bcd(month); TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI write TWDR = bin2bcd(year); TWCR = (1<<TWINT)|(1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; // TWI stop TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); } Думаю остальное сами допишите :smile: Изменено 15 Ноября, 2011 в 17:42 пользователем torip3ng Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость химик Опубликовано 15 Ноября, 2011 в 20:01 Жалоба Поделиться Опубликовано 15 Ноября, 2011 в 20:01 Класс !!! А как переписать вот такую строку с указатулем? *date=bcd2bin(i2c_read(1)); Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость torip3ng Опубликовано 15 Ноября, 2011 в 20:04 Жалоба Поделиться Опубликовано 15 Ноября, 2011 в 20:04 //TWI Read byte TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; *date=bcd2bin(TWDR); Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость химик Опубликовано 15 Ноября, 2011 в 20:36 Жалоба Поделиться Опубликовано 15 Ноября, 2011 в 20:36 А еще вот такое data=twi_read(0); Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость torip3ng Опубликовано 15 Ноября, 2011 в 21:31 Жалоба Поделиться Опубликовано 15 Ноября, 2011 в 21:31 (изменено) А еще вот такое data=twi_read(0); //TWI Read byte TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))) {}; data=TWDR; twi_read(0) - 0 означает что мы читаем последний байт с устройства. Изменено 15 Ноября, 2011 в 21:32 пользователем torip3ng Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость химик Опубликовано 16 Ноября, 2011 в 14:44 Жалоба Поделиться Опубликовано 16 Ноября, 2011 в 14:44 Переписал библиотеку, запускаю симуляцию покадрово. Пачка из четырех байт, видимо инициализация часов. Через 0,24сек пошла вторая пачка из 7 байт. И вот здесь видно что условие стоп не появляется, на линии SDA логический 0! Хотя напряжение на нем изменяется пилообразно от 0 до 1 вольта. И дальше, такая "пила" пробегает с интервалом около 0,9сек, появляется и исчезает. Вывод: что то не дает появится условию Stop. Что именно? Последнее обновление файлов:RTC.rar Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость mczarin Опубликовано 16 Ноября, 2011 в 20:10 Жалоба Поделиться Опубликовано 16 Ноября, 2011 в 20:10 Повторюсь, надо вводить сущности постепенно. Иначе искать можно очень долго. Попробуй сначала вообще чистый проект с подключенной библиотекой TWI, который опрашивает RTC в бесконечном цикле (без таймеров, LCD и т.д.). Соотв. в эмуляторе убери из схемы вообще всё, кроме МК и RTC. Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость torip3ng Опубликовано 16 Ноября, 2011 в 20:52 Жалоба Поделиться Опубликовано 16 Ноября, 2011 в 20:52 из rtc.c убрать #asm .equ __i2c_port=0x15;PORTC .equ __sda_bit=1 .equ __scl_bit=0 #endasm из ds1307_twi убрать #include <twi.h> if(PIND.6 == 0){ tmp=bin2bcd (hour); tmp++; if(tmp >= 36) tmp=0; // oгpaничeниe peгyлиpoвки чacoв hour=bcd2bin (tmp); rtc_set_time(hour,min,sec); // yвeличивaeм знaчeниe чacoв надо так if(PIND.6 == 0){ tmp=hour; tmp++; if(tmp >= 24) tmp=0; // oгpaничeниe peгyлиpoвки чacoв hour=tmp; rtc_set_time(hour,min,sec); // yвeличивaeм знaчeниe чacoв в rtc_set_time уже выполняется bcd2bin Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость химик Опубликовано 17 Ноября, 2011 в 17:21 Жалоба Поделиться Опубликовано 17 Ноября, 2011 в 17:21 ...надо так if(PIND.6 == 0){ tmp=hour; tmp++; if(tmp >= 24) tmp=0; // oгpaничeниe peгyлиpoвки чacoв hour=tmp; rtc_set_time(hour,min,sec); // yвeличивaeм знaчeниe чacoв в rtc_set_time уже выполняется bcd2bin Да здесь понял, дважды гоняю байты туда сюда. А в остальном, ото выше что не влияет на работоспособность. Вобщем зависает шина в функции rtc_get_time в строке где должен формироваться импульс Stop, отладка переступает эту строку и на осцилографе видно, что этого условия не произошло. Далее при следующей попытке запустить условие Start, программа зависает на строке Почему не состоялось условие Stop? Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость torip3ng Опубликовано 17 Ноября, 2011 в 17:40 Жалоба Поделиться Опубликовано 17 Ноября, 2011 в 17:40 (изменено) После // TWI stop TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); поставь while (!(TWCR & (1<<TWINT))) {}; и сообщи об результатах :smile: может принудительная отправка NACK нужна протеусу. Изменено 17 Ноября, 2011 в 17:41 пользователем torip3ng Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти