Перейти к содержанию
    

Салют разработчикам !

 

Имею затык при взаимодействии с компасом HMC5843 посредством протокола I2C.

В качестве МК применяю MSP430F2471

 

Проблема в следующем:

для прочтения регистра нужно записать в HMC5843 по I2C протоколу адрес регистра а затем произвести операцию чтения.

Делаю так:

 

#define NACK_1 0x0100
#define NACK_2 0x0200

unsigned int I2C_Read(unsigned char addr){
unsigned int data = 0;  


  UCB0CTL1 |= UCTXSTT | UCTR;                   // UCTR - Transmit, UCTXSTT - generate START
  while (UCB0CTL1 & UCTXSTT);                     // waiting untill START sent
  
  
  UCB0TXBUF = addr;                                    // Loading register address
  while (!(IFG2 & UCB0TXIFG)) if (UCB0STAT & UCNACKIFG){         // waiting until data sent or NACK 

    UCB0CTL1 |= UCTXSTP;                            // Generate STOP
    while (UCB0CTL1 & UCTXSTP);                   // Ensure stop condition got sent
    
    return NACK_1;                                     // wait untill rx flag is set
  }

  
  UCB0CTL1 &= ~UCTR;                              // Clear UCTR for reading operation
  UCB0CTL1 |= UCTXSTT;                            // Send START, SLAVE ADDR with WRITE
  while (UCB0CTL1 & UCTXSTT);                   // waiting untill START sent
  
    
  while (!(IFG2 & UCB0RXIFG)) if (UCB0STAT & UCNACKIFG){

    UCB0CTL1 |= UCTXSTP;                            // Generate STOP
    while (UCB0CTL1 & UCTXSTP);                   // Ensure stop condition got sent
    
    return NACK_2;                                         // wait untill rx flag is set
  }


  data = UCB0RXBUF;
  
  UCB0CTL1 |= UCTXSTP;                              // Generate STOP 
  while (UCB0CTL1 & UCTXSTP);                     // Ensure stop condition got sent
  
  return data;

}//I2C_Read

 

Получаю такой результат:

 

448625.gif

 

Почему вылазит этот NACK ???

Адрес правильный а он со мной говорить не хочет !

 

 

Скорость I2C - 10Кгц

Подтягивающие резисторы 15К.

 

 

При чтении почему-то компас шлет два байта (регистр из которого читать не указываем по причине невозможности см. выше)

и что интересно при запросе чтения компас дает нам ACK а при запросе записи NACK - почему ?

 

448643.gif

или

448642.gif

 

Из нижней картинки хорошо видно что есть START мы передаем адрес 0x1E и бит чтения 1, далее компасс дает ACK и выдает ДВА байта - 0x10 (что может быть значением нулевого регистра компаса) и еще какой-то байт 0x7F и потом говорит нам NACK а мы делаем STOP.

 

вот процедура чтения:

#define NACK_1 0x0100
#define NACK_2 0x0200

unsigned int I2C_Read(unsigned char addr){
unsigned int data = 0;  

  
  UCB0CTL1 &= ~UCTR;                              // Clear UCTR for reading operation
  UCB0CTL1 |= UCTXSTT;                            // Send START, SLAVE ADDR with WRITE
  while (UCB0CTL1 & UCTXSTT);                   // waiting untill START sent
  
    
  while (!(IFG2 & UCB0RXIFG)) if (UCB0STAT & UCNACKIFG){

    UCB0CTL1 |= UCTXSTP;                            // Generate STOP
    while (UCB0CTL1 & UCTXSTP);                   // Ensure stop condition got sent
    
    return NACK_2;                                         // wait untill rx flag is set
  }


  data = UCB0RXBUF;
  
  UCB0CTL1 |= UCTXSTP;                              // Generate STOP 
  while (UCB0CTL1 & UCTXSTP);                     // Ensure stop condition got sent
  
  return data;

}//I2C_Read

 

