如何使用bcm2835库更改mlx90614的从站地址?我试过下面的代码...

int main()
{
   // Buffer, where I store data which I'll send
   unsigned char buf[6];

   // bcm2835 i2c module intialisation code
   bcm2835_init();
   bcm2835_i2c_begin();
   bcm2835_i2c_set_baudrate(25000);
   bcm2835_i2c_setSlaveAddress(0x00);

   // For debug purposes, I read what reason codes operations give.
   bcm2835I2CReasonCodes why;
   bcm2835_i2c_begin();

   // function which reads and prints what value eeprom address 0x0e has.
   // See below the main.

   printf("Initial check\n");
   check(); // this time it prints a factory default value 0x5a.

   // To access eeprom, the command must start with 0x2X, where x determines the
   // address, resulting 0x2e.
   buf[0] = 0x2e;

   // According to datasheet, I first have to clear the address before
   // real write operation.
   buf[1] = 0x00;
   buf[2] = 0x00;
   why = bcm2835_i2c_write(buf,3);
   reason(why); // resolves and prints the reason code. This time it prints OK

   // according to datasheet, eeprom needs 5ms to make a write operation,
   // but I give it 2 seconds.
   sleep(2);

   // Then I check did the value in eeprom 0x0e change. IT DOESN'T!
   printf("Check after clear\n");
   check();

   // Then I try to write a new address to the eeprom but since the clearing
   // the register didn't work, this is very unlikely to work either.
   buf[0] = 0x2e;
   buf[1] = 0x4b;
   buf[2] = 0x00;
   why = bcm2835_i2c_write(buf,3);
   reason(why);
   sleep(2);

   // The datasheet says that I have to reset the power supply and after that
   // the device should respond to the new slave address.
   // I do that by pluging off the jumper wires and reconnecting them
   // after the program has finnished.
   bcm2835_i2c_end();
   return 0;
}

// The function I use to determine what the reason code was.
void reason(bcm2835I2CReasonCodes why)
{
   printf("Reason is: ");
   if(why == BCM2835_I2C_REASON_OK)
   {
      printf("OK");
   }else if(why == BCM2835_I2C_REASON_ERROR_NACK){
      printf("NACK");
   }else if(why == BCM2835_I2C_REASON_ERROR_CLKT){
      printf("Clock stretch");
   }else if(why == BCM2835_I2C_REASON_ERROR_DATA ){
      printf("Data error");
   }else{
      printf("Dunno lol");
   }
   printf("\n");
   return;
}

// Here I read eeprom 0x2e.
void check()
{
   unsigned char buf[6];
   unsigned char reg = 0x2e;
   bcm2835I2CReasonCodes why;
   // better safe than sorry with the buffer :)
   buf[0] = 0;
   buf[1] = 0;
   buf[2] = 0;
   why = bcm2835_i2c_write (&reg, 1);
   reason(why);
   why = bcm2835_i2c_read_register_rs(&reg,&buf[0],3);
   reason(why);
   printf("Buffer values are: %x ; %x ; %x \n", buf[0], buf[1], buf[2]);
}


该程序的输出如下:

Initial check
Reason is: OK
Reason is: OK
Buffer values are: 5a ; be ; dc
Reason is: OK
Check after clear
Reason is: OK
Reason is: OK
Buffer values are: 5a ; be ; dc
Reason is: OK


如果在此之后运行i2cdetect -y 1,则该设备不会出现在表中,但是它将响应从0x00或0x5a调用它的程序。使用完此类程序后,i2cdetect会从地址0x5a正常检测设备。

所以我想真正的问题是,为什么我不能清除并重写eeprom 0x0e?

Mlx90614 SMBus通信的描述可以在下面找到。最相关的页面是IMO页面19,它实际上给出了我要执行的操作的伪代码示例。
http://www.melexis.com/Assets/SMBus-communication-with-MLX90614-5207.aspx

这是mlx90614的数据表
http://www.melexis.com/Assets/IR-sensor-thermometer-MLX90614-Datasheet-5152.aspx

这是bcm2835的文档
www.airspayce.com/mikem/bcm2835/group__i2c.html

最佳答案

您必须添加一个错误字节。请看以下网站的解释:https://sf264.wordpress.com/2011/03/10/howto-mlx90614-und-pwm/

00002e4b00计算CRC-8得出0xa3

我曾用此网站来计算CRC-8:http://smbus.org/faq/crc8Applet.htm

我没有测试过,但是我认为这应该起作用:

buf[0] = 0x2e;
buf[1] = 0x4b;
buf[2] = 0x00;
buf[3] = 0xa3;
why = bcm2835_i2c_write(buf,4);

07-28 02:58