Hi,all
我在用MSP430F5418A和温度传感器TMP101通信过程中,遇到以下这个问题:
我向TMP101发送数据时,总是发送到第五个数据的时候就进不了中断了,前四个数据是正常发送的,请问这是怎么回事?
下面是我的源程序,请指教:
#include "msp430x54xA.h"
unsigned char *PTxData; // Pointer to TX data
unsigned char TXByteCtr;
#define VCC3P3_PwrOn (P8OUT |= BIT5)
#define VCC3P3_PwrGood (P8IN & BIT6)
#define LED_ON (P3OUT &= ~(BIT6))
#define LED_OFF (P3OUT |= BIT6)
const unsigned char TxData[] = // Table of data to transmit
{
0x01,
0x0b,
0x02,
0x01,
0x04,
0x03,
0x32,
0x00,
};
void test_mcu_port_init(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
test_mcu_port_init();
VCC3P3_PwrOn;
while(!(VCC3P3_PwrGood))
{
;
}
LED_ON;
P3SEL |= 0x80; // Assign I2C pins to USCI_B0
P5SEL |= 0x10;
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = 0x4a; // Slave Address is 048h
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE; // Enable TX interrupt
// while (1)
// {
__delay_cycles(50); // Delay required between transaction
PTxData = (unsigned char *)TxData; // TX array start address
// Place breakpoint here to see each
// transmit operation.
TXByteCtr = sizeof TxData; // Load TX byte counter
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(GIE); // Enter LPM0, enable interrupts
__no_operation(); // Remain in LPM0 until all data
// is TX'd
while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
// }
}
void test_mcu_port_init(void)
{
/*将所有端口恢复到初始值*/
P1OUT &= 0x00;
P2OUT &= 0x00;
P3OUT &= 0x00;
/*LED为关闭状态*/
LED_OFF;
P4OUT &= 0x00;
/*I/O扩展芯片中断管脚拉高*/
P4OUT |= BIT6;
P5OUT &= 0x00;
P6OUT &= 0x00;
P7OUT &= 0x00;
/*关闭1.8V的MOSFET*/
P7OUT |= BIT4;
P8OUT |= 0x00;
/*定义所有端口方向和功能选择*/
P1SEL |= 0x00;
P1DIR |= 0x5b;
P2SEL |= 0x00;
P2DIR |= 0xe7;
P3SEL |= 0xbf;
P3DIR |= 0x40;
P4SEL |= 0x59;
P4DIR |= 0xae;
P5SEL |= 0xd0;
P5DIR |= 0x25;
P6SEL |= 0x03;
P6DIR |= 0x78;
P7SEL |= 0x0b;
P7DIR |= 0xb4;
P8SEL |= 0x00;
P8DIR |= 0x3f;
}
//——————————————————————————
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//——————————————————————————
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
switch(__even_in_range(UCB1IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG
if (TXByteCtr) // Check TX byte counter
{
UCB1TXBUF = *PTxData++; // Load TX buffer
TXByteCtr–; // Decrement TX byte counter
}
else
{
UCB1CTL1 |= UCTXSTP; // I2C stop condition
UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
}
default: break;
}
}
程序中,我想将数组TxData中的数据发送到TMP101,但是出现了上面所说的那个情况。请帮忙看一下到底是哪里出错了?
Thx
Nick
Young Hu:
Nick,
您好!
”总是发送到第五个数据的时候就进不了中断了,前四个数据是正常发送的“
与TMP101的通信必须得符合TMP101的时序要求。最好是用示波器抓一下波形看一下,这样最清楚了!
在您的另一个帖子中已经回复了您的问题。
谢谢!
Nick wang:
回复 Young Hu:
谢谢您的及时回复。
我还有个问题想请教:
每次单片机上电之后,初始化I2C时,只要执行完UCB1CTL1 &= ~UCSWRST; 这条语句,寄存器UCBSTAT中的
UCBBUSY位就会置1,之后程序就不能正常收发数据了。UCBBUSY位只有在产生了UCTXSTT之后才会置1,但是实际
程序上没有到UCTXSTT这条语句。按说上电之后,SDA应该是高电平呀,可是为什么UCBBUSY位还会置1呢?
谢谢
Nick
Peter_Zheng:
回复 Nick wang:
The bus busy bit, UCBBUSY, is set after a START and cleared after a STOP. 那么作为master从上电开始UCBBUSY置置位并不影响整个i2c读写程序。
Peter_Zheng:
回复 Nick wang:
The bus busy bit, UCBBUSY, is set after a START and cleared after a STOP. 那么作为master从上电开始UCBBUSY置置位并不影响整个i2c读写程序。
Nick wang:
回复 Peter_Zheng:
谢谢您的回复,但是我是在执行完UCB1CTL1 &= ~UCSWRST; 这条语句UCBBUSY位就置1了,还没有START。UCBBUSY
位置1会产生影响,进不了中断,不能正常收发数据。
Thx
Nick
Peter_Zheng:
回复 Nick wang:
如你所说执行到第五个数据出现错误,前四个都是正确的,但这与UCBBUSY上电开始置位是没有关系的。具体检查一下程序,如鸵鸟蝈蝈所说,用示波器观测一下。
kun zheng:
回复 Nick wang:
每次单片机上电之后,初始化I2C时,只要执行完UCB1CTL1 &= ~UCSWRST; 这条语句,寄存器UCBSTAT中的
UCBBUSY位就会置1,之后程序就不能正常收发数据了。
出现这个问题应该是从机将SCL拉高,也就是从机在等待主机发送stop位,上次运行时主机没有给从机发送STOP位。断电后重新上电能够正常就能验证是上述问题,解决办法,将代码完善,或者将I2C口配成普通I/O口,强行拉低