Почему два байта и почему NACK при попытке записи - ломаю голову третий день. Подкиньте идею.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему два байта и почему NACK при попытке записи - ломаю голову третий день. Подкиньте идею.
Не очень внимательно прочитал ваше сообщение, но зацепившись взглядом за адрес 0x1E ... может поэтому (см. цитату из даташита)

The default (factory) HMC5843 7-bit slave address is 0x3C for write operations, or 0x3D for read operations.

Заметил, что и у писателей документации и у читателей-разработчиков очень часто возникает недопонимание в части трактовки адреса устройства I2C. Бывает, что ошибки и тех, и других. :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тоже не внимательно прочитал)

Если адрес не его то устройство вообще по идее вообще должно молчать. А оно отвечает и отвечает отказом. Значит команда ему не понятна...мэйби...ор нот. либо оно не готово ответить

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3С и 3D это уже 8-ми битные адреса с учетом флага RW.

7-ми битный адлрес 1E - сдвиньте на 1 бит вправо 3С или 3D.

В даташите на HMC так написано:

7-ми битный адрес 1E,

8-ми битный для записи 3C

8-ми битный для чтения 3D

 

Экспериментировал, с другим адрес не откликается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3С и 3D это уже 8-ми битные адреса с учетом флага RW.

7-ми битный адлрес 1E - сдвиньте на 1 бит вправо 3С или 3D.

В даташите на HMC так написано:

7-ми битный адрес 1E,

8-ми битный для записи 3C

8-ми битный для чтения 3D

 

Экспериментировал, с другим адрес не откликается.

Они же просят скорость обмена 100к или 400к , а у Вас вроде 10к - может в этом дело?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Они же просят скорость обмена 100к или 400к , а у Вас вроде 10к - может в этом дело?

 

Думал об этом. Давал 100к, 400к - результат тот же.

На этих скоростях мне фронты не нравятся вот и работаю на 10к, сигналы нормальные (прямоугольные, без затянутых фронтов) так вроде надежнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Думал об этом. Давал 100к, 400к - результат тот же.

На этих скоростях мне фронты не нравятся вот и работаю на 10к, сигналы нормальные (прямоугольные, без затянутых фронтов) так вроде надежнее.

 

А может быть дело в том, что I2C предусматривает slow rate control, а фронты у Вас заваленные...

Кроме того, напряжение питания должно быть в предлелах 1.6 - 2.0 , а у Вас там целых 3 - может ему от этого плохеет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне кажется подозрительной большая пауза на SCL перед выдачей NAK при записи адреса м/с. На диаграмме чтения такой паузы нет. Откуда она берется? Сам датчик SCL "растягивает"? По спецификации I2C это допустимо и нормально и вполне объяснимо тем, что у м/с есть свой собственный внутренний клок. Но какова же причина этой паузы? При беглом чтении даташита я ответа не увидел. :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне кажется подозрительной большая пауза на SCL перед выдачей NAK при записи адреса м/с. На диаграмме чтения такой паузы нет. Откуда она берется? Сам датчик SCL "растягивает"? По спецификации I2C это допустимо и нормально и вполне объяснимо тем, что у м/с есть свой собственный внутренний клок. Но какова же причина этой паузы? При беглом чтении даташита я ответа не увидел. :laughing:

Наверно это компас делает stetching, чтобы дать ACK/NACK

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Наверно это компас делает stetching, чтобы дать ACK/NACK
Что вы имеете в виду? Я не нашел упоминания этого термина в даташите. И вообще эту команду обычно аппаратура автомата I2C отрабатывает. Поскольку у датчика нет других аппаратных адресов и он не может быть мастером (а следовательно ему не нужно арбитраж на шине поддерживать), то дешифрация адреса должна происходить без каких-либо задержек, на частоте тактирования его мастером.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что вы имеете в виду? Я не нашел упоминания этого термина в даташите. И вообще эту команду обычно аппаратура автомата I2C отрабатывает. Поскольку у датчика нет других аппаратных адресов и он не может быть мастером (а следовательно ему не нужно арбитраж на шине поддерживать), то дешифрация адреса должна происходить без каких-либо задержек, на частоте тактирования его мастером.

