问题标签 [i2c]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
3377 浏览

c - 最佳常见做法 I2C 寄存器映射

只是想知道在 C 中关于 I²C 寄存器映射的最佳实践是什么,或者更确切地说是其他人经常使用/喜欢什么。

到目前为止,我通常已经做了很多定义,一个用于每个寄存器,一个用于所有位、掩码、移位等。但是,最近我看到一些驱动程序使用(可能是打包的)结构而不是定义。我认为这些是 Linux 内核模块。

无论如何,他们会

然后他们将使用 offsetof(或宏)来获取 i2c 寄存器并使用 sizeof 来读取要读取的字节数。

我发现这两种方法都有其优点:

结构方法:

  • (+) 寄存器偏移在逻辑上都包含在结构中,而不必在定义中拼出每个寄存器。
  • (+) 条目大小使用适当大小的数据类型明确说明。
  • (-) 这不考虑广泛使用的位字段
  • (-) 这不考虑不是字节映射的寄存器映射(例如 LM75),其中一个从偏移量 n+0x00 读取 2 个字节,但 n+0x01 是另一个寄存器,而不是寄存器 n 的高/低字节+0x00
  • (-) 这并没有考虑地址空间中的大间隙(例如,0x00、0x01、0x80、0xAA 处的寄存器,没有中间...)并且(我认为?)依赖于编译器优化来摆脱结构.

定义方法:

  • (+) 每个寄存器及其位通常在一个块中定义,这使得查找正确的符号变得容易并依赖于命名约定。
  • (+) 透明/不知道地址空间间隙。
  • (-) 每个寄存器都必须单独定义,即使没有间隙
  • (-) 因为定义往往是全局的,所以名称通常很长,在源代码中有些乱七八糟的长符号名称。
  • (-) 要读取的数据大小通常是硬编码的幻数或 (end - start + 1) 样式的计算,符号名称可能很长。
  • (o) 透明/不知道数据大小与地图中的地址。

基本上,我正在寻找一种更聪明的方法来处理这些情况。我经常发现自己为每个寄存器和每个位以及可能的掩码和移位(后两个取决于数据类型)键入了很多令人痛苦的长符号名称,只是最终只使用了其中的几个(但讨厌稍后重新定义缺少的符号,这就是我在一个会话中输入所有符号的原因)。尽管如此,我注意到要读取/写入的字节大小主要是幻数,通常需要并排读取数据表和源代码才能理解最基本的交互。

