为什么我只收到第一个地址字节? (I2C协议) [英] Why am I only receiving the first address byte? (I2C Protocol)

查看:98
本文介绍了为什么我只收到第一个地址字节? (I2C协议)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

期待从属设备进行确认并返回数据,但事实并非如此. 这是我的协议. 这是我的数据表

数据表中提到从站将首先发送MSB来应答.字节0和字节1包含 预测值.所有字节均由主机确认."

源库

仅供参考,我在Arduino Fio上,但我没有继承Arduino库.

    #include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <uart.h>
#include <i2c_master.h>

#define LED PB5

#define I2C_READ 0x5A

char buffer[1];

//char data[9];
uint16_t val = 0;
uint8_t status = 0;


void getVal()
{
  if(i2c_start(I2C_READ))
    {
        uart_puts("Start ");

        val = ((uint8_t)i2c_read_ack())<<8; 
        val |= i2c_read_ack();

    status = ((uint8_t)i2c_read_nack());

      i2c_stop();

    } else
  {
        uart_puts("Error");

        i2c_stop();
    }
}

int main(void)
{
  init_uart(57600);
  i2c_init();

  DDRB = _BV(5);

    for(;;)
    {



        getVal();

        itoa(status, buffer, 10); //convert decimal to string base 10
        uart_puts(buffer);

  PORTB = 0xFF;
  _delay_ms(500);
  PORTB = 0x00;
  _delay_ms(500);
}
return 0;   /* never reached */

}


修改修订:

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <uart.h>
#include <i2c_master.h>

#define LED PB5

#define I2C_READ 0x5A

char buffer[10];

//char data[9];
uint16_t val = 0;
uint8_t status = 0;


{
  if(!i2c_start(I2C_READ))
    {
        uart_puts("Error");

        i2c_stop();

    } else
    {
        uart_puts("Start ");
        i2c_start((IAQ_ADDR << 1) + 1); //i2c_start(0xB5);

        val = ((uint8_t)i2c_read_ack())<<8; 
        val |= i2c_read_ack();

        status = ((uint8_t)i2c_read_nack());

        i2c_stop();
    }
}

int main(void)
{
  init_uart(57600);
  i2c_init();

  DDRB = _BV(5);

    for(;;)
    {

      getVal();

            itoa(status, buffer, 10); //convert decimal to string base 10
            uart_puts(buffer);

      PORTB = 0xFF;
      _delay_ms(500);
      PORTB = 0x00;
      _delay_ms(500);
    }
    return 0;   /* never reached */
    }

解决方案

不知道正在使用的i2c库的细节就很难说,但是我首先要检查的一件事是i2c_start(I2C_READ).

数据表中提供的i2c地址为0x5a,就像您放入宏中一样.但是第一个字节还包含读/写标志作为最低有效位. i2c_start()函数必须将0xb5放到总线上(即(0x5a << 1) + 1进行读取)

如果不是i2c_start(),则您的从属设备实际上并未得到寻址,因此不会确认.

Expecting the slave to ACKnowledge and return data, but it does not. This is my protocol. This is my Datasheet

The datasheet mentions "The slave will answer by sending bytes with MSB first. Byte0 and byte1 contain the prediction value. All bytes are acknowledged by the master."

Edit: Source Library

Also FYI I'm on an Arduino Fio but I am not inheriting the Arduino library.

    #include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <uart.h>
#include <i2c_master.h>

#define LED PB5

#define I2C_READ 0x5A

char buffer[1];

//char data[9];
uint16_t val = 0;
uint8_t status = 0;


void getVal()
{
  if(i2c_start(I2C_READ))
    {
        uart_puts("Start ");

        val = ((uint8_t)i2c_read_ack())<<8; 
        val |= i2c_read_ack();

    status = ((uint8_t)i2c_read_nack());

      i2c_stop();

    } else
  {
        uart_puts("Error");

        i2c_stop();
    }
}

int main(void)
{
  init_uart(57600);
  i2c_init();

  DDRB = _BV(5);

    for(;;)
    {



        getVal();

        itoa(status, buffer, 10); //convert decimal to string base 10
        uart_puts(buffer);

  PORTB = 0xFF;
  _delay_ms(500);
  PORTB = 0x00;
  _delay_ms(500);
}
return 0;   /* never reached */

}


Edit Revised:

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <uart.h>
#include <i2c_master.h>

#define LED PB5

#define I2C_READ 0x5A

char buffer[10];

//char data[9];
uint16_t val = 0;
uint8_t status = 0;


{
  if(!i2c_start(I2C_READ))
    {
        uart_puts("Error");

        i2c_stop();

    } else
    {
        uart_puts("Start ");
        i2c_start((IAQ_ADDR << 1) + 1); //i2c_start(0xB5);

        val = ((uint8_t)i2c_read_ack())<<8; 
        val |= i2c_read_ack();

        status = ((uint8_t)i2c_read_nack());

        i2c_stop();
    }
}

int main(void)
{
  init_uart(57600);
  i2c_init();

  DDRB = _BV(5);

    for(;;)
    {

      getVal();

            itoa(status, buffer, 10); //convert decimal to string base 10
            uart_puts(buffer);

      PORTB = 0xFF;
      _delay_ms(500);
      PORTB = 0x00;
      _delay_ms(500);
    }
    return 0;   /* never reached */
    }

解决方案

Difficult to tell without having details of the i2c library that is being used, but the one thing I'd be checking first is the i2c_start(I2C_READ).

The i2c address provided in the datasheet is 0x5a as you've put in your macro. But the first byte also contains the read/write flag as the least significant bit. The i2c_start() function has to be putting 0xb5 onto the bus (i.e. (0x5a << 1) + 1 for a read)

If i2c_start() is not, then your slave device is not actually being addressed and so won't ack.

这篇关于为什么我只收到第一个地址字节? (I2C协议)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