Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: i2c в lpc2378
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Ivan_Kov
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 Нажмите для просмотра прикрепленного файла
на ней видно, что сигнал СТАРТ и передача адреса - проходят нормально,
а при передачи первого-же бита данных возникает проблема:
длительность импульса CLK почему-то оказывается увеличенной, и уровень SDA меняется (падает) при высоком уровне CLK. естественно что это не допустимо и, повидимому, расценивается как сигнал старта, от сюда и значение state = 8.
выяснил что такое поведение возникает из-за lpc. Кто-нибудь сталкивался с подобным?
Сергей Борщ
Цитата(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 пока оно занято чем-то другим и таким образом тормозить обмен.
Ivan_Kov
Спасибо, разобрался.
smile.gif
Сергей Борщ
Цитата(Ivan_Kov @ Mar 5 2007, 10:54) *
Спасибо, разобрался.
Рискну процитировать коллегу из другой ветки:
Цитата(Andy Mozzhevilov @ Feb 21 2007, 05:46) *
Отчет в студию!
По крайней мере так принято, даже если он в стиле "сам был дурак".
wink.gif
Ivan_Kov
Все дело оказалось в том, что я не снимал флаг STA (старт) регистра I2CON. Поэтому после передачи адреса, контроллер i2c передавал повторный сигнал старта. В мануале очень подробно описана процедура работы с i2c, но необходимость снятия этого флага не упоминается прямо, лишь косвенно. Это меня и сбило с толку.
АдскийОдуванчик
Цитата(Ivan_Kov @ Mar 6 2007, 09:42) *
Все дело оказалось в том, что я не снимал флаг STA (старт) регистра I2CON. Поэтому после передачи адреса, контроллер i2c передавал повторный сигнал старта. В мануале очень подробно описана процедура работы с i2c, но необходимость снятия этого флага не упоминается прямо, лишь косвенно. Это меня и сбило с толку.


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