程序如下,为IIC的master通讯程序:
#include
unsigned char TXData =0; // Pointer to TX data
unsigned char TXByteCtr;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
// Init SMCLK = MCLk = ACLK = 1MHz
CSCTL0_H = 0xA5;
CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting = 8MHz
CSCTL2 = SELA_3 + SELS_3 + SELM_3; // set ACLK = MCLK = DCO
CSCTL3 = DIVA_3 + DIVS_3 + DIVM_3; // set all dividers to 1MHz
// Configure Pins for I2C
P1SEL1 |= BIT6 + BIT7; // Pin init
UCB0CTLW0 |= UCSWRST; // put eUSCI_B in reset state
UCB0CTLW0 |= UCMODE_3 + UCMST + UCSSEL_2;// I2C master mode, SMCLk
UCB0BRW = 0x8; // baudrate = SMCLK / 8
UCB0I2CSA = 0x48; // address slave is 48hex
UCB0CTLW0 &=~ UCSWRST; //clear reset register
UCB0IE |= UCTXIE0 + UCNACKIE; //transmit and NACK interrupt enable
while(1)
{
__delay_cycles(1000); // Delay between transmissions
TXByteCtr = 1; // Load TX byte counter
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
// is TX'd
TXData++; // Increment data byte
}
}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
{
switch(__even_in_range(UCB0IV,0x1E))
{
case 0x00: break; // Vector 0: No interrupts break;
case 0x02: break;
case 0x04:
UCB0CTLW0 |= UCTXSTT; //resend start if NACK
break; // Vector 4: NACKIFG break;
case 0x18:
if (TXByteCtr) // Check TX byte counter
{
UCB0TXBUF = TXData; // Load TX buffer
TXByteCtr--; // Decrement TX byte counter
}
else
{
UCB0CTLW0 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF);// Exit LPM0
}
break; // Vector 26: TXIFG0 break;
default: break;
}
}
这个程序用IAR单步执行和连续执行的结果是不一样的,所以搞不清其语句的执行次序。有疑惑的地方为高亮标出部分,主程序中执行UCB0CTLW0 |= UCTR + UCTXSTT; 执行后UCB0模块开始发送开始信号和从机地址,这部分动作可以脱离CPU执行,同时CPU继续执行下面的__bis_SR_register(CPUOFF + GIE);语句关闭CPU并打开全局中断。按照用户手册说,当UCB0模块开始发送开始信号时就置位了UCTXIFG0,等全局中断打开后就会立刻进入中断case 0x18:执行 UCB0TXBUF = TXData; // Load TX buffer,现在的问题是这个语句是否需要CPU执行,但这时CPU还处于休眠状态如何执行?即使这句不需要CPU动作,那么后面的TXByteCtr--; 一定需要CPU执行,这时CPU不是进入休眠了吗?如何执行?
忘了说了,用IAR连续执行的仿真结果是正确的,好像是不需要唤醒CPU就可以执行 UCB0TXBUF = TXData; 和 TXByteCtr--; 两条语句,很迷惑为何是这种结果,请大侠指点。
MCU休眠之后,是可以通过中断唤醒的,执行完中断之后继续休眠。