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

 
 
> i2c: программная реализация без PU, помогите пожалуйста! срочно надо!
junoSynthesizer
сообщение Apr 2 2007, 20:02
Сообщение #1


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

Группа: Свой
Сообщений: 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;
}


после сброса проца выполняю старт и пишу управляющий байт... АЦК не приходит. пишу в ИАРе.
help.gif


--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Apr 2 2007, 21:26
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
junoSynthesizer
сообщение Apr 2 2007, 21:48
Сообщение #3


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

Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397



Цитата(Сергей Борщ @ Apr 2 2007, 21:26) *
Надеюсь, подтяжки снаружи стоят?


в вопросе ниписано - "программная реализация без PU"...

а вообще - спасибо 2 SasaVitebsk огромное! затикали!


--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 2 2007, 22:15
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
junoSynthesizer
сообщение Apr 2 2007, 22:39
Сообщение #5


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

Группа: Свой
Сообщений: 83
Регистрация: 25-11-05
Из: odessa
Пользователь №: 11 397



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


--------------------
Вся жизнь - ништяк, все бабы - леди, а солнце - шар дающий свет
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Apr 2 2007, 23:55
Сообщение #6


Гуру
******

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



Цитата(junoSynthesizer @ Apr 2 2007, 21:39) *
данная проблема образовалась при написании либ для лабораторного стенда для универа (и одна из них - часики),
Так прямо на часики пару резисторов и допаять. Они будут очень гармонично составлять одно целое с I2C-устройством.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 07:36
Рейтинг@Mail.ru


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