日前想用MSP430F2132做个工程项目,当项目进入到调试AT24C02的时候,发现2132模拟IIC读定不了24C02(程序是从MSP430F2418只移植过来的,在F2418和F149都能正常运行),于是更换成MSP430F1232,却又发现有些24C02能读写,有些又不能读写,经反复上网查资料,看到有贴子提到2132引脚结构的问题,造成模拟IIC时会出现中间电平,影响读写,可以考虑用硬件IIC。所以我又把方案改回2132,想使用其硬件IIC,但现在调试却怎么也调不通,操作IIC的时候CLK引脚一直处于低电平,反复对照2132用户手册和源程序,始终没看到哪里有设置不对的地方,所以在此求助,贴出源代码,希望大师指点
/****************延时****************************/
#define CPU_F ((double)5500000)//根据实际工作频率做相应的调整
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
//时钟设置
void Clock_Init(uint8 System_Clock)
{
BCSCTL1 = RSEL3 + RSEL1 + RSEL0; //选择DCO并调节振荡频段
DCOCTL = DCO1 + DCO0; //选择DCO的频率
}
//IIC初始化
void IIC_Port_Init(void)
{
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_3 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 54; // fSCL = SMCLK/55 = ~100kHz
UCB0BR1 = 0;
P3SEL |= BIT1 + BIT2; // Assign I2C pins to USCI_B0
UCB0I2CSA = SlaveAddress;
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
}
//写模式
void I2C_WriteMode(void)
{
UCB0CTL1 |= UCTR;
IFG2 &=~ UCB0TXIFG;
IE2 &=~ UCB0RXIE; // 关闭接收中断,开启发送中断
IE2 |= UCB0TXIE;
}
//读模式
void I2C_ReadMode(void)
{
UCB0CTL1 &=~ UCTR;
IFG2 &=~ UCB0RXIFG;
IE2 &=~ UCB0TXIE;
IE2 |= UCB0RXIE; // 关闭发送中断,开启接收中断
}
//发送一字节
void I2C_Txbyte(uint8 Reg_addr,uint8 Reg_data)
{
while(UCB0STAT & UCBBUSY);
I2C_WriteMode();
TxData[1]=Reg_addr;
TxData[0]=Reg_data;
TXByteCtr=2; // Load TX byte counter
UCB0CTL1 |= UCTXSTT; // I2C TX, start condition
//while (UCB0CTL1 & UCTXSTT);
//__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
while (UCB0CTL1 & UCTXSTP);
}
//读一字节
void I2C_Rxbyte(uint8 Reg_addr)
{
while(UCB0STAT & UCBBUSY);
I2C_WriteMode();
TxData[0]=Reg_addr;
TXByteCtr=1; // Load TX byte counter
UCB0CTL1 |= UCTXSTT; // I2C TX, start condition
//__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
while (UCB0CTL1 & UCTXSTP);
I2C_ReadMode();
RXByteCtr=1;
UCB0CTL1 |= UCTXSTT;
//__bis_SR_register(CPUOFF + GIE);
while (IFG2 & UCB0RXIFG);
while (UCB0CTL1 & UCTXSTP);
}
//中断处理
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if(IFG2 & UCB0TXIFG)
{
if(TXByteCtr) // Check TX byte counter
{
TXByteCtr--;
UCB0TXBUF = TxData[TXByteCtr]; // Load TX buffer // Decrement TX byte counter
}
else
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
//IE2 &= ~UCB0TXIE; //Disable TX interrupt
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
if(IFG2 & UCB0RXIFG)
{
if(RXByteCtr)
{
RXByteCtr--;
if(RXByteCtr == 0)
{
UCB0CTL1 |= UCTXSTP + UCTXNACK; //必须在接受最后一个数据之前发送停止和NACK
}
RxBuf[RXByteCtr] = UCB0RXBUF;
//UCB0CTL1 &= ~UCTXNACK; //发送完一个NACK后UCTXNACK自动复位
}
else
{
//UCB0CTL1 |= UCTXSTP;
IFG2&=~UCB0RXIFG;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}