rezident 0 7 декабря, 2009 Опубликовано 7 декабря, 2009 · Жалоба 2 Resident: Паузы при чтении нет, как видно на осциллограмме.Чтении? :cranky: Вроде как запись по осциллограмме получается. Адрес 0x3C=0b00111100. Или я ошибаюсь? В чем же дело ?Выходит сама м/с растягивает SCL. :laughing: Но почему она выдает NACK на запись я не знаю. :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kaplinsky 0 7 декабря, 2009 Опубликовано 7 декабря, 2009 · Жалоба Чтении? :cranky: Вроде как запись по осциллограмме получается. Адрес 0x3C=0b00111100. Или я ошибаюсь? Выходит сама м/с растягивает SCL. :laughing: Но почему она выдает NACK на запись я не знаю. :( Ты не на ту осциллограмму смотрел. Чтение у меня вторая осциллограмма в этой теме. ПРОРЫВ ! Проблема решена, причина найдена (неправильное программирование I2C модуля MSP430) ! (подробнее позже) Сейчас борюсь с тем что при чтении выдает два байта вместо одного, опишу решение обязательно. ================================================================================ Изначально идея состояла в том что бы не использовать прерывания для чтения данных компаса. Не хотелось городить глобальные переменные,флаги, счетчики, делать "роботу" в прерывании... и прочую ерунду - зачем если можно подождать (пусть и в активном ожидании) соответствующих флагов. Моей главной ошибкой было то что я ждал бита UCTXSTT - ждал пока передастся START и адрес Славы (ну логично же! ) UCB0CTL1 |= UCTXSTT | UCTR; // Send START, SLAVE ADDR with WRITE // while (UCB0CTL1 & UCTXSTT); а потом уже записывал адрес регистра в буфер передатчика. А не надо было его ждать (почему - не знаю, ведь написано же, флаг очищается после того как передастся START и адрес Славы) Но еще, после передачи устанавливается флаг прерывания передатчика (UCB0TXIFG) сигнализирующий о том что можно записывать данные в буфер передатчика, мол заряжай давай. А понял я когда у меня уже вскипел моск, и я перебрав все варианты (и даже перепробовав разные резисторы) все же решил создать ISR и включить прерывания. Где то глубоко внутри терзало меня сомнение что примеры все написаны с использованием прерываний но я отмахивал это сомнение в конец очереди, так как не очень мне нравиться как сделаны примеры) ... :rolleyes: вот рабочая функция, может кому пригодиться: #define NACK_TX -1 #define NACK_RX -2 int I2C_Read(unsigned char addr, unsigned char *data, int cnt){ int result,i; result = 0; UCB0CTL1 |= UCTXSTT | UCTR; // Send START, SLAVE ADDR with WRITE // while (UCB0CTL1 & UCTXSTT); while (!(IFG2 & UCB0TXIFG)) if (UCB0STAT & UCNACKIFG){ result = NACK_TX; goto STOP; } UCB0TXBUF = addr; while (!(IFG2 & UCB0TXIFG)) if (UCB0STAT & UCNACKIFG){ result = NACK_TX; goto STOP; } UCB0CTL1 &= ~UCTR; UCB0CTL1 |= UCTXSTT; // Send START, SLAVE ADDR with WRITE for (i=0;i<cnt;i++){ while (!(IFG2 & UCB0RXIFG)) if (UCB0STAT & UCNACKIFG){ result = NACK_RX; goto STOP; } data[i] = UCB0RXBUF; }//for STOP: UCB0CTL1 |= UCTXSTP; while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent if (IFG2 & UCB0RXIFG) UCB0RXBUF; return result; }//I2C_Read Благодарю всех кто откликнулся: Alexashka, jam, rezident :cheers: - спасибо ребята ! А также Форуму Electronix.ru - :a14: давно я так не подсаживался... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alexashka 0 8 декабря, 2009 Опубликовано 8 декабря, 2009 · Жалоба Таки объясните откуда Nax брался? Таймаут в слейве? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kaplinsky 0 8 декабря, 2009 Опубликовано 8 декабря, 2009 · Жалоба Таки объясните откуда Nax брался? Таймаут в слейве? :) Думаю так: Из за того что я ждал больше положенного 9-клок задерживался со стороны микроконтроллера, и компас на нас забивал, потом, когда мы все же давали 9-й клок компасу уже было на нас начхать вот он и делал NACK. На самом деле делать NACK - значит ничего не делать на шине, а вот для ACK надо при девятом клоке удерживать SDA в низком состоянии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 8 декабря, 2009 Опубликовано 8 декабря, 2009 · Жалоба когда мы все же давали 9-й клок компасу уже было на нас начхать вот он и делал NACK. На самом деле делать NACK - значит ничего не делать на шине, а вот для ACK надо при девятом клоке удерживать SDA в низком состоянии.ACK - ACKnowledge (подтверждение), NACK - No ACKnowledge (отсутствие подтверждения). Согласно спецификации I2C, минимальная частота обмена на шине не ограничена, т.е. шина по сути полностью статическая. В отличие от SMBUS, например. Так что slave "начхать" на дешифрацию своего адреса никак не может (не имеет права), если только у него не аварийная ситуация при которой он не может корректно функционировать. Так что ваши догадки выглядят не очень убедительно. Может вы функцию инициализации модуля USCI еще до кучи приведете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kaplinsky 0 8 декабря, 2009 Опубликовано 8 декабря, 2009 · Жалоба ACK - ACKnowledge (подтверждение), NACK - No ACKnowledge (отсутствие подтверждения). Согласно спецификации I2C, минимальная частота обмена на шине не ограничена, т.е. шина по сути полностью статическая. В отличие от SMBUS, например. Так что slave "начхать" на дешифрацию своего адреса никак не может (не имеет права), если только у него не аварийная ситуация при которой он не может корректно функционировать. Так что ваши догадки выглядят не очень убедительно. Может вы функцию инициализации модуля USCI еще до кучи приведете? ОК, Слава дешифровал свой адрес, готов выдать ACK но 9-го клока все нет и нет. ( ну по крайней мере у меня других идей нет почему оно не работало раньше) инициализация I2C: void I2C_Init(unsigned char s_addr){ P3SEL |= 0x06; UCB0CTL1 |= UCSWRST; UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; UCB0CTL1 = UCSSEL_3 + UCSWRST; /* BASE FREQ (SMCLK) 8 Mhz 0x0020 - 400 Kbs 0x0050 - 100 Kbs 0x0320 - 10 Kbs 0x1F40 - 1 Kbs */ UCB0BR0 = 0x50; UCB0BR1 = 0x00; UCB0I2COA = 0x01; UCB0I2CSA = s_addr; UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IFG2 &= ~ (UCB0TXIFG | UCB0RXIFG); }//I2C_Init Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 9 декабря, 2009 Опубликовано 9 декабря, 2009 · Жалоба ОК, Слава дешифровал свой адрес, готов выдать ACK но 9-го клока все нет и нет.Как я понял, у вас не писался следующий байт в регистр передатчика (не то условие проверяли, UCTXSTT вместо UCBxTXIFG), потому SCL тормозился. А потом у вас генерировалось STOP-условие, невзирая на отсутствие флага UCNACKIFG. Так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kaplinsky 0 9 декабря, 2009 Опубликовано 9 декабря, 2009 · Жалоба Как я понял, у вас не писался следующий байт в регистр передатчика (не то условие проверяли, UCTXSTT вместо UCBxTXIFG), потому SCL тормозился. Это верно. А потом у вас генерировалось STOP-условие, невзирая на отсутствие флага UCNACKIFG. Так? Нет, флаг UCNACKIFG был, я его обнаруживал и давал STOP что бы освободить шину. Собственно из за этого флага невозможно было передать байт для записи (адрес регистра компаса) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pavel V. 0 9 декабря, 2009 Опубликовано 9 декабря, 2009 · Жалоба Буквально на днях боролся с аппаратным I2C на процессоре F1611, в итоге так и не смог его заставить работать (точнее, смог, но были какие-то паранормальные ошибки). Осциллографа под рукой, к сожалению, не было, поэтому точно сказать что происходило на шине не могу, но по косвенным признакам не формировался STOP после передачи заданного числа байт, приходилось формировать его вручную. Читал Errat-у по этому камню, там куча проблем с I2C, видимо, я на одну из них и напоролся. Вылечилось все только программной реализацией I2C.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kaplinsky 0 9 декабря, 2009 Опубликовано 9 декабря, 2009 · Жалоба Читал Errat-у по этому камню, там куча проблем с I2C, видимо, я на одну из них и напоролся. Вылечилось все только программной реализацией I2C.. Таки да, граблей с I2C там хватает. Перед тем как вскипятить себе мозг на MSP430F2471 я работал с MSP430F2274 (eZ430-RF2500) хотел подключить туда компас. В Errata проблема не описана но при работе линия SCL всегда была в нуле - что я только не делал. http://e2e.ti.com/forums/p/9665/51804.aspx#51804 Поделись ка программной реализацией I2C пожалуйста ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pavel V. 0 9 декабря, 2009 Опубликовано 9 декабря, 2009 · Жалоба Поделись ка программной реализацией I2C пожалуйста ? Прикрепил к сообщению библиотечку. Использую ее для работы с часами PCF8563, весьма стабильно и предсказуемо, в отличие от аппаратной реализации :unsure: Использовать примерно так: uint8_t pcf8563_get_byte(uint8_t addr) { i2cStart(); i2cWrite(0xA2); i2cWrite(addr); i2cStart(); i2cWrite(0xA3); uint8_t ret = i2cRead(0); i2cStop(); return ret; } void pcf8563_set_byte(uint8_t addr, uint8_t value) { i2cStart(); i2cWrite(0xA2); i2cWrite(addr); i2cWrite(value); i2cStop(); } Удачи! i2c.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1921 0 1 февраля, 2011 Опубликовано 1 февраля, 2011 · Жалоба Преречитываю в который раз как увлекательный роман. Надо было пройти этим путём, чтобы оценить. КЛАСС! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться