TI中文支持网
TI专业的中文技术问题搜集分享网站

LP-MSP430FR2476: 怎么在多个外设中断下循环执行?

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:

好的,期待您的反馈

赞(0)
未经允许不得转载:TI中文支持网 » LP-MSP430FR2476: 怎么在多个外设中断下循环执行?
分享到: 更多 (0)