我想知道其他人如何处理这些情况?我在网上找到了一些示例,其中人们还费力地在一个大标题中输入了每个寄存器、位等,但没有什么非常确定的……但是,在这一点上,上面的两个选项似乎都不太聪明:(

0 投票
2 回答
1532 浏览

linux - 需要帮助处理共享 ARM9 GPIO 中断 (linux) 上的多个共享 I2C MAX3107 芯片

我们小组正在使用嵌入式处理器(Phytec LPC3180、ARM9)。我们设计了一个电路板,它在 LPC3180 的一个 I2C 总线上包含四个 MAX3107 UART 芯片。以防万一,我们正在运行内核 2.6.10,这是该处理器可用的最新版本(对该产品的支持不是很好;我们必须开发或修复 Phytec 提供的许多驱动程序,并且 Phytec似乎对升级该产品的 linux 代码(尤其是内核版本)没有兴趣。这太糟糕了,因为 LPC3180 是一个不错的设备,尤其是在不需要以太网且实际上不需要以太网的低功耗嵌入式产品的情况下'不想要以太网(由于以太网控制器芯片的相关功耗)。

当 I2C 总线上的四个设备(MAX3107 UART 芯片)之一接收到一个字符时,它会产生一个中断。所有四个 MAX3107 芯片的中断线是共享的(开漏下拉),并且该线连接到配置为电平中断的 3180 的 GPIO 引脚。当 3017 中的一个产生中断时,将运行一个处理程序,该处理程序执行以下处理(大致):

请注意,这是我觉得有些麻烦的地方,即在离开上述代码之前没有重新启用中断。相反,驱动程序的编写使得中断由下半部分工作队列任务重新启用(使用“enable_irq(LPC_IRQ_LINE)函数调用”。由于工作队列任务不在中断上下文中运行,我相信它们可能会休眠,我认为对于中断处理程序来说是个坏主意。

上述方法的基本原理如下: 1. 如果四个 MAX3107 uart 芯片中的一个接收到一个字符并产生一个中断(例如),中断处理程序需要确定四个 I2C 设备中的哪个实际引起了中断。然而,显然,由于 I2C 读取可以休眠,因此无法从上半部中断处理程序的上下文中读取 I2C 设备,这被认为不适合中断处理程序上半部。2.解决上述问题(即哪个设备导致中断)的方法是让中断禁用并退出上半部分处理程序,之后非中断上下文代码可以查询I2C总线上的四个设备中的每一个找出哪个接收到了字符(并因此产生了中断)。3. 一旦下半部分处理程序确定哪个设备产生了中断,下半部分代码就会禁用该芯片上的中断,这样它就不会重新触发到 LPC3180 的中断线。这样做之后,它会读取串行数据并退出。

这里的主要问题似乎是没有办法从中断处理程序上半部分中查询四个 MAX3107 uart 芯片。如果上半部分在返回之前简单地重新启用中断,这将导致同一芯片再次产生中断,我认为导致上半部分禁用中断,安排下半部分工作队列并禁用中断只是发现自己回到了同一个地方,因为在下半部分代码到达导致中断的芯片之前,另一个中断已经发生,等等,......

任何与此驱动程序打交道的建议将不胜感激。我真的不喜欢允许在驱动程序的上半部分禁用中断但在存在上半部分驱动代码之前不重新启用中断的想法。这似乎并不安全。

谢谢,

吉姆

PS:在我的阅读中,我发现线程中断是处理上述要求的一种手段(至少这是我对http://lwn.net/Articles/302043/等网站文章的解释)。我不确定 Phytec 提供的 2.6.10 内核是否包含线程中断函数。我打算在接下来的几天内对此进行调查。

0 投票
1 回答
1188 浏览

c - 从 Arduino 中的 PCA 9554 (i2c) 读取

我正在尝试从 arduino 中的 PCA9554 读取数据。硬件设置很简单:PCA9554的3个地址线都连接到高电平(+5 v),所以这个设备的地址是0x27。我用来读取值的代码如下:

但它始终为 0。

这段代码有什么问题?

我认为硬件没有错误,因为我可以从 I2C 总线上的其他设备读取。

0 投票
1 回答
4321 浏览

python - 如何在没有互联网连接的情况下在树莓派中安装 python 库?

我必须在我的 Raspberry Pi 中安装一些库,但我无法将它连接到互联网。是否可以在 Windows pc 中下载它们(甚至 linux 也可以)并将它们复制到树莓派,以便我可以进行离线安装。这怎么可能?

这些是我需要的库

我也想安装这个程序使它成为一个 http 服务器

我想将所有这些下载到 Windows,然后将它们复制到我可以安装它们的树莓派。任何帮助,将不胜感激。谢谢

0 投票
1 回答
866 浏览

usb - 多个 MSP430 之间是否可以同时进行 I2C、SPI 和 USB 通信?

我已经编写了几个 MSP430x6xx 微控制器作为一些 I2C 从设备的主控。其中一个 MSP430 使用其内置的 USB 模块将从 I2C 从机接收的数据传输到 PC。我想扩展它以允许所有微控制器使用公共总线系统将从各自的 I2C 从机接收到的数据发送到 PC。使用 SPI 将数据从所有 MSP430 传输到单个 MSP430 主控(已经同时作为 I2C 主控和 USB 设备)然后将其传输到 PC 是否可行?我将不胜感激任何其他建议。谢谢

0 投票
1 回答
2820 浏览

python - 如何使用 I²C 将 Arduino Uno 与 Raspberry Pi 连接

我正在尝试使用 I²C 通过I²C接口将数据从Arduino Uno发送到Raspberry Pi。这是我使用的代码。

在阿杜诺:

在树莓派中:

我收到以下错误。

回溯(最后一次调用):
文件 "/home/pi/i2ctest.py" ,第 8 行,在 <module>
watt = bus.read_byte_data(address,1)
IOError: [Errno 5] Input/Output error

我该如何解决?此外,除了 SMBus 库之外,在 Raspberry Pi 中使用 I²C 是否还有其他选择?

0 投票
1 回答
2225 浏览

linux-device-driver - 树莓派中的 I2C Bitbanging

我们正在我们raspberry pi的一个项目中使用;同样我们要使用 i2c 来连接触摸屏。由于 pi 中的 i2c 不支持使用 i2c 位撞击的时钟拉伸计划。我正在按照链接中给出的程序进行操作; I2C-GPIO

我无法激活i2con gpio。我收到以下错误

问候苏曼

0 投票
2 回答
29513 浏览

python-2.7 - 如何使用带有 I2C 的 Raspberry Pi 从 Arduino 读取数据

我正在尝试使用 python smbus 模块将数据从 Arduino UNO 读取到 Raspberry Pi。我能在 smbus 模块上找到的唯一文档是这里。我不确定 cmd 在模块中的含义。我可以使用 write 将数据发送到 Arduino。我写了两个简单的程序,一个用于读取,一个用于写入

用来写的

供阅读的

Arduino代码是

当我运行读取程序时,它每次都返回“33”。Arduino 返回调用了 sendData 函数。

我正在使用数据电平转换器,描述说它可能有点迟钝。

有没有人让这个工作?

0 投票
0 回答
280 浏览

linux - 与用户进程/线程相比,真的没有办法控制工作队列处理的优先级吗?

我一直在阅读各种参考资料,这些参考资料讨论了在 linux 驱动程序中使用下半部分工作队列进行延迟处理。据我所知,内核工作队列完成的任何工作似乎都像普通用户进程/线程一样被调度,内核工作队列相关进程和用户进程之间唯一真正的区别是工作队列可以移动数据在用户端缓冲区和内核缓冲区之间。如果知道我对这些引用的解释是否正确,或者是否有机制可以让我对工作队列处理的优先级保持一定程度的控制,我将不胜感激。更具体地说,我想知道我是否可以保证工作队列进程的优先级高于任何用户进程,至少在工作队列进程不休眠时。我' 我在处理挂在 400 kHz(即慢速)I2C 总线上的芯片的读/写的上下文中提出了这个问题。我们在 ARM9 处理器上运行 linux 2.6.10。- 谢谢!

0 投票
1 回答
545 浏览

arduino - 使用 AVR TWI 接口的问题

我正在尝试使用 atmega2560 访问 HMC5883L 模块。我编写了一个类 (I2C),其中包含 I2C 通信所必需的基本方法。

首先,我将解释问题。这就是我所做的。

(考虑术语有它们的普通含义。SLAW = SLA+W(从地址+写入)...)

一切顺利,直到进入 while 循环。在循环中,它似乎被困在i2c.stop()

i2c.stop()是这样实现的;

我做错了什么吗?我该如何解决这个问题?

(所有其他功能都按照数据表示例中的方式简单实现。)