|
|
  |
i2c: программная реализация без PU, помогите пожалуйста! срочно надо! |
|
|
|
Apr 2 2007, 20:02
|
Частый гость
 
Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397

|
итак, задача: есть готовая схема, расчитанная под 51 проц. надо её пересадить на 8515 -> надо написать драйвер и2ц для общения с часиками 1307 БЕЗ использования подтягивающего резистора на линии СДА и СЦЛ. на 51м работало, на авр - никак не могу завести, а срочно надо. готового нигде не нашёл, попытался написать сам. видимо где-то туплю, подскажите где: Код void i2c_start() { SDA_port = 1; SCL_port = 1; I2CDELAY(); SDA_ddr = 1; SDA_port = 0; I2CDELAY();
SCL_ddr = 1; SCL_port = 0; I2CDELAY(); }
ubyte i2c_wb(ubyte i2c_data) { ubyte i = 8, acknowledge = 0, tmp = 0; do { tmp = i2c_data; SDA_port = (ubyte)(tmp & _0b10000000); i2c_data <<= 1; I2CDELAY(); SCL_port = 1; I2CDELAY(); SCL_port = 0; I2CDELAY(); } while (--i); SDA_ddr = 0; SDA_port = 1; I2CDELAY(); SCL_port = 1; I2CDELAY(); if (!SDA_pin) { acknowledge = 1; *left_7seg = 0xac; // вывожу на индикатор для проверки, пришло ли ацк } SCL_port = 0; I2CDELAY(); SDA_ddr = 1; return acknowledge; } после сброса проца выполняю старт и пишу управляющий байт... АЦК не приходит. пишу в ИАРе.
--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
|
|
|
|
|
Apr 2 2007, 20:43
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(junoSynthesizer @ Apr 2 2007, 20:02)  итак, задача: есть готовая схема, расчитанная под 51 проц. надо её пересадить на 8515 -> надо написать драйвер и2ц для общения с часиками 1307 БЕЗ использования подтягивающего резистора на линии СДА и СЦЛ. на 51м работало, на авр - никак не могу завести, а срочно надо. готового нигде не нашёл, попытался написать сам. видимо где-то туплю, подскажите где: после сброса проца выполняю старт и пишу управляющий байт... АЦК не приходит. пишу в ИАРе.  Сам брал из под GCC. Возможно подправлял чего-то. Возможно вам всё и не надо. Просто не хотелось копаться - скинул всё. У меня работает в IARе. Как с 24с512 так и со своими часами на м88 в режиме эмуляции 24с16. В принципе можно взять только нужные процедуры.
Прикрепленные файлы
i2c.zip ( 5.54 килобайт )
Кол-во скачиваний: 135
|
|
|
|
|
Apr 2 2007, 21:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(junoSynthesizer @ Apr 2 2007, 19:02)  на 51м работало, на авр - никак не могу завести Полагаю, разница в схемотехнике портов. У х51 порты имеют открытый коллектор (сток), в AVR - честные push-pull. Поэтому нельзя в АВР выводить в порт, к которому подключены линии I2C единицы. Надо записать в PORTx нули, и формировать уровень нуля переводом линии на вывод (DDRx = 1), а единицы - переводом линии на ввод (DDRx = 0). Надеюсь, подтяжки снаружи стоят?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 2 2007, 21:48
|
Частый гость
 
Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397

|
Цитата(Сергей Борщ @ Apr 2 2007, 21:26)  Надеюсь, подтяжки снаружи стоят? в вопросе ниписано - "программная реализация без PU"... а вообще - спасибо 2 SasaVitebsk огромное! затикали!
--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
|
|
|
|
|
Apr 2 2007, 22:15
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(junoSynthesizer @ Apr 2 2007, 20:48)  в вопросе ниписано - "программная реализация без PU"... Ах это вы подтяжки (Pull-ups) так обозвали? Ну тогда извините - я подумал что это вы про внутренний модуль периферии. Сокращение какое-то совсем не общепринятое. Ну тогда отвечу так - в x51 верхняя подтяжка включена всегда, в AVR - только если вы настроили ногу на ввод и записали в PORTx единицу. Поэтому добавлю, что для получения единицы на линии I2C надо сначала перевести ножку на ввод (DDRx = 0) а затем включить подтяжку (PORTx = 1). Для выдачи нуля последовательность должна быть обратной - отключаем подтяжку (PORTx = 0), переводим на вывод (DDRx = 1). Причем сопротивление этой подтяжки ненормировано и на порядки(!) выше необходимых для I2C. Поэтому их использование для I2C - чистейшее радиолюбительство в худшем смысле этого слова, ставить такое в изделие не "для себя" нельзя, и даже если оно сейчас и заработало - вы можете получить самые разные ошибки в работе, которые будут объясняться только одним - несоблюдением спецификации на шину I2C. И все это веселье вы хотите получить пожалев пару резисторов??? Не меньший набор сбоев вы можете получить если будете пытаться выводить "честную" (PORTx=1, DDRx=1) единицу на линии I2C. Поэтому когда у вас начнутся чудеса, вы в свой следующий вопрос ("Почему не работает/сбоит/иногда все рушится") обязательно добавьте, что грубо нарушили спецификацию I2C и это будет 100% правильного ответа уже в самом вопросе. P.S. Посмотрел код от SasaVitebsk - вторая проблема (выдача "честной" единицы) в полном объеме. Хотите убедиться? Включите в разрыв линии SDA резистор 100 ом, сделайте тестовую програму цикл { старт-команда чтения-чтение байта(NACK) стоп } и наблюдайте осциллографом в момент, когда микросхема выдает ACK на команду чтения и в момент начала формирования NACK третий уровень - т.е. конфликт, когда вы выдаете единицу, а внешнее устройство выдает ноль. Согласитесь, этот конфликт - отнюдь не штатный режим работы схемы. У меня в 1995 выходной каскад микрочиповской памяти примерно через неделю деградировал настолько, что уже не мог сформировать уровень лог. нуля при подтяжке 4.7К. С тех пор я по этим граблям не хожу и хочу вас предостеречь. Возможно сейчас схемотехника и технология кристаллов изменились, но этот конфликт уровней может вылезти где-нибудь, где вы его совсем не ждете - в увеличении общего потребляемого тока, в импульсах тока по питанию со всеми вытекающими и т.д.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 2 2007, 22:39
|
Частый гость
 
Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397

|
2Сергей Борщ спасибо за столь полный ответ. а ситуация такая: данная проблема образовалась при написании либ для лабораторного стенда для универа (и одна из них - часики), где из-за универсальности использования одного порта конструкторы решили не цеплять пулл-ап. если бы я делал - я бы не экономил ничего, особенно - если для себя. но поскольку работаем с тем, чем есть... приходится задавать вопрос на форуме =)
--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
|
|
|
|
|
Apr 2 2007, 23:53
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(SasaVitebsk @ Apr 2 2007, 22:22)  В каком месте данный хомут? Код #define I2C_SDL_LO CLEARBIT( SDAPORT, SDA) #define I2C_SDL_HI SETBIT( SDAPORT, SDA)
uint8_t i2cPutbyte(uint8_t b) .............. I2C_SDL_HI; // leave SDL HI // added CLEARBIT(SDADDR, SDA); // change direction to input on SDA line (may not be needed) HDEL; А должно быть Код #define I2C_SDL_LO SETBIT( SDADDR, SDA) #define I2C_SDL_HI CLEARBIT( SDADDR, SDA)
uint8_t i2cPutbyte(uint8_t b) .............. I2C_SDL_HI; // leave SDL HI HDEL;
void i2cInit(void) { I2C_SDL_HI; // set I/O state and pull-ups CLEARBIT( SDAPORT, SDA); // write 0 to SDA output latch ну и то же самое для линии SCL.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 2 2007, 23:55
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(SasaVitebsk @ Apr 3 2007, 00:22)  В каком месте данный хомут? В любом месте где Вы(автор кода) настраиваите порт на выход и тяните к 1. По спецификации i2c тянуть можно только к 0 и это принципиально ! Использовать внутренние PullUP можно, но это сильно ограничит скорость работы i2c (конечно в зависимости от условий работы) Типа, просто проведите тест: Если на 400КГц у Вас все будет работать без ошибок, то смело запускайте на 100КГц и ни о чем не волнуйтесь если конечно условия со временем не поменяются  Цитата а ситуация такая: данная проблема образовалась при написании либ для лабораторного стенда для универа (и одна из них - часики), где из-за универсальности использования одного порта конструкторы решили не цеплять пулл-ап. интересный способ обучения студентов типа, найди ошибку
|
|
|
|
|
Apr 3 2007, 00:16
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(SasaVitebsk @ Apr 3 2007, 01:06)  Можно и нужно будет переписать. (Никому нельзя доверять. Даже западникам.  ) Но на самом деле может приграничная гонка и есть - надо посмотреть, но без мультимастера и при одном общем питании - это не должно привести к выходу из строя микросхемы и к ухудшению скорости. Повторюсь, при своевременном освобождении шины. А вообще конечно надо просто 0/обрыв давать да и всё. Это еще не "гонки". Гонки начинаются когда Вы пытаетесь прикрутить SAM7 и ARV по i2c, особенно если Вы ТОЧНО знаете как должен работать i2c
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|