Любой участник протокола имеет право на bus wait, сажая SCL в ноль, при этом мастер должен застопорить clock и ждать, пока линия освободится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот такая схема подключения используется

465127.gif

только еще есть два подтягивающих резистора по 15К (других не было, я не думаю что проблема может быть в этом) к питанию линий SDA и SCL

Питание подаю 3.3 в.

 

 

вот такая платка у меня 465157.jpg

вот отсюда http://www.sparkfun.com/commerce/product_i...roducts_id=9371

 

Проверял гипотезу что разные адреса могут быть и что 0x1Е для чтения, а для записи какой не известно.

Написал перебор адресов, перебрал все для записи ( W=0 ) не откликнулся никакой - везде этот NACK ...

 

Мне кажется подозрительной большая пауза на SCL перед выдачей NAK при записи адреса м/с. На диаграмме чтения такой паузы нет. Откуда она берется? Сам датчик SCL "растягивает"? По спецификации I2C это допустимо и нормально и вполне объяснимо тем, что у м/с есть свой собственный внутренний клок. Но какова же причина этой паузы? При беглом чтении даташита я ответа не увидел. :laughing:

 

Вот на что я обратил внимание:

 

After each 8-bit transfer, the master device generates a 9 th clock pulse, and releases the SDA line.

The receiving device (addressed slave) will pull the SDA line low to acknowledge (ACK) the successful transfer or leave

the SDA high to negative acknowledge (NACK).

 

так вот причина паузы скорее всего мастер, MSP430.

кстати пауза эта плавающая. Я наблюдал увеличение/уменьшение этой паузы при многократных попытках записи.

 

надо зреть в себя...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот такая схема подключения используется

только еще есть два подтягивающих резистора по 15К (других не было, я не думаю что проблема может быть в этом) к питанию линий SDA и SCL

Питание подаю 3.3 в.

Ну осталось проверить только резисторы - по стандарту 2.4ком...

И ещё - попробуйте перед тем как просить данные дать ему адрес конфигурационного регистра , потом записать туда 0х00, а потом только читать...

пошлите ему 0х3с 0х00 0х00, а потом только читайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Любой участник протокола имеет право на bus wait, сажая SCL в ноль, при этом мастер должен застопорить clock и ждать, пока линия освободится.
Я об этом знаю и упоминал, что этот прием полностью соответствует спецификации I2C. Только при реализации "чистого" слейва это чаще всего не требуется. Например, в EEPROM и ADC пин SCL функционально является входом, без возможности управления (удержания) SCL.

только еще есть два подтягивающих резистора по 15К (других не было, я не думаю что проблема может быть в этом) к питанию линий SDA и SCL
Все же попробуйте уменьшить номиналы резисторов до 2...4,7кОм.

кстати пауза эта плавающая. Я наблюдал увеличение/уменьшение этой паузы при многократных попытках записи.
Пауза только при записи? А при чтении она есть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Немного поэкспериментировал с резисторами, вместо SLAVE устройства (компаса) поцепил два резистора подтянутых к питанию.

 

Это 47К, 100Кгц

467226.png

 

Это 4.3К, 100Кгц.

467227.png

Сигнал стал правильнее.

 

Обратите внимание паузы нет между 8-м и 9-м клоками

 

А теперь компас с резисторами 4.3К и 100Кгц клоками

467224.png

 

пауза 400 мксек. И это одна из самых маленьких что мне удалось поймать - в основном 9-й клок уходит далеко за экран осциллографа.

 

 

2 Resident: Паузы при чтении нет, как видно на осциллограмме. В чем же дело ?

 

 

...9-й клок, NACK его !

не переключайтесь, будьте с нами, продолжение следует...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...