简体   繁体   English

对从RPI到HMCL3855L的I2C通信进行故障排除

[英]Troubleshooting I2C communication from RPI to HMCL3855L

I'm trying to figure out how to communicate with the HMC3855L compass module using a Raspberry Pi running Arch linux. 我试图弄清楚如何使用运行Arch linux的Raspberry Pi与HMC3855L指南针模块进行通信。

Currently I've got the connections all set up and I can see the device address (0x1E) using the unix tool i2cdetect but when every I try and run my code I get nothing. 目前,我已经建立了所有连接,并且可以使用unix工具i2cdetect看到设备地址(0x1E),但是每当我尝试运行代码时,我一无所获。 I'm using the Bcm2835 library by Mike McCauley for the C programming. 我正在使用Mike McCauley的Bcm2835库进行C编程。

I'm fairly new to programming in C but so I just need something quick and dirty to read some bytes off this thing. 我对使用C语言进行编程还很陌生,但是我只需要快速又脏的东西来读取一些东西。 I checked and made sure all my arrays contained the correct values and that the pointers were pointing to the appropriate addresses. 我检查并确保所有数组都包含正确的值,并且指针指向正确的地址。 Everytime I run my script and check i2cdetect again the address changes from (0x1E) to (0x03) which is pretty strange. 每次我运行脚本并再次检查i2cdetect时,地址都从(0x1E)变为(0x03),这很奇怪。 Any advice on the matter would be greatly appreciated. 任何有关此事的建议将不胜感激。 Code is as follows... 代码如下...

/* i2ccompass:
* Test script for continuously reading data from i2c compass
* device and logging to a file.
*
*/

#include <bcm2835.h>
#include <stdio.h>

uint16_t clk_div = BCM2835_I2C_CLOCK_DIVIDER_148;
uint8_t slave_address = 0x1E;
uint64_t delay = 70000;

int main(void) {

    if (!bcm2835_init()) return 1;
    bcm2835_i2c_begin();
    bcm2835_i2c_setSlaveAddress(slave_address);

    printf("Clock divider set to: %d\n", clk_div);
    printf("Slave address set to: %d or %X\n",slave_address,slave_address);

    char writeBuff[3] = {0x3C,0x00,0x70};
    char gainBuff[3] = {0x3C,0x01,0xA0};
    char modeBuff[3] = {0x3C,0x02,0x00};
    char startTransBuff[2] = {0x3D,0x06};
    char repeat[2] = {0x3C,0x03};
    char readBuff[10];

    char *wb_ptr, *gb_ptr, *mb_ptr,
          *stb_ptr, *r_ptr, *re_ptr;
    wb_ptr = writeBuff;
    gb_ptr = gainBuff;
    mb_ptr = modeBuff;
    stb_ptr = startTransBuff;
    r_ptr = readBuff;
    re_ptr = repeat;

    bcm2835_i2c_write(wb_ptr, 3);
    bcm2835_delayMicroseconds(delay);
    bcm2835_i2c_write(gb_ptr, 3);
    bcm2835_delayMicroseconds(delay);
    bcm2835_i2c_write(mb_ptr, 3);
    bcm2835_delayMicroseconds(delay);
    bcm2835_i2c_write(stb_ptr, 2);

    bcm2835_delayMicroseconds(delay);

    bcm2835_i2c_read(r_ptr, 6);
    int i = 1;
    for(i; i <= 10; i++){
     printf("Read Buf[%d] = %x or %d\n",
          i-1, readBuff[i-1], readBuff[i-1]);
    }
    bcm2835_delayMicroseconds(delay);

    bcm2835_i2c_write(re_ptr, 2);

    bcm2835_i2c_end();
    bcm2835_close();
    printf("... done\n");
        return 0;
}

I dont see anything unusual in the code you hava provided but suspect function bcm2835_i2c_write(). 我没有看到您提供的代码中有任何异常,但怀疑函数bcm2835_i2c_write()。

The amount of delay could also cause the problem. 延迟量也可能导致问题。 You have not provided any delay after setting slave address migh cause a problem. 设置从站地址可能导致问题后,您没有提供任何延迟。

The steps on debugging any I2C device 调试任何I2C设备的步骤

1.Verify your hardware connection is ok (especially SCL and SDA) 1.验证您的硬件连接是否正常(尤其是SCL和SDA)

2.Verify that does your API uses the slave address correctly as expected by the i2c slave ie;HMC3855L and after sending slave address verify you're receiving ACK signal as response. 2.验证您的API是否按照i2c从站(HMC3855L)的预期正确使用了从站地址,并在发送从站地址后验证您正在接收ACK信号作为响应。

3.Verify you're configuring the control registers correectly . 3.验证您是否正确配置了控制寄存器。 In some i2c devices initially when it starts they might be in power down mode so we have to change it by setting some bits in the control register 在某些i2c设备最初启动时,它们可能处于掉电模式,因此我们必须通过在控制寄存器中设置一些位来对其进行更改

4.Mainly the timing diagram for read & write is the most important and more prone to have mistakes, ie; 4,读写时序图主要是最重要的,更容易出错。 note where are the start and stop conditions are used (most of them use repeated start), If you're just writing a API driver code you must have to understand how the i2c read & write works inside the kernel 请注意在哪里使用了开始和停止条件(其中大多数使用重复开始), 如果您只是在编写API驱动程序代码,则必须了解i2c读写在内核中的工作方式

5.Conversion of data might take some time , so check that information in datasheet electrical characteristics section 5.数据转换可能需要一些时间,因此请检查数据表电气特性部分中的信息

Considering all these informations I hope you'll be able to solve problem 考虑到所有这些信息,我希望您能够解决问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM