1. UCB0CTL1 |= UCTXSTT; // I2C start condition
这句执行开始条件就马上进入IIC中断吗?还是执行了下一句进入休眠后等到有数据才进入中断的?
2.为什么中断服务程序对应的中断向量是发送数据的?不应该是接收数据的吗
#include <msp430.h>
unsigned int RxByteCtr;
unsigned int RxWord;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= BIT0; // P1.0 output
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x4e; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0RXIE; // Enable RX interrupt
TACTL = TASSEL_2 + MC_2; // SMCLK, contmode
while (1)
{
RxByteCtr = 2; // Load RX byte counter
UCB0CTL1 |= UCTXSTT; // I2C start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts
// Remain in LPM0 until all data
// is RX'd
if (RxWord < 0x1d00) // >28C?
P1OUT &= ~0x01; // No, P1.0 = 0
else
P1OUT |= 0x01; // Yes, P1.0 = 1
__disable_interrupt();
TACCTL0 |= CCIE; // TACCR0 interrupt enabled
__bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts
// Remain in LPM0 until TACCR0
// interrupt occurs
TACCTL0 &= ~CCIE; // TACCR0 interrupt disabled
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TA0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)
#else
#error Compiler not supported!
#endif
{
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
// The USCIAB0TX_ISR is structured such that it can be used to receive any
// 2+ number of bytes by pre-loading RxByteCtr with the byte count.
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
#else
#error Compiler not supported!
#endif
{
RxByteCtr–; // Decrement RX byte counter
if (RxByteCtr)
{
RxWord = (unsigned int)UCB0RXBUF << 8; // Get received byte
if (RxByteCtr == 1) // Only one byte left?
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
}
else
{
RxWord |= UCB0RXBUF; // Get final received byte,
// Combine MSB and LSB
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
mike2:
这个是TI 的IIC第一个例子程序,看不懂,能解释一下吗?
mike2:
回复 mike2:
求先知们解答一下
Maka Luo:
mike2
1. UCB0CTL1 |= UCTXSTT; // I2C start condition这句执行开始条件就马上进入IIC中断吗?还是执行了下一句进入休眠后等到有数据才进入中断的?
这条只是启动I2C,进入中断取决于I2C中断标志的产生。2.为什么中断服务程序对应的中断向量是发送数据的?不应该是接收数据的吗
发送数据,你只需要将发送数据放入UCB0TXBUF中,硬件模块自动会发送数据出去,如果使能发送完成中断,在数据发送完成后会有中断产生。
代码例程中中断时接收数据的,所以去读取UCB0RXBUF 的数值。#include <msp430.h>unsigned int RxByteCtr;unsigned int RxWord;int main(void){ WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= BIT0; // P1.0 output P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x4e; // Set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt TACTL = TASSEL_2 + MC_2; // SMCLK, contmode while (1) { RxByteCtr = 2; // Load RX byte counter UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until all data // is RX'd if (RxWord < 0x1d00) // >28C? P1OUT &= ~0x01; // No, P1.0 = 0 else P1OUT |= 0x01; // Yes, P1.0 = 1 __disable_interrupt(); TACCTL0 |= CCIE; // TACCR0 interrupt enabled __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until TACCR0 // interrupt occurs TACCTL0 &= ~CCIE; // TACCR0 interrupt disabled }}#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)#pragma vector = TIMER0_A0_VECTOR__interrupt void TA0_ISR(void)#elif defined(__GNUC__)void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)#else#error Compiler not supported!#endif{ __bic_SR_register_on_exit(CPUOFF); // Exit LPM0}// The USCIAB0TX_ISR is structured such that it can be used to receive any// 2+ number of bytes by pre-loading RxByteCtr with the byte count.#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)#pragma vector = USCIAB0TX_VECTOR__interrupt void USCIAB0TX_ISR(void)#elif defined(__GNUC__)void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)#else#error Compiler not supported!#endif{ RxByteCtr–; // Decrement RX byte counter if (RxByteCtr) { RxWord = (unsigned int)UCB0RXBUF << 8; // Get received byte if (RxByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { RxWord |= UCB0RXBUF; // Get final received byte, // Combine MSB and LSB __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 }}
mike2:
回复 Maka Luo:
Maka
mike2
1. UCB0CTL1 |= UCTXSTT; // I2C start condition这句执行开始条件就马上进入IIC中断吗?还是执行了下一句进入休眠后等到有数据才进入中断的?
这条只是启动I2C,进入中断取决于I2C中断标志的产生。
非常感谢回复,本例中如果一切硬件正常,启动i2c开始后,立刻会进入后面的iic中断处理程序吗?这样在iic中断处理完成后才运行下面一句进入低功耗?还是先进入低功耗,后来定时器中断中打开全局中断允许,待传感器返回应答才进入iic中断处理程序?
__bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts2.为什么中断服务程序对应的中断向量是发送数据的?不应该是接收数据的吗
发送数据,你只需要将发送数据放入UCB0TXBUF中,硬件模块自动会发送数据出去,如果使能发送完成中断,在数据发送完成后会有中断产生。
代码例程中中断时接收数据的,所以去读取UCB0RXBUF 的数值。
我意思是本例是单片机读取数据,为什么中断程序是interrupt(USCIAB0TX_VECTOR),这个是发送的中断吧?请原谅初学者的简单问题
#include <msp430.h>unsigned int RxByteCtr;unsigned int RxWord;int main(void){ WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR |= BIT0; // P1.0 output P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x4e; // Set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt TACTL = TASSEL_2 + MC_2; // SMCLK, contmode while (1) { RxByteCtr = 2; // Load RX byte counter UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until all data // is RX'd if (RxWord < 0x1d00) // >28C? P1OUT &= ~0x01; // No, P1.0 = 0 else P1OUT |= 0x01; // Yes, P1.0 = 1 __disable_interrupt(); TACCTL0 |= CCIE; // TACCR0 interrupt enabled __bis_SR_register(CPUOFF + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until TACCR0 // interrupt occurs TACCTL0 &= ~CCIE; // TACCR0 interrupt disabled }}#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)#pragma vector = TIMER0_A0_VECTOR__interrupt void TA0_ISR(void)#elif defined(__GNUC__)void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TA0_ISR (void)#else#error Compiler not supported!#endif{ __bic_SR_register_on_exit(CPUOFF); // Exit LPM0}// The USCIAB0TX_ISR is structured such that it can be used to receive any// 2+ number of bytes by pre-loading RxByteCtr with the byte count.#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)#pragma vector = USCIAB0TX_VECTOR__interrupt void USCIAB0TX_ISR(void)#elif defined(__GNUC__)void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)#else#error Compiler not supported!#endif{ RxByteCtr–; // Decrement RX byte counter if (RxByteCtr) { RxWord = (unsigned int)UCB0RXBUF << 8; // Get received byte if (RxByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { RxWord |= UCB0RXBUF; // Get final received byte, // Combine MSB and LSB __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 }}