Part Number:LP-MSP430FR2476
您好,我用例程改了一个通过硬件eUSCI_B I2C接口控制一个外围传感器,发送采集命令—>连续采集数据,
我发现每运行一次,只能采集一次数据,我单步调试,发现程序停留在最后一行?为什么没有循环调用中断去执行读取数据的动作?非常感谢!
UCB0IE |= UCTXIE0 | UCRXIE0 | UCNACKIE; //开启了收发,无响应中断,
TXByteCtr = 2; // Load TX byte counter,发两个字节命令
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data is TX'd
while(1)
{
RXByteCtl = 9;
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTLW0 &= ~UCTR; // I2C RX
UCB0CTLW0 |= UCTXSTT; // I2C start condition
__bis_SR_register(LPM0_bits|GIE); / / Enter LPM0 w/ interrupt
}
中断处理后,我加了下面这几行,想继续触发RX中断,但是还是不行?
UCB0CTLW0 &= ~UCTR; // I2C RX
UCB0CTLW0 |= UCTXSTT;
UCB0IFG |= UCTXIFG;
RXByteCtl = 9;
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
谢谢!
TI_001:
#include <msp430.h>#include <stdint.h>
uint8_t RXByteCtl;uint8_t RXData[];
uint8_t TXData[]= {0x15, 0x36}; // TX datauint8_t TXByteCtr;
int main(void){ WDTCTL = WDTPW | WDTHOLD; P1SEL0 |= BIT2 | BIT3; // I2C pins
PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings
UCB0CTLW0 |= UCSWRST; // Software reset enabled UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync// UCB0CTLW1 |= UCASTP_2; // Automatic stop generated after UCB0TBCNT is reachedF
UCB0BRW = 10; // fSCL = SMCLK/160 = ~100kHz RXByteCtl = 9; // number of bytes to be received UCB0I2CSA = 0x0025; // Slave address UCB0CTL1 &= ~UCSWRST; UCB0IE |= UCTXIE0 | UCRXIE0 | UCNACKIE; // | UCBCNTIE;
TXByteCtr = 2; // Load TX byte counter while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts // Remain in LPM0 until all data is TX'd while(1) { RXByteCtl = 9; while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTLW0 &= ~UCTR; // I2C RX UCB0CTLW0 |= UCTXSTT; // I2C start condition __bis_SR_register(LPM0_bits|GIE); // Enter LPM0 w/ interrupt
}}#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)#pragma vector = USCI_B0_VECTOR__interrupt void USCIB0_ISR(void)#elif defined(__GNUC__)void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)#else#error Compiler not supported!#endif{ switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)) {
case USCI_NONE: break; // Vector 0: No interrupts case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG UCB0CTL1 |= UCTXSTT; // I2C start condition break; case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 case USCI_I2C_UCTXIFG3: break; // Vector 14: TXIFG3 case USCI_I2C_UCRXIFG2: break; // Vector 16: RXIFG2 case USCI_I2C_UCTXIFG2: break; // Vector 18: TXIFG2 case USCI_I2C_UCRXIFG1: break; // Vector 20: RXIFG1 case USCI_I2C_UCTXIFG1: break; // Vector 22: TXIFG1 case USCI_I2C_UCRXIFG0: // Vector 24: RXIFG0 if(RXByteCtl>0) { __delay_cycles(6000); RXByteCtl–; RXData[RXByteCtl] = UCB0RXBUF; // Get RX data } else { /* display( ); */
UCB0CTLW0 &= ~UCTR; // I2C RX UCB0CTLW0 |= UCTXSTT; UCB0IFG |= UCTXIFG; RXByteCtl = 9; __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } break; case USCI_I2C_UCTXIFG0: if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = TXData[TXByteCtr-1]; // Load TX buffer TXByteCtr–; // Decrement TX byte counter //__delay_cycles(10); } else { UCB0CTLW0 |= UCTXSTP; // I2C stop condition UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } break; case USCI_I2C_UCBCNTIFG: break; // Vector 28: BCNTIFG case USCI_I2C_UCCLTOIFG: break; // Vector 30: clock low timeout case USCI_I2C_UCBIT9IFG: break; // Vector 32: 9th bit default: break; }}
,
TI_001:
具体就是我用的UCB0 I2C 口,
UCB0CTLW0, UCB0CTLW1, UCB0IE, UCB0IFG 这几个register,哪些是用户可以更改(write & read),哪些是系统自己用的(read only)?
谢谢!
,
Susan Yang:
TI_001 说:我用例程改了一个通过硬件eUSCI_B I2C接口控制一个外围传感器
请问您修改的哪个例程?目前MSP430是主机?
TI_001 说:UCB0CTLW0, UCB0CTLW1, UCB0IE, UCB0IFG 这几个register,哪些是用户可以更改(write & read),哪些是系统自己用的(read only)?
这个您可以看一下哦用户手册内的寄存器说明,如
RW就表示可以读也可以写
,
TI_001:
您好,谢谢解答,
再帮我看看,我的代码为什么不能无限循环RX中断?
,
TI_001:
switch(__even_in_range(UCA1IV,USCI_UART_UCSTTIFG)) { case USCI_NONE: break; // Vector 0 – no interrupt case USCI_SPI_UCRXIFG: SPI_RXData = UCA1RXBUF; UCA1IFG &= ~UCRXIFG; __bic_SR_register_on_exit(LPM0_bits); // Wake up to setup next TX break; case USCI_SPI_UCTXIFG: UCA1TXBUF = RTD; // Transmit characters UCB0CTLW0 |= UCTXSTT; RXByteCtrl = 9; break; default: break;
您好,我在A1中断处理后面这么操作,程序能返回到B0中断那里吗?就是在两个中断直接来回循环?谢谢!
,
Susan Yang:
抱歉,之前漏掉了您的回复。请问您现在情况如何了?
,
TI_001:
您好,谢谢!
现在是第二次进入while(1)循环后,hang在第一个while (UCB0CTL1 & UCTXSTP); 不管是TX, RX STT,看到一个topic在说这个现象,有人把LP jumper去掉有效,我试了没有作用。
,
TI_001:
现在是第二次进入while(1)循环后,hang在第一个while (UCB0CTL1 & UCTXSTP); 不管是TX, RX STT,看到一个topic在说这个现象,有人把LP jumper去掉有效,我试了没有作用。
这个很接近我的问题,也是I2C 的clk一直为低了,但是没有说怎么解决?怎么排查?能帮我问下吗?非常感谢!
,
Susan Yang:
SCL一直为低,有可能是程序设计上的问题导致MCU无法读取&填充buffer而导致,建议重点分析MCU I2C中断服务程序
I2C中断服务程序被意外屏蔽
中断服务程序中陷入了一些标志位查询的while(flag != xxx)死循环
I2C功能系统被意外禁止
,
TI_001:
非常感谢您的耐心解答!
我大概发现了问题:示波器这边,我发现其实我已经正确RX到了第一轮的数据,最后一个byte后跟了一个NACK(即高电平),这个也符合user guide描述,没有问题。
但是,然后过了很长时间(大约一半的RX时间)master又发送了一个read-header得到不完整的2byte,(即最后一个byte只有7bit,然后就SDA high, SCL low 持续不变了)。
程序这边,就是停留在__bis_SR_register(LPM0_bits | GIE);等待RX中断了,
为什么会有一个小尾巴?莫名多出来一个read-header和不完整的2byte?
非常感谢!
,
Susan Yang:
TI_001 说:然后过了很长时间(大约一半的RX时间)master又发送了一个read-header得到不完整的2byte
也就是说,之前的RX是正常的,之后某一次RX不正常?
若是可以,能否给出示波器波形?
,
TI_001:
总的图像
正常接收9个字节,以master NACK结束,
这个就是master私自发送读,得到2个不完整数据,破坏了状态吧?
我即使多加一句这个UCB0CTLW1 |= UCASTP_0; 还是一样,
谢谢!
,
TI_001:
UCB0CTL1 &= ~UCTR; // I2C RX UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupt
如果有前面2行,第三行是不是一定会被执行跳转去执行RX中断?
现在问题就是while(1)第二遍就停留在这里了?
谢谢!
,
TI_001:
我如果注释掉RX部分,while里只要TX,可以连续不断发送2 byte commands 出去,TX中断来回循环很顺利。
,
Susan Yang:
TI_001 说:如果有前面2行,第三行是不是一定会被执行跳转去执行RX中断?
这个语句表明进入LPM0且打开了中断
TI_001 说:这个就是master私自发送读,得到2个不完整数据,破坏了状态吧?
看起来是的。我目前对此没有什么想法,单纯看您程序的话,并没有发现什么问题。
,
TI_001:
好的,谢谢您!我再调调看,
,
Susan Yang:
好的,期待您的反馈