嗨,对话框我正在研究peripherals_demo,并找到UART的GPIO端口/引脚的初始化。但是没有代码,做i2c的gpio端口/引脚。我应该初始化I2C的GPIO端口/引脚吗?如何?还是我错过了什么?
谢谢
嗨jamesleo-konka,
请在Peripherals_demo \ config \ default目录中查看gpio_setup.h文件,在那里,您将找到每个gpio的定义,然后在periph_setup.c中找到peirph_setup()函数您将通过hw_gpio_configure找到引脚的初始化() 功能。
谢谢mt_dialog.
嗨MT_Dialog,对不起,我错过了GPIO配置代码,它们被重新定义为CFG_GPIO_I2C1_SCL_PORT,并使用宏HW_GPIO_PINCONFIG初始化。
嗨MT_Dialog,我将以下代码放在项目hrp_sensor的peri_setup中://------------------------------// ----- I2C端口/引脚配置------ P3.5 = SCL,P1.2 = SDA --------hw_gpio_configure_pin(hw_gpio_port_3,hw_gpio_pin_5,hw_gpio_mode_output,hw_gpio_func_gpio,true);hw_gpio_configure_pin(hw_gpio_port_1,hw_gpio_pin_2,hw_gpio_mode_input_pullup,hw_gpio_func_gpio,true);
hw_gpio_set_pin_function(hw_gpio_port_3,hw_gpio_pin_5,hw_gpio_mode_output,hw_gpio_func_i2c_scl);hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_2, HW_GPIO_MODE_INPUT_PULLUP, HW_GPIO_FUNC_I2C_SDA);//------------------------------这样对吗?我对2 init函数有点混淆:hw_gpio_configure_pin,hw_gpio_set_pin_function。对于PIN,我们可以将其设置为输入/输出(带/无拉,或PUSH_PULL或SPEED),然后我们设置备用功能。为什么我应该在2个函数中将模式(输入/输出)设置两次?
为什么RX引脚设置为输出:hw_gpio_configure_pin(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, 1);hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART2_RX);?
在platform_devices.h中,有很多行来初始化I2C设备,比如:I2C_SLAVE_DEVICE(I2C1, BH1750, 0x23, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_FAST);
但我找不到BH1750的定义,MEM_24LC256,FM75 ,,,,,,They在AD_I2C_OPEN()中也使用。
HW_GPIO_CONFIGURE_PIN()包括HW_GPIO_SET_PIN_FUNCT()您可以查看代码或DOXYGEN以获取每个功能的描述。hw_gpio_set_pin_function()足以配置您的引脚,HW_GPIO_CONFIGURE_PIN()执行相同的操作,但如果它将处于活动状态,则此外设置默认状态。关于将UART RX设置为输出和使用两个GPIO函数的原因,以便设置UART的RX,我想在HRP_Sensor项目的Periph_Init()函数中看到它,所以右上方引脚的设置有一个解释,简而言之,这是jlink仿真串口的解决方法。
没有定义——它们只是宏I2C_SLAVE_DEVICE所使用的名称,完成这些操作后,您就可以使用它们来打开适配器。
嗨MT_Dialog,以下是使用I2C适配器的正确顺序:1.首先声明I2C设备:I2C_BUS(I2C1)i2c_slave_device(i2c1,bme280,0x76,hw_i2c_addressing_7b,hw_i2c_speed_standard);//I2C_BUS_END.2.操作I2C设备i2c_device dev;静态char wbuf [5] =“test”;char rbuf [5];dev = ad_i2c_open(bme280);/ *打开所选设备* /ad_i2c_bus_acquire(dev);/ *获取访问总线* /ad_i2c_write(dev,wbuf,sizeof(wbuf));/ *将某些数据同步写入I2C设备* /// - 这将生成启动,发送从地址(W),发送REG地址,写入数据Ad_i2c_read (dev, rbuf, sizeof(rbuf), 100);/*同步读取I2C设备的数据*/ // I2C改变方向,生成RESTART, send SLAVE address(R),send reg address,读取数据,生成STOPad_i2c_bus_release (dev);/ *释放I2Cad_i2c_close(dev);/ *关闭所选设备* /
另一个问题:1.什么时候使用ad_i2c_init()?2.启动任务后是否应该调用ad_i2c_xx ?上电复位后(没有任务运行)是否可以进行I2C设备初始化?4.要将一个数据写入I2C设备的寄存器,我可以参考以下内容:ad_i2c_write(dev,wbuf,2);// 2字节,first = reg地址,第二个=数据
嗨MT_dialog非常感谢。有太多的宏,它不容易分析/跟踪源代码。
示例项目peripherals_demo使用户与hw_i2c_xx和ad_i2c_xx混淆,特别是在EEPROM_24XX256.c中。HW_I2C_XX和AD_I2C_XX都同时使用。
用户何时调用ad_i2c_init()?我没有找到调用AD_I2C_INIT()的代码。
詹姆士
您调用的命令的序列取决于您使用的SDK,例如在最新的SDK上:
是的,您在I2C总线上对设备的分配是正确的。
2)的处理设备,当你即将开始一个事务是适当的(ad_i2c_open (BME280))也是正确的,这个ad_i2c_bus_aquire ad_i2c_write以来()不是必需的()和ad_i2c_read()执行公共汽车的本事和设备也释放总线和设备。
同时,直接把事情因为你想生成一个重启状态,启动条件生成从总线读取时,这意味着你将不得不提供(因此写在i2c总线)寄存器的地址,你会喜欢阅读,上面的代码我不认为会在ad_i2c_write()和ad_i2c_read()之间产生一个重启条件(重启条件是在ad_i2c_read()操作期间在总线上的写和读之间触发)。据我所知,在ad_i2c_write和ad_i2c_read之间应该有一个STOP条件。重新启动条件是在您在文章中提到它的地方生成的。
关于你的其他问题:
1) ad_i2c_init()在prvSetupHardware()中的system_init()函数中被调用,在pm_system_init()函数中有一个额外的函数init_adapters(),从这个函数中所有启用的适配器都被初始化。
2)系统将让适配器知道唤醒或启动,适配器将初始化hw,只要你配置了它们,这发生在系统上电或启动默认情况下。
是的,我想你能做到。
嗨,mt_dialog,感谢您的帮助,我的AD_I2C_XX已开始,我得到了I2C端口的输出。ad_i2c_write()和ad_i2c_read()似乎无法生成RESTART信号,因为它们都完成了I2C操作的完整步骤:START, SLAVE address (W/R), data(W/R),,,,STOP。如果用户使用HW_I2C_XX生成重启信号吗?请告诉我一个示例代码。
正如上面提到的,通常生成的启动条件当你想读值从I2C奴隶(I2C总线上的大师写的地址注册,喜欢阅读,然后重启问题为了开始阅读)。ad_i2c_write()和ad_i2c_read()将分别执行写和读。对于68x所配备的当前I2C模块,你不能写,然后强制重启条件,以写入地址进行读操作。其原因是,如上所述,I2C模块将自动生成STOP条件时,其FIFO是空的,并重启条件时,您更改操作。
所以让我们假设你在从站开始编写数据,你决定你想读取,所以你必须写的奴隶地址,你想在公共汽车上读取,所以你将提供您希望读到I2C FIFO的地址,以免生成停止(请记住您的FIFO是否为空I2C将发送停止条件)。如果您提供了您希望读取模块的I2C从设备的地址,则没有一种方式知道这是一个地址,并且您现在要读取的方式,并将在与数据相同的交易上发送地址,由于您没有从WRITE切换到读取以便生成重启。
综上所述,我不知道为了强制重启I2C条件(也许你可以做一个虚拟读取来强制重启,然后开始正确的读取事务,写入地址并再次读取,但这将导致两个RESTART条件,我可以告诉,我不确定任何slave将处理这),尽管我不能看到什么是错误的停止条件之间的实际读和写?
嗨jamesleo-konka,
请在Peripherals_demo \ config \ default目录中查看gpio_setup.h文件,在那里,您将找到每个gpio的定义,然后在periph_setup.c中找到peirph_setup()函数您将通过hw_gpio_configure找到引脚的初始化() 功能。
谢谢mt_dialog.
嗨MT_Dialog,
对不起,我错过了GPIO配置代码,它们被重新定义为CFG_GPIO_I2C1_SCL_PORT,并使用宏HW_GPIO_PINCONFIG初始化。
谢谢
嗨MT_Dialog,
我将以下代码放在项目hrp_sensor的peri_setup中:
//------------------------------
// ----- I2C端口/引脚配置------ P3.5 = SCL,P1.2 = SDA --------
hw_gpio_configure_pin(hw_gpio_port_3,hw_gpio_pin_5,hw_gpio_mode_output,hw_gpio_func_gpio,true);
hw_gpio_configure_pin(hw_gpio_port_1,hw_gpio_pin_2,hw_gpio_mode_input_pullup,hw_gpio_func_gpio,true);
hw_gpio_set_pin_function(hw_gpio_port_3,hw_gpio_pin_5,hw_gpio_mode_output,hw_gpio_func_i2c_scl);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_2, HW_GPIO_MODE_INPUT_PULLUP, HW_GPIO_FUNC_I2C_SDA);
//------------------------------
这样对吗?
我对2 init函数有点混淆:hw_gpio_configure_pin,hw_gpio_set_pin_function。
对于PIN,我们可以将其设置为输入/输出(带/无拉,或PUSH_PULL或SPEED),然后我们设置备用功能。
为什么我应该在2个函数中将模式(输入/输出)设置两次?
为什么RX引脚设置为输出:
hw_gpio_configure_pin(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, 1);
hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART2_RX);?
在platform_devices.h中,有很多行来初始化I2C设备,比如:
I2C_SLAVE_DEVICE(I2C1, BH1750, 0x23, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_FAST);
但我找不到BH1750的定义,MEM_24LC256,FM75 ,,,,,,They在AD_I2C_OPEN()中也使用。
谢谢
嗨jamesleo-konka,
HW_GPIO_CONFIGURE_PIN()包括HW_GPIO_SET_PIN_FUNCT()您可以查看代码或DOXYGEN以获取每个功能的描述。hw_gpio_set_pin_function()足以配置您的引脚,HW_GPIO_CONFIGURE_PIN()执行相同的操作,但如果它将处于活动状态,则此外设置默认状态。关于将UART RX设置为输出和使用两个GPIO函数的原因,以便设置UART的RX,我想在HRP_Sensor项目的Periph_Init()函数中看到它,所以右上方引脚的设置有一个解释,简而言之,这是jlink仿真串口的解决方法。
没有定义——它们只是宏I2C_SLAVE_DEVICE所使用的名称,完成这些操作后,您就可以使用它们来打开适配器。
谢谢mt_dialog.
嗨MT_Dialog,
以下是使用I2C适配器的正确顺序:
1.首先声明I2C设备:
I2C_BUS(I2C1)
i2c_slave_device(i2c1,bme280,0x76,hw_i2c_addressing_7b,hw_i2c_speed_standard);//
I2C_BUS_END.
2.操作I2C设备
i2c_device dev;
静态char wbuf [5] =“test”;
char rbuf [5];
dev = ad_i2c_open(bme280);/ *打开所选设备* /
ad_i2c_bus_acquire(dev);/ *获取访问总线* /
ad_i2c_write(dev,wbuf,sizeof(wbuf));/ *将某些数据同步写入I2C设备* /// - 这将生成启动,发送从地址(W),发送REG地址,写入数据
Ad_i2c_read (dev, rbuf, sizeof(rbuf), 100);/*同步读取I2C设备的数据*/ // I2C改变方向,生成RESTART, send SLAVE address(R),send reg address,读取数据,生成STOP
ad_i2c_bus_release (dev);/ *释放I2C
ad_i2c_close(dev);/ *关闭所选设备* /
另一个问题:
1.什么时候使用ad_i2c_init()?
2.启动任务后是否应该调用ad_i2c_xx ?上电复位后(没有任务运行)是否可以进行I2C设备初始化?
4.要将一个数据写入I2C设备的寄存器,我可以参考以下内容:
ad_i2c_write(dev,wbuf,2);// 2字节,first = reg地址,第二个=数据
谢谢
嗨MT_dialog
非常感谢。
有太多的宏,它不容易分析/跟踪源代码。
示例项目peripherals_demo使用户与hw_i2c_xx和ad_i2c_xx混淆,特别是在EEPROM_24XX256.c中。HW_I2C_XX和AD_I2C_XX都同时使用。
用户何时调用ad_i2c_init()?我没有找到调用AD_I2C_INIT()的代码。
詹姆士
嗨jamesleo-konka,
您调用的命令的序列取决于您使用的SDK,例如在最新的SDK上:
是的,您在I2C总线上对设备的分配是正确的。
2)的处理设备,当你即将开始一个事务是适当的(ad_i2c_open (BME280))也是正确的,这个ad_i2c_bus_aquire ad_i2c_write以来()不是必需的()和ad_i2c_read()执行公共汽车的本事和设备也释放总线和设备。
同时,直接把事情因为你想生成一个重启状态,启动条件生成从总线读取时,这意味着你将不得不提供(因此写在i2c总线)寄存器的地址,你会喜欢阅读,上面的代码我不认为会在ad_i2c_write()和ad_i2c_read()之间产生一个重启条件(重启条件是在ad_i2c_read()操作期间在总线上的写和读之间触发)。据我所知,在ad_i2c_write和ad_i2c_read之间应该有一个STOP条件。重新启动条件是在您在文章中提到它的地方生成的。
关于你的其他问题:
1) ad_i2c_init()在prvSetupHardware()中的system_init()函数中被调用,在pm_system_init()函数中有一个额外的函数init_adapters(),从这个函数中所有启用的适配器都被初始化。
2)系统将让适配器知道唤醒或启动,适配器将初始化hw,只要你配置了它们,这发生在系统上电或启动默认情况下。
是的,我想你能做到。
谢谢mt_dialog.
嗨,mt_dialog,
感谢您的帮助,我的AD_I2C_XX已开始,我得到了I2C端口的输出。
ad_i2c_write()和ad_i2c_read()似乎无法生成RESTART信号,因为它们都完成了I2C操作的完整步骤:START, SLAVE address (W/R), data(W/R),,,,STOP。
如果用户使用HW_I2C_XX生成重启信号吗?请告诉我一个示例代码。
谢谢
嗨jamesleo-konka,
正如上面提到的,通常生成的启动条件当你想读值从I2C奴隶(I2C总线上的大师写的地址注册,喜欢阅读,然后重启问题为了开始阅读)。ad_i2c_write()和ad_i2c_read()将分别执行写和读。对于68x所配备的当前I2C模块,你不能写,然后强制重启条件,以写入地址进行读操作。其原因是,如上所述,I2C模块将自动生成STOP条件时,其FIFO是空的,并重启条件时,您更改操作。
所以让我们假设你在从站开始编写数据,你决定你想读取,所以你必须写的奴隶地址,你想在公共汽车上读取,所以你将提供您希望读到I2C FIFO的地址,以免生成停止(请记住您的FIFO是否为空I2C将发送停止条件)。如果您提供了您希望读取模块的I2C从设备的地址,则没有一种方式知道这是一个地址,并且您现在要读取的方式,并将在与数据相同的交易上发送地址,由于您没有从WRITE切换到读取以便生成重启。
综上所述,我不知道为了强制重启I2C条件(也许你可以做一个虚拟读取来强制重启,然后开始正确的读取事务,写入地址并再次读取,但这将导致两个RESTART条件,我可以告诉,我不确定任何slave将处理这),尽管我不能看到什么是错误的停止条件之间的实际读和写?
谢谢mt_dialog.