MAX77651 无法使用 i2c 读取寄存器
MAX77651 Can't read register with i2c
我正在尝试在编程之前测试 MAX77651 芯片的 i2c 通信。
这是我的设置:
我有一个 UMFT4222ev 通过 USB 连接到我的 Linux 笔记本电脑。得益于 MAX77651 评估套件,该芯片的 SCL 和 SDA 连接到我的 MAX77651 的 SDA 和 SCL。我的 MAX77651evkit 在 Vbatt 引脚上使用 3.7V 供电。
我还从 git 集线器和 libft4222 安装了 mraa 库。我知道 mraa 安装得很好,因为我用示例进行了尝试。
我听说 mraa 库负责 FT4222 的设置,所以我只使用 mraa 函数来制作我的程序。
我在 Maxim 的网站上搜索集成了 i2c 从地址和一个寄存器,我可以在其中读取数据并检查是否一切正常。然后我阅读了 i2c 通信协议以读取此处可用的单个寄存器:https://datasheets.maximintegrated.com/en/ds/MAX77650-MAX77651.pdf 第 78 页。
利用所有这些信息,我试图制作我的 "test program"。我解决了编译错误,但是当我执行程序时,我无法获取应该为 0xFF 的寄存器中的内容。
这是我的程序:
#include "stdio.h"
#include "syslog.h"
#include "string.h"
#include "unistd.h"
#include "mraa/i2c.h"
#include "mraa.h"
#define I2C_ADDR 0x48
int
main(int argc, char *argv[])
{
uint8_t *message;
*message=0XAC;
int i,j,k;
char reg_a_lire = 0x06;
mraa_init();
mraa_i2c_context i2c;
i2c = mraa_i2c_init(0);
mraa_i2c_frequency(i2c,MRAA_I2C_FAST);
mraa_i2c_address(i2c, I2C_ADDR);
mraa_i2c_write_byte(i2c,0x90);
mraa_i2c_read(i2c, message,1);
mraa_i2c_write_byte(i2c,reg_a_lire);
mraa_init();
mraa_i2c_write_byte(i2c,0x91);
mraa_i2c_read(i2c, message,1);
mraa_i2c_read(i2c, message,1);
printf("%02X \n", *message);
mraa_i2c_stop(i2c);
return 0;
}
这是实际输出:
alex@cyclonit-laptop ~/Test_alex/tests $ ./a.out
AC
而且我想要 FF 而不是 AC。
我认为我的错误可能是由于我错过了初始化 FT4222 或 MAX77651 的原因,我可能没有正确加电并且它不足以在 Vbatt 上施加 3.7V。但也许这是我的程序的问题,因为我对 uint8_t 了解不多,我做错了。
我希望有人对 FT4222 and/or MAX77651 有经验,可以帮助我。
我觉得你被pg搞糊涂了。 75of the MAX77651 datasheet.
ADDRESS | 7-BIT SLAVE ADDRESS | 8-BIT WRITE ADDRESS | 8-BIT READ ADDRESS
Main Address | 0x48, 0b 100 1000 | 0x90, 0b 1001 0000 | 0x91, 0b 1001 0001
(ADDR = 1)* | | |
-------------+---------------------+---------------------+-------------------
Main Address | 0x40, 0b 100 0000 | 0x80, 0b 1000 0000 | 0x81, 0b 1000 0001
(ADDR = 0)* | | |
根据您对 I²C 规范的看法,您要么使用 7 位地址,要么同时使用两个 8 位地址。原因是第一个 I²C 事务发送以下 8 位:
76543210
\_____/\-- R/#W
\------ 7-bit Slave Address
在您的情况下,0x48
向左移动一位,然后是 1
用于读取模式或 0
用于写入模式。注意
(0x40 << 1) | 0x00 == 0x80 == 8-bit Write Address (ADDR = 0)
(0x40 << 1) | 0x01 == 0x81 == 8-bit Read Address (ADDR = 0)
(0x48 << 1) | 0x00 == 0x90 == 8-bit Write Address (ADDR = 1)
(0x48 << 1) | 0x01 == 0x91 == 8-bit Read Address (ADDR = 1)
有些人喜欢使用从属地址,而另一些人则喜欢给出单独的地址,因此很清楚通信的第一个字节是什么样子。
所以你应该从你的代码中删除多余的 mraa_i2c_write_byte(i2c, ...);
行,因为它们的意图似乎是将读取或写入地址发送到从设备。
查看 MRAA library API reference。有抽象读写寄存器的函数,可以是字节宽[8位]寄存器,也可以是字宽[16位]寄存器:
mraa_i2c_read_byte_data
mraa_i2c_read_bytes_data
mraa_i2c_write_byte_data
在这两种情况下,您都应该检查 return 代码以了解操作是否成功。在你的情况下,你的 message
可能没有改变,因为事先有一个 stop/error 条件,因为从机没有确认它的从机地址或者它没有确认你错误的 0x90/0x91 数据字节已发送,因为它们没有作为有效地址出现在 Programmer's Guide 中。
另一个问题是您尝试使用两个连续的读取操作来读取寄存器 INTM_GLBL(0x06;全局中断屏蔽寄存器)。我不确定您是打算读取寄存器 0x06 两次还是打算读取 INT_M_CHG(0x07;充电器的全局中断掩码),因为这不是它会做的。注意 pg 上的描述。 datasheet 的 78 个:
Note that when the MAX77650/MAX77651 receive a stop
they do not modify their register pointer.
这是支持 multi-byte/sequential 读取的 I²C 从设备的典型行为。如果要读取多个寄存器,则必须对多个字节的数据发出顺序读取操作,例如使用 mraa_i2c_read_bytes_data
.
类似下面的内容可能会让您走上正轨。如果发生读取错误,它应该读取 CID 和 CLKS 设置并永远等待。如果成功,它将禁用充电,所有输出,将红色 LED 设置为每隔一秒闪烁一次,并且 - 一旦您取消注释 - 将 On/Off 控制器转换为通过软件打开状态以启用偏置和LED.
#define MAX77651_SLA 0x48u
#define CNFG_GLBL_REG 0x10u
#define CID_REG 0x11u
#define CNFG_CHG_B_REG 0x19u
#define CNFG_SBB0_B_REG 0x2Au
#define CNFG_SBB1_B_REG 0x2Cu
#define CNFG_SBB2_B_REG 0x2Eu
#define CNFG_LDO_B_REG 0x39u
#define CNFG_LED1_A_REG 0x41u
#define CNFG_LED1_B_REG 0x44u
#define CNFG_LED_TOP_REG 0x46u
int main(int argc, char *argv[]) {
uint8_t data;
int res;
mraa_init();
mraa_i2c_context i2c0;
i2c0 = mraa_i2c_init(0);
mraa_i2c_frequency(i2c0, MRAA_I2C_STD);
mraa_i2c_address(i2c0, MAX77651_SLA);
res = mraa_i2c_read_byte_data(i2c0, CID_REG);
if (res < 0) {
printf("Reading CID_REG failed.\n");
mraa_i2c_stop(i2c0);
while(1);
}
data = res;
printf("CID_REG: CLKS = %02X CID = %02X\n", ((data & 0x70u) >> 4), (data & 0x0Fu));
/* you should check return values here */
mraa_i2c_write_byte_data(i2c0, 0x00u /* CHG_EN = off */, CNFG_CHG_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_LDO = off */, CNFG_LDO_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_SBB0 = off */, CNFG_SBB0_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_SBB1 = off */, CNFG_SBB1_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_SBB2 = off */, CNFG_SBB2_B_REG);
/* set up red led to toggle every second */
mraa_i2c_write_byte_data(i2c0, 0x17u /* P = 1s, D = 50% */, CNFG_LED1_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x98u /* FS = 6.4mA, BRT = 5.0mA */, CNFG_LED1_A_REG);
mraa_i2c_write_byte_data(i2c0, 0x01u /* EN_LED_MSTR = on */, CNFG_LED_TOP_REG);
// DANGER ZONE: enable only when you know what this is supposed to do
//mraa_i2c_write_byte_data(i2c0, 0x10u /* SBIA_EN = on, SBIA_LPM = normal */, CNFG_GLBL_REG);
mraa_i2c_stop(i2c0);
while(1);
}
我成功读取了MAX77651的I2C寄存器。
首先查看硬件部分,我必须确保 VIO 具有正确的电压,就像@FRob 在隐藏评论中所说的那样。
然后对于软件,我停止使用 mraa 库,因为我无法控制一切。我使用了 FT4222 库,它允许我打开和启动 FT4222 设备。我在这个库中使用了部分 I2C 示例来初始化设备。然后我注意到我必须先使用 FT4222 的写入功能发送我想读取的寄存器,然后简单地使用读取功能来获取我的结果。这些是所需的两个步骤。
我不会 post 我制作的整个程序,因为它主要取自用于初始化的 I2C 示例,但这是我添加的部分,用于读取我的寄存器 0X06,它应该包含 0xFF:
uint8 resultat=0x11;
uint8 *p_resultat=&resultat;
int chiffre;
slaveAddr
uint16 bytesToWrite2 = 1;
uint16 bytesWritten2=1;
uint8 valeur= 0x06; // REGISTER TO READ
uint8 *p_valeur=&valeur;
FT4222_I2CMaster_Write(ftHandle,slaveAddr,
p_valeur,bytesToWrite2,&bytesWritten); //INDICATES WHICH REGISTER TO
// READ
chiffre = FT4222_I2CMaster_Read(ftHandle,
slaveAddr,p_resultat,1, &bytesRead); // READ REGISTER
printf("The content of the register %02X is : %02X \n " ,
valeur,resultat); // DISPLAY RESULT
printf("reading success if : %d = 0 \n " , chiffre);
// READING SUCCESS ?
使用此代码和初始化我得到以下结果:
alex@cyclonit-laptop ~/Downloads/libft4222-1.2.1.4/examples $ ./a.out
Device 0 is interface A of mode-0 FT4222H:
0x0403601c FT4222 A
Chip version: 42220200, LibFT4222 version: 01020104
The content of the register 06 is : FF
reading success if : 0 = 0
Skipping interface B of mode-0 FT4222H.
如果有人有同样的问题,你可以通过回答这个问题来问我你的问题post.I非常感谢这里帮助过我的人!
我正在尝试在编程之前测试 MAX77651 芯片的 i2c 通信。
这是我的设置:
我有一个 UMFT4222ev 通过 USB 连接到我的 Linux 笔记本电脑。得益于 MAX77651 评估套件,该芯片的 SCL 和 SDA 连接到我的 MAX77651 的 SDA 和 SCL。我的 MAX77651evkit 在 Vbatt 引脚上使用 3.7V 供电。
我还从 git 集线器和 libft4222 安装了 mraa 库。我知道 mraa 安装得很好,因为我用示例进行了尝试。
我听说 mraa 库负责 FT4222 的设置,所以我只使用 mraa 函数来制作我的程序。
我在 Maxim 的网站上搜索集成了 i2c 从地址和一个寄存器,我可以在其中读取数据并检查是否一切正常。然后我阅读了 i2c 通信协议以读取此处可用的单个寄存器:https://datasheets.maximintegrated.com/en/ds/MAX77650-MAX77651.pdf 第 78 页。
利用所有这些信息,我试图制作我的 "test program"。我解决了编译错误,但是当我执行程序时,我无法获取应该为 0xFF 的寄存器中的内容。
这是我的程序:
#include "stdio.h"
#include "syslog.h"
#include "string.h"
#include "unistd.h"
#include "mraa/i2c.h"
#include "mraa.h"
#define I2C_ADDR 0x48
int
main(int argc, char *argv[])
{
uint8_t *message;
*message=0XAC;
int i,j,k;
char reg_a_lire = 0x06;
mraa_init();
mraa_i2c_context i2c;
i2c = mraa_i2c_init(0);
mraa_i2c_frequency(i2c,MRAA_I2C_FAST);
mraa_i2c_address(i2c, I2C_ADDR);
mraa_i2c_write_byte(i2c,0x90);
mraa_i2c_read(i2c, message,1);
mraa_i2c_write_byte(i2c,reg_a_lire);
mraa_init();
mraa_i2c_write_byte(i2c,0x91);
mraa_i2c_read(i2c, message,1);
mraa_i2c_read(i2c, message,1);
printf("%02X \n", *message);
mraa_i2c_stop(i2c);
return 0;
}
这是实际输出:
alex@cyclonit-laptop ~/Test_alex/tests $ ./a.out
AC
而且我想要 FF 而不是 AC。
我认为我的错误可能是由于我错过了初始化 FT4222 或 MAX77651 的原因,我可能没有正确加电并且它不足以在 Vbatt 上施加 3.7V。但也许这是我的程序的问题,因为我对 uint8_t 了解不多,我做错了。
我希望有人对 FT4222 and/or MAX77651 有经验,可以帮助我。
我觉得你被pg搞糊涂了。 75of the MAX77651 datasheet.
ADDRESS | 7-BIT SLAVE ADDRESS | 8-BIT WRITE ADDRESS | 8-BIT READ ADDRESS
Main Address | 0x48, 0b 100 1000 | 0x90, 0b 1001 0000 | 0x91, 0b 1001 0001
(ADDR = 1)* | | |
-------------+---------------------+---------------------+-------------------
Main Address | 0x40, 0b 100 0000 | 0x80, 0b 1000 0000 | 0x81, 0b 1000 0001
(ADDR = 0)* | | |
根据您对 I²C 规范的看法,您要么使用 7 位地址,要么同时使用两个 8 位地址。原因是第一个 I²C 事务发送以下 8 位:
76543210
\_____/\-- R/#W
\------ 7-bit Slave Address
在您的情况下,0x48
向左移动一位,然后是 1
用于读取模式或 0
用于写入模式。注意
(0x40 << 1) | 0x00 == 0x80 == 8-bit Write Address (ADDR = 0)
(0x40 << 1) | 0x01 == 0x81 == 8-bit Read Address (ADDR = 0)
(0x48 << 1) | 0x00 == 0x90 == 8-bit Write Address (ADDR = 1)
(0x48 << 1) | 0x01 == 0x91 == 8-bit Read Address (ADDR = 1)
有些人喜欢使用从属地址,而另一些人则喜欢给出单独的地址,因此很清楚通信的第一个字节是什么样子。
所以你应该从你的代码中删除多余的 mraa_i2c_write_byte(i2c, ...);
行,因为它们的意图似乎是将读取或写入地址发送到从设备。
查看 MRAA library API reference。有抽象读写寄存器的函数,可以是字节宽[8位]寄存器,也可以是字宽[16位]寄存器:
mraa_i2c_read_byte_data
mraa_i2c_read_bytes_data
mraa_i2c_write_byte_data
在这两种情况下,您都应该检查 return 代码以了解操作是否成功。在你的情况下,你的 message
可能没有改变,因为事先有一个 stop/error 条件,因为从机没有确认它的从机地址或者它没有确认你错误的 0x90/0x91 数据字节已发送,因为它们没有作为有效地址出现在 Programmer's Guide 中。
另一个问题是您尝试使用两个连续的读取操作来读取寄存器 INTM_GLBL(0x06;全局中断屏蔽寄存器)。我不确定您是打算读取寄存器 0x06 两次还是打算读取 INT_M_CHG(0x07;充电器的全局中断掩码),因为这不是它会做的。注意 pg 上的描述。 datasheet 的 78 个:
Note that when the MAX77650/MAX77651 receive a stop
they do not modify their register pointer.
这是支持 multi-byte/sequential 读取的 I²C 从设备的典型行为。如果要读取多个寄存器,则必须对多个字节的数据发出顺序读取操作,例如使用 mraa_i2c_read_bytes_data
.
类似下面的内容可能会让您走上正轨。如果发生读取错误,它应该读取 CID 和 CLKS 设置并永远等待。如果成功,它将禁用充电,所有输出,将红色 LED 设置为每隔一秒闪烁一次,并且 - 一旦您取消注释 - 将 On/Off 控制器转换为通过软件打开状态以启用偏置和LED.
#define MAX77651_SLA 0x48u
#define CNFG_GLBL_REG 0x10u
#define CID_REG 0x11u
#define CNFG_CHG_B_REG 0x19u
#define CNFG_SBB0_B_REG 0x2Au
#define CNFG_SBB1_B_REG 0x2Cu
#define CNFG_SBB2_B_REG 0x2Eu
#define CNFG_LDO_B_REG 0x39u
#define CNFG_LED1_A_REG 0x41u
#define CNFG_LED1_B_REG 0x44u
#define CNFG_LED_TOP_REG 0x46u
int main(int argc, char *argv[]) {
uint8_t data;
int res;
mraa_init();
mraa_i2c_context i2c0;
i2c0 = mraa_i2c_init(0);
mraa_i2c_frequency(i2c0, MRAA_I2C_STD);
mraa_i2c_address(i2c0, MAX77651_SLA);
res = mraa_i2c_read_byte_data(i2c0, CID_REG);
if (res < 0) {
printf("Reading CID_REG failed.\n");
mraa_i2c_stop(i2c0);
while(1);
}
data = res;
printf("CID_REG: CLKS = %02X CID = %02X\n", ((data & 0x70u) >> 4), (data & 0x0Fu));
/* you should check return values here */
mraa_i2c_write_byte_data(i2c0, 0x00u /* CHG_EN = off */, CNFG_CHG_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_LDO = off */, CNFG_LDO_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_SBB0 = off */, CNFG_SBB0_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_SBB1 = off */, CNFG_SBB1_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x04u /* EN_SBB2 = off */, CNFG_SBB2_B_REG);
/* set up red led to toggle every second */
mraa_i2c_write_byte_data(i2c0, 0x17u /* P = 1s, D = 50% */, CNFG_LED1_B_REG);
mraa_i2c_write_byte_data(i2c0, 0x98u /* FS = 6.4mA, BRT = 5.0mA */, CNFG_LED1_A_REG);
mraa_i2c_write_byte_data(i2c0, 0x01u /* EN_LED_MSTR = on */, CNFG_LED_TOP_REG);
// DANGER ZONE: enable only when you know what this is supposed to do
//mraa_i2c_write_byte_data(i2c0, 0x10u /* SBIA_EN = on, SBIA_LPM = normal */, CNFG_GLBL_REG);
mraa_i2c_stop(i2c0);
while(1);
}
我成功读取了MAX77651的I2C寄存器。
首先查看硬件部分,我必须确保 VIO 具有正确的电压,就像@FRob 在隐藏评论中所说的那样。
然后对于软件,我停止使用 mraa 库,因为我无法控制一切。我使用了 FT4222 库,它允许我打开和启动 FT4222 设备。我在这个库中使用了部分 I2C 示例来初始化设备。然后我注意到我必须先使用 FT4222 的写入功能发送我想读取的寄存器,然后简单地使用读取功能来获取我的结果。这些是所需的两个步骤。
我不会 post 我制作的整个程序,因为它主要取自用于初始化的 I2C 示例,但这是我添加的部分,用于读取我的寄存器 0X06,它应该包含 0xFF:
uint8 resultat=0x11;
uint8 *p_resultat=&resultat;
int chiffre;
slaveAddr
uint16 bytesToWrite2 = 1;
uint16 bytesWritten2=1;
uint8 valeur= 0x06; // REGISTER TO READ
uint8 *p_valeur=&valeur;
FT4222_I2CMaster_Write(ftHandle,slaveAddr,
p_valeur,bytesToWrite2,&bytesWritten); //INDICATES WHICH REGISTER TO
// READ
chiffre = FT4222_I2CMaster_Read(ftHandle,
slaveAddr,p_resultat,1, &bytesRead); // READ REGISTER
printf("The content of the register %02X is : %02X \n " ,
valeur,resultat); // DISPLAY RESULT
printf("reading success if : %d = 0 \n " , chiffre);
// READING SUCCESS ?
使用此代码和初始化我得到以下结果:
alex@cyclonit-laptop ~/Downloads/libft4222-1.2.1.4/examples $ ./a.out
Device 0 is interface A of mode-0 FT4222H:
0x0403601c FT4222 A
Chip version: 42220200, LibFT4222 version: 01020104
The content of the register 06 is : FF
reading success if : 0 = 0
Skipping interface B of mode-0 FT4222H.
如果有人有同样的问题,你可以通过回答这个问题来问我你的问题post.I非常感谢这里帮助过我的人!