Имею затык при взаимодействии с компасом 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
#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
Получаю такой результат:

Почему вылазит этот NACK ???
Адрес правильный а он со мной говорить не хочет !
Скорость I2C - 10Кгц
Подтягивающие резисторы 15К.
При чтении почему-то компас шлет два байта (регистр из которого читать не указываем по причине невозможности см. выше)
и что интересно при запросе чтения компас дает нам ACK а при запросе записи NACK - почему ?

или

Из нижней картинки хорошо видно что есть 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
#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 при попытке записи - ломаю голову третий день. Подкиньте идею.