主题中讨论的其他部件:TMP100, MSP430WARE
在我的代码中,我启用了所有USI_B模块的中断,设置了GIE位,并有一个具有正确中断向量的ISR。 (使用TI示例代码中的矢量和ISR名称)目前我使用轮询来实现I2C。 但是我想以正确的方式使用中断来节省电能,因为这将是一个电池供电的设备。
使用轮询,我已验证正在设置对应的TX标志,并通过逻辑分析器验证从属设备确认了每个字节。 我无法理解为什么ISR不能运行。 下面的相关代码块:
USI_B初始化块:
//初始化USI_B0到标准速度I2C主模式。 PIN已分配给SCL和SDA。 UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC; // 7位寻址,单主 UCB0CTL1 || UCSSEL_2 | UCTR | UCSWRST; //发送器模式,来自SMCLK UCB0BR1 =0; //将高波特率寄存器设置为0 UCB0BR0 = I2C_CLOCK_DIV; // 100KHz总线频率,源自16MHz SMCLK除以40 UCB0STAT = 0; //重置状态更改标记 IFG2 &=~(UCB0TXIFG | UCB0RXIFG); //重置传输和接收标记 UCB0I2CIE = UCNACKIE | UCSTPIE | UCSTIE | UCALEI;//为所有总线状态更改启用中断 IE2 |= UCB0RXIE | UCB0TXIE; //启用I2C接收和传输的中断(默认情况下启用传输) UCB0I2CSA = 0; //将从属地址初始化为0 UCB0CTL1 &=~UCSWRST; //重置UCSWRST,启动I2C通信
__bis_sr_register (GIE); //启用全局中断
I2C总线初始化环路:
同时(~status和MCP2.3018万_init){ //当MCP2.3018万未初始化时
如果(IFG2和UCB0TXIFG || INTERRUCK_TEST > 0){ //如果是加载TXBUFFER的时间
如果(~status & MCP2.3018万_init){ //如果MCP2.3018万未初始化:
如果(i2c_i > OLATB+1){ //如果这是最后一个寄存器之后的位:
I2C_I = 0; //重置i2c迭代器
UCB0CTL1 || UCTXSTP; //传输停止信号
status |= MCP2.3018万_init;
}
UCB0TXBUF = MCP2.3018万_INIT_DATA[i2c_i]; //将init数据数组中的相应字节放入TX缓冲区
I2C_I++; //递增i2c迭代
器}
}否则,如果(UCB0I2CSA ==0){ //否则:如果从地址为0
UCB0I2CSA = MCP2.3018万_opcode; //写入模式的加载从属地址+0
UCB0CTL1 || UCTXSTT; //发送I2C启动条件
} 如果(UCB0STAT和UCNACKIFG){ //如果收到了nack
UCB0STAT &=~UCNACKIFG; //清除标记
I2C_I = 0; //将地址迭代器重置为0
UCB0CTL1 || UCTXSTT; //设置启动条件
IFG2 |= UCB0TXIFG; //设置TX标志
}
//__bis_sr_register (LPM0_bits + GIE); //关闭CPU以节省电源,启用全局中断
}
P1OUT |= BIT0; //初始化时亮起LED1
I2C数据ISR:
#pragma vector=USCIAB0TX_vector //由于USI_B处于I2C模式,因此这是I2C数据ISR
__interrupt void USICIAB0TX_ISR(void){ //如果USI_B TX寄存器为空或RX寄存器已满
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits); //清除位以唤醒CPU
} //返回主环路
I2C状态ISR:
#pragma vector=USCIAB0RX_vector //由于USI_B处于I2C模式,因此这是I2C状态ISR
__interrupt void USICIAB0RX_ISR(void){ //当I2C状态改变时
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits); //清除位以唤醒CPU
} //返回主环路