首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我只接收第一个地址字节?(I2C协议)

为什么我只接收第一个地址字节?(I2C协议)
EN

Stack Overflow用户
提问于 2016-04-13 00:32:51
回答 4查看 776关注 0票数 2

期望从ACKnowledge返回数据,但它没有。这是我的协议这是我的数据表

数据表提到:“从节点将首先发送带有MSB的字节。Byte0和byte1包含预测值。所有字节都由主节点确认。”

编辑: 源库

另外,FYI我在Arduino Fio上,但我没有继承Arduino库。

代码语言:javascript
复制
    #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 */

}

编辑修订本:

代码语言:javascript
复制
#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 */
    }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-04-13 01:05:56

如果没有正在使用的i2c库的详细信息,很难判断,但我首先要检查的一件事是i2c_start(I2C_READ)

数据表中提供的i2c地址是0x5a,就像您在宏中放置的那样。但是第一个字节也包含读/写标志作为最不重要的位。i2c_start()函数必须将0xb5放到总线上(即读取的(0x5a << 1) + 1 )。

如果没有i2c_start(),那么您的从设备实际上不会被寻址,因此不会被破坏。

票数 3
EN

Stack Overflow用户

发布于 2016-04-13 01:04:32

您的程序有未定义的行为。您已经将buffer声明为:

代码语言:javascript
复制
char buffer[1];

这是一个单一字符的数组。唯一可以存储的以空结尾的字符串是空字符串(即buffer[0] == '\0'所在的位置)。但是您正在使用它将整数转换为字符串。

您需要使缓冲区足够大,以容纳您希望存储在其中的最大字符串,包括终止符。

票数 2
EN

Stack Overflow用户

发布于 2016-04-13 01:27:37

我不知道你的根本问题是什么。你有什么症状?你的UART有什么样的输出?

正如其他人所说的,您的buffer变量太小,无法作为C字符串保存任何有价值的内容。itoa (AVR libc条目)通常提供一个以空结尾的字符串,因此您至少需要对所有字符和空值都足够大。您可能遇到了溢出缓冲区的问题,在这种情况下,您应该有一个简单的解决方案。

使用uin8_t意味着您应该为最多255个表示分配足够的空间。您需要3个字符来表示整个范围,以及一个字符作为空字符。更改您的代码以读取char buffer[4];,并查看这是否改善了您所遇到的问题。

如果I2C协议实现有错误,如果没有关于错误所在的准确信息,这将很难诊断。如果您可以访问逻辑分析器,应该可以在这里提供帮助。

编辑:

我刚刚看了一下数据表,您使用连续的i2c_start(0x5A) s的i2c_read_ack()方法似乎是正确的。但是,根据您的链接协议,您可能只是在您的UART上看到“错误”,因为i2c_start()返回0以获得成功的开始事务,并且您检查if(i2c_start(I2C_READ))何时应该在getVal()中测试if(! i2c_start(I2C_READ))

您似乎也有一些基于链接uint8_t gist的不必要的i2c_master.c转换。如果这真的是一个与Arduino兼容的板,我建议只使用Arduino IDE,看看是否可以得到一个简单的I2C示例来使用传感器来证明您的访问方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36586465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档