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

 
 
 
Reply to this topicStart new topic
> i2c в lpc2378, не работает
Ivan_Kov
сообщение Mar 2 2007, 16:14
Сообщение #1


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

Группа: Свой
Сообщений: 174
Регистрация: 30-10-06
Из: г. Курск
Пользователь №: 21 787



lpc работает в режиме master, имеется 1 slave.

Если пытаюсь послать данные, происходит вот что:

1) настраиваю i2c (конфигурация пинов, частота = 200кГц, установка бита i2en)
2) даю старт (бит sta = 1)
3) читаю State. State = 0x8 - ок
4) передаю адрес slave.
5) читаю State. State = 0x18 - ок
6) пишу 1-ый байт данных
7) читаю State. State = 0x8 , а должно быть 0x28

если пытаюсь читать из slave, то возникает аналогичная ситуация - после первой попытки чтения, получаю State = 0x8 , вместо 0x50.

вот осцилограмма SDA и SCL снятая при передачи данных от master к slave Прикрепленный файл  i2c_osc24.zip ( 6.15 килобайт ) Кол-во скачиваний: 154

на ней видно, что сигнал СТАРТ и передача адреса - проходят нормально,
а при передачи первого-же бита данных возникает проблема:
длительность импульса CLK почему-то оказывается увеличенной, и уровень SDA меняется (падает) при высоком уровне CLK. естественно что это не допустимо и, повидимому, расценивается как сигнал старта, от сюда и значение state = 8.
выяснил что такое поведение возникает из-за lpc. Кто-нибудь сталкивался с подобным?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 2 2007, 18:46
Сообщение #2


Гуру
******

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



Цитата(Ivan_Kov @ Mar 2 2007, 15:14) *
выяснил что такое поведение возникает из-за lpc. Кто-нибудь сталкивался с подобным?
Работал с I2C на 2119 год назад. Глянул мануал - модуль I2C там одинаковый. Глянул в исходники - в прерывании после анализа I2CSTAT я сбрасываю биты через I2CCONCLR:
Код
switch(I2STAT) {
        case 0x08:        // Start done
                I2DAT = I2C.DevAddr & ~(1<<0);        // SEND SLA+W
                I2CONCLR = (I2C_INT | I2C_START);
                break;
        case 0x20:        // Slave addr NACK
                I2CONSET = I2C_STOP | I2C_START;        // generate stop
                I2CONCLR = I2C_INT;
                break;
        case 0x18:        // Slave addr ACK
                I2DAT = I2C.Addr;
                I2CONCLR = I2C_INT;
                break;
        case 0x28:        // Byte transfer ACK
                if(I2C.Read) {
                    I2CONSET = I2C_START;        // generate repeated start
                    I2CONCLR = I2C_INT;
                } else {        // Write
                    if(I2C.Counter) {
                        I2DAT = *I2C.pData++;
                        I2C.Counter--;
                    } else {
                        I2CONSET = I2C_STOP;
                        I2C.flag = 0;
                    }
                    I2CONCLR = I2C_INT;
                }
                break;
Затянутый CLK - штатное явление, устройство вправе затягивать clk пока оно занято чем-то другим и таким образом тормозить обмен.


--------------------
На любой вопрос даю любой ответ
"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
Ivan_Kov
сообщение Mar 5 2007, 11:54
Сообщение #3


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

Группа: Свой
Сообщений: 174
Регистрация: 30-10-06
Из: г. Курск
Пользователь №: 21 787



Спасибо, разобрался.
smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 5 2007, 22:42
Сообщение #4


Гуру
******

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



Цитата(Ivan_Kov @ Mar 5 2007, 10:54) *
Спасибо, разобрался.
Рискну процитировать коллегу из другой ветки:
Цитата(Andy Mozzhevilov @ Feb 21 2007, 05:46) *
Отчет в студию!
По крайней мере так принято, даже если он в стиле "сам был дурак".
wink.gif


--------------------
На любой вопрос даю любой ответ
"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
Ivan_Kov
сообщение Mar 6 2007, 09:42
Сообщение #5


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

Группа: Свой
Сообщений: 174
Регистрация: 30-10-06
Из: г. Курск
Пользователь №: 21 787



Все дело оказалось в том, что я не снимал флаг STA (старт) регистра I2CON. Поэтому после передачи адреса, контроллер i2c передавал повторный сигнал старта. В мануале очень подробно описана процедура работы с i2c, но необходимость снятия этого флага не упоминается прямо, лишь косвенно. Это меня и сбило с толку.
Go to the top of the page
 
+Quote Post
АдскийОдуванчик
сообщение Apr 19 2007, 13:48
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 13-02-07
Пользователь №: 25 324



Цитата(Ivan_Kov @ Mar 6 2007, 09:42) *
Все дело оказалось в том, что я не снимал флаг STA (старт) регистра I2CON. Поэтому после передачи адреса, контроллер i2c передавал повторный сигнал старта. В мануале очень подробно описана процедура работы с i2c, но необходимость снятия этого флага не упоминается прямо, лишь косвенно. Это меня и сбило с толку.


Зачёт! Сам неделю назад становился на эти же грабли. Самое обидное, что в UM на LPC 213x написан !!! очень красивый!!! пример как нужно работать с I2C. И в нём сами филипсовцы не снимают STA бит. Гады!


--------------------
Новичок знает, что все ответы есть в документации. Опытный программист знает в какой, где, и где её достать.
Go to the top of the page
 
+Quote Post

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

 


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


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