了解更多常见问题解答教程

4个职位/ 0个新职位
最后一篇
ahiggs
离线
最后看到:4个月2个星期前
加入:2019-12-17 07:10
多个I2C总线

你好,

我有一个关于在DA14585上使用多个I2C总线的问题。我正在使用MCP9600热电偶放大器,每个有8个可能的地址。我需要将64个传感器连接到DA14585,并以~1Hz读取它们。

我的计划是设置8个独立的总线,每个总线都有自己的数据线和一个共享时钟(在DA14585上总共使用9个引脚)。DA14585将设置I2C控制器的基础上,它想要交谈的总线和当它完成这个总线,让数据线保持高。从I2C的角度来看,非活动总线上的芯片在总线不活动时看到的是常数1,这比其他配置更好,在其他配置中每个芯片都有自己的时钟,芯片看到的是常数停止/启动命令。

我唯一不确定的是如何在代码中完成这一点。我想将其设置为这样,以便我可以通过公共汽车切换。是必要的保留_gpio()命令,或者会让事情混淆吗?否则我认为这会有效

void init_MCP(void){RESERVE_GPIO(,ALL_SCL_PORT, ALL_SCL_PIN, PID_I2C_SCL);RESERVE_GPIO (BUS1_SDA_PORT BUS1_SDA_PIN, PID_I2C_SDA); / / ? ?RESERVE_GPIO (BUS2_SDA_PORT BUS2_SDA_PIN, PID_I2C_SDA); / / ? ?剩余的针……GPIO_ConfigurePin(ALL_SCL_PORT, ALL_SCL_PIN, INPUT, PID_I2C_SCL, false);} void select_MCP_BUS(uint8_t BUS_NUMBER){switch BUS_NUMBER: case 1: GPIO_ConfigurePin(BUS1_SDA_PORT, BUS1_SDA_PIN, INPUT, PID_I2C_SDA, false);for(所有其他总线)GPIO_ConfigurePin(BUS1_SDA_PORT, BUS1_SDA_PIN, INPUT, PID_GPIO, false);打破;case 2: GPIO_ConfigurePin(BUS2_SDA_PORT, BUS2_SDA_PIN, INPUT, PID_I2C_SDA, false);for(所有其他总线)GPIO_ConfigurePin(BUS1_SDA_PORT, BUS1_SDA_PIN, INPUT, PID_GPIO, false); break; case 3: remaining busses... } void send_temperature(){ for(all 8 busses){ select_MCP_BUS(bus#) for(all 8 MCPs){ sample_send_temp(MCP#) } } }

我知道我可以使用一个I2C mux来完成这个,但我们的空间有限,它只是一个额外的组件,可能会失败

设备:
PM_Dialog
离线
最后看到:3小时59分钟前
职员
加入:2018-02-08 11:03
嗨ahiggs,

嗨ahiggs,

感谢您在线的问题,详细描述。我们没有演示所描述的功能的示例,但这可能是一种可能的方法。每次要更改“BUS_NUMBER”时,您应该将适当的GPIO重新配置为I2C引脚。你在HW设置上测试了吗?

谢谢,PM_Dialog

ahiggs
离线
最后看到:4个月2个星期前
加入:2019-12-17 07:10
你好,

你好,

感谢你的及时回复。我只在其中一个总线上使用MCP9600S测试了硬件设置,但它有效。我还没有设计电路板以测试完整的系统。如果有人有兴趣,这是这个设置的代码片段

void sensor_init(){adc_calibrate();adc_timer [0] = app_easy_timer(adc_timer_delay [0],readadc0);//检查定时器是否可用(int a = 0; a <1; a ++){if(adc_timer [a] ==yeasy_timer_invalid_timer){whis(1); // badbadbad}} // for mcp放大器:boolinit_error = false;READ_ADC [0] = 1;init_i2c();for(Uint8_t i = 0; i <1; i ++){//初始化1总线(8 max)set_i2c_bus(i + 1); // 1索引(UInt8_t a = 0; <2; a ++){//初始化2个传感器((8 max)IF(!init_mcp(a))// 0索引init_rure;}}}}}}}}}}}} void init_i2c(void){//初始化mcp芯片gpio_configurepin的i2c总线(i2c_scl_port,i2c_scl_pin,input_pullup,pid_i2c_scl,false); //不要配置SDA PIN you} void set_i2c_bus(uint8_t总线){//选择哪些数据线用于i2c //从pid_i2c_sda //释放其他引脚,我认为这可能是更清晰的使用最后一个引脚被跟踪...... GPIO_ConfigurePin(I2C_SDA1_PORT,I2C_SDA1_PIN,INPUT,PID_GPIO,FALSE); GPIO_ConfigurePin(I2C_SDA2_PORT,I2C_SDA2_PIN,INPUT,PID_GPIO,FALSE); GPIO_ConfigurePin(I2C_SDA3_PORT,I2C_SDA3_PIN,INPUT,PID_GPIO,FALSE); GPIO_ConfigurePin(I2C_SDA4_PORT,I2C_SDA4_PIN,INPUT,PID_GPIO,FALSE); GPIO_CONFIGUREPIN(I2C_SDA5_POR,I2C_SDA5_PIN,INPUT,PID_GPIO,FALSE); GPIO_CONFIGUREPIN(I2C_SDA6_PORT,I2C_SDA6_PIN,INPUT,PID_GPIO,FALSE); GPIO_CONFIGUREPIN(I2C_SDA7_PORT,I2C_SDA7_PIN,INPUT,PID_GPIO,FALSE); GPIO_ConfigurePin(I2C_SDA8_PORT, I2C_SDA8_PIN, INPUT, PID_GPIO, false); //set the new bus pin to PID_I2C_SDA switch(bus){ case 1: GPIO_ConfigurePin(I2C_SDA1_PORT, I2C_SDA1_PIN, INPUT, PID_I2C_SDA, false); break; case 2: GPIO_ConfigurePin(I2C_SDA2_PORT, I2C_SDA2_PIN, INPUT, PID_I2C_SDA, false); break; case 3: GPIO_ConfigurePin(I2C_SDA3_PORT, I2C_SDA3_PIN, INPUT, PID_I2C_SDA, false); break; case 4: GPIO_ConfigurePin(I2C_SDA4_PORT, I2C_SDA4_PIN, INPUT, PID_I2C_SDA, false); break; case 5: GPIO_ConfigurePin(I2C_SDA5_PORT, I2C_SDA5_PIN, INPUT, PID_I2C_SDA, false); break; case 6: GPIO_ConfigurePin(I2C_SDA6_PORT, I2C_SDA6_PIN, INPUT, PID_I2C_SDA, false); break; case 7: GPIO_ConfigurePin(I2C_SDA7_PORT, I2C_SDA7_PIN, INPUT, PID_I2C_SDA, false); break; case 8: GPIO_ConfigurePin(I2C_SDA8_PORT, I2C_SDA8_PIN, INPUT, PID_I2C_SDA, false); break; } } bool init_MCP(uint8_t addr){ user_i2c_init(0x60+addr, I2C_7BIT_ADDR, I2C_STANDARD, I2C_1BYTE_REGISTER, I2C_1BYTE_ADDR); //device config register, 0.0625°C ambient accuracy, 18-bit, 1 sample, shutdown mode: 0b00000001 (highest accuracy settings) if(i2c_write_2byte_MCP(0x06, 0x02)!=I2C_NO_ERROR) return 0; //initialize next sample: device status register 0x04, clear bit7 to start sample, other bits can be cleared too if(i2c_write_2byte_MCP(0x04, 0x00)!=I2C_NO_ERROR) return 0; SetWord16(I2C_ENABLE_REG, 0x0); // Disable the I2C controller SetBits16(CLK_PER_REG, I2C_ENABLE, 0); // Disable clock for I2C return 1; } uint16_t read_MCP(uint8_t addr){//read the MCP, assuming the temperature is ready user_i2c_init(0x60+addr, I2C_7BIT_ADDR, I2C_STANDARD, I2C_1BYTE_REGISTER, I2C_1BYTE_ADDR); uint16_t value=0; //device config register, 0.0625°C ambient accuracy, 18-bit, 1 sample, shutdown mode: 0b00000001 (highest accuracy settings) if(i2c_write_2byte_MCP(0x06, 0x02)!=I2C_NO_ERROR) return 0; //select register to read by first writing to select it: 0x00 for hot, 0x02 for cold(chip) temperature if(i2c_write_byte_MCP(0x00)!=I2C_NO_ERROR) value=0xFFFF; //read the two bytes from the register if(i2c_read_2byte_MCP(&value)!=I2C_NO_ERROR) value=0xFFFF; //initialize next sample: device status register, clear bit7 to start sample, other bits can be cleared too if(i2c_write_2byte_MCP(0x04, 0x00)!=I2C_NO_ERROR) value=0xFFFF; SetWord16(I2C_ENABLE_REG, 0x0); // Disable the I2C controller SetBits16(CLK_PER_REG, I2C_ENABLE, 0); // Disable clock for I2C return value;//right shift by 4 to get integer temperature (or do temp °C = MSB*16+LSB/16 if greater than 0) } #define I2C_SCL_PORT GPIO_PORT_0//pin 1 on QFN40 chip #define I2C_SCL_PIN GPIO_PIN_0 #define I2C_SDA1_PORT GPIO_PORT_0//pin 2 on QFN40 chip #define I2C_SDA1_PIN GPIO_PIN_1 #define I2C_SDA2_PORT GPIO_PORT_0//pin 3 on QFN40 chip #define I2C_SDA2_PIN GPIO_PIN_2 #define I2C_SDA3_PORT GPIO_PORT_0 #define I2C_SDA3_PIN GPIO_PIN_3 #define I2C_SDA4_PORT GPIO_PORT_2//would use P0_4, but used by UART #define I2C_SDA4_PIN GPIO_PIN_0 #define I2C_SDA5_PORT GPIO_PORT_3 #define I2C_SDA5_PIN GPIO_PIN_0 #define I2C_SDA6_PORT GPIO_PORT_2//would use P0_5 but used by UART #define I2C_SDA6_PIN GPIO_PIN_9 #define I2C_SDA7_PORT GPIO_PORT_2 #define I2C_SDA7_PIN GPIO_PIN_1 #define I2C_SDA8_PORT GPIO_PORT_1//would use P0_6 but used by UART #define I2C_SDA8_PIN GPIO_PIN_2

PM_Dialog
离线
最后看到:3小时59分钟前
职员
加入:2018-02-08 11:03
嗨ahiggs,

嗨ahiggs,

谢谢你的意见。如果您有任何其他问题,请提出一个新的论坛线程。

谢谢,PM_Dialog