Other Parts Discussed in Thread: MSP430F5529, LM75A
主题中讨论的其他器件: 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 执行读取操作、无法打开链接。
感谢你的帮助。