主题中讨论的其他器件: LM75A
大家好、我将使用具有 msp430f5529的定制板。 MSP 具有多个 i2c 从器件(通过 LTC4315f 总线缓冲器连接的单个板载 LM75A 和两个非板载 LM75A)。
MSP 本身也是 Raspberry PI4的从器件。 I2C 主器件和从器件分别为 USCI_B0和 B1。
问题是:Raspberry 会启动循环(while true)命令、例如询问非板载 LM75A。 系统在一段时间内正常工作(例如5个周期或6分钟不间断、它未固定)、然后它挂起。 主机等待10秒超时、但 MSP 挂起忙。
MSP 的 I2C_MASTER 代码从官方库中的 MSP430F55xx_USCI_i2c_standard_master.c 复制。
下面的主 Init 代码。 时钟源为 SMCLK:
void I2C_init() { //initClockTo16MHz(); I2C_INIT_GPIO(); UCB0CTL1 |= UCSWRST; //启用 SW 复位 UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式 UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位 UCB0BR0 = 10;//160; //1.01/10 ~100kHz // fSCL = SMCLK/160 =~100kHz UCB0BR1 = 0; UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作 UCB0IE |= UCNACKIE; }
I2C 从设备是定制的:
void initGPIO() { //I2C 引脚 P4SEL |= BIT1 | BIT2; } void initI2C() { UCB1CTL1 |= UCSWRST; //启用 SW 复位 UCB1CTL0 = UCMODE_3 + UCSYNC; // I2C 主设备,同步模式 UCB1CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位 UCB1I2COA = SLAVE_ADDR; //自有地址 UCB1BR0 = 1;//160; UCB1BR1 = 0; UCB1CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作 UCB1IE |=(UCRXIE | UCTXIE| UCSTPIE | UCSTTIE | UCALIE | UCNACKIE); } int I2C_SLAVE_INIT (void){ initGPIO(); initi2C(); 返回0; } //********* // I2C 中断 // enum i2c_slave_Stage{waiting_for_start、receive_REG_ADDR、 waiting_for_data_or_restart、transmit 数据、waiting for _stop}; enum i2c_slave_Stage = waiting_for_start; void read_i2c_data(){ uint8_t temp = UCB1RXBUF; if (stage== receive_REG_ADDR){ I2C_offset =(temp > sizeof (i2c_interface_struct))? sizeof (i2c_interface_struct):temp; Stage = WAITING_OR_DATA_OR_RESTART; }否则、如果(STAGE = WAITING_OR_DATA_OR_RESTART)为{ (*(((uint8_t*)(&i2c_interface_struct))+i2c_offset))= temp; Stage = WAITING_FAND_STOP; }否则{ //生成 NAK UCB1CTL1 |= UCTXNACK; } #if Defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__) #pragma vector=USCI_B1_Vector __interrupt void USCI_B1_ISR (void) #Elif Defined (__GISR__)__USCI_B1_COMPILE_INTERRUCTB1_ERROR (void)(USCI_BI_BIST_BINC_BIST_ERROR)(UB1)(UBINC_COMPLE= UBIST_ERROR)(UBIST_BIST_BIST_ERROR) #endif { volatile uint8_t temp; switch (__evo_in_range (UCB1IV、0xC) ){ USCI_NONE 案例: 中断; //向量0 -无中断 USCI_I2C_UCALIFG 案例: 中断; //中断矢量:I2C 模式:UCALIFG USCI_I2C_UCNACKIFG 案例: 中断; //中断矢量:I2C 模式:UCNACKIFG USCI_I2C_UCSTTIFG 案例: 如果(阶段= WAITING_OR_RESTART) 阶段=传输数据; 其他 阶段=接收_REG_ADDR; 中断; //中断矢量:I2C 模式:UCSTTIFG USCI_I2C_UCSTPIFG 案例: //修复:写入事务中的停止可能先于数据 IF (UCB1IFG 和 UCRXIFG){ //(*((((uint8_t*)(&i2c_interface_struct))+i2c_offset))= UCB1RXBUF; read_i2c_data(); } I2C_OFFSET=0; 阶段= WAITING_FAND_START; 中断; //中断矢量:I2C 模式:UCSTPIFG USCI_I2C_UCRXIFG 案例: read_i2c_data(); 中断; //中断矢量:I2C 模式:UCRXIFG USCI_I2C_UCTXIFG 案例: //修复:不要检查 stage=transmit 数据(在 regAddr 之前可能会在写事务中重新启动) UCB1TXBUF =*(((uint8_t*)(&i2c_interface_struct))+ i2c_offset); while (UCB1IFG 和 UCTXIFG); 中断; //中断矢量:I2C 模式:UCTXIFG 默认值:中断; } }
代码在第88行挂起( while (UCB1IFG & UCTXIFG); ) *未确定突出显示的工作方式*
以下是传感器检查代码。 首先、通过缓冲器建立线路、然后读取传感器、然后关闭总线。
if (LTC4315_BUS_ENABLE (LTC4315_I2C_address、LTC4315_BUS2)){// 41 - LTC if (LM75A_Read_temperature1 (&temp))){ temp_storage.device2_temperature_storage =(uint32_t) temp; } } LTC4315_BUS_DISABLE (LTC4315_I2C_ADDRESS、LTC4315_BUS2);
无论是否连接了调试器、都会捕获挂起。 有时我在_bis_SR_register (LPM0_bits + GIE)上捕获到调试器;I2C_Master_WriteReg 的字符串、无法关闭 LTC 行、但调试器说 UCB1_ISR 正在使用(从站)。 那么、我想知道、UCB0_ISR 和 UCB1_ISR 之间是否会有冲突? 或者、我只是看不到它是不是太多了?
也许很重要:系统在 main 的 while (1)循环中工作。 还有 UART、SPI 和 RTC_A 工作正常。 此外、我尝试从 I2C 主设备删除 LPM0、但后来无法使用 LTC 执行读取操作、无法打开链接。
感谢你的帮助。