TI中文支持网
TI专业的中文技术问题咨询交流网站

MSP430f169I2C通信,I2CBUSY始终显示1的问题

尝试使用MSP430f169与AD5933进行通信,但程序始终卡死在发送字节部分,判断是否空闲的语句

观察发现I2CBUSY位一直为1

请问这是什么问题?真诚求教。后附主程序和I2C程序

主程序

/********************

void main(void)
{
WDT_Init();
Clock_Init(); //系统时钟设置
I2c_Init();

_EINT(); //打开中断
I2CWriteInit();
/*—–启动频率扫描————–

ad5933_write ( 0x82, 0x0e);delay_ms(5);
//频率增量:0
// Transmit to frequency increment register // program 1Khz frequency increment assuming internal osc of 16.776Khz
ad5933_write ( 0x87, 0x02);delay_ms(5);
ad5933_write ( 0x86, 0x7D);delay_ms(5); ad5933_write ( 0x85, 0x00);delay_ms(5);
//增量数:(随意设定)
// Transmit to NUMBER OF INCREMENTS register // program 10 frequency increments
ad5933_write ( 0x89, 0x0A);delay_ms(5);
ad5933_write ( 0x88, 0x00);delay_ms(5);
// Transmit to settling time cycles register // program 15 output cycles at each frequency before a adc conversion
ad5933_write ( 0x8B, 0x0F);delay_ms(5);
ad5933_write ( 0x8A, 0x00);delay_ms(5);

/*—————-读取数据———————-*/ while(1)
{
ZT = ad5933_read(0x8f);
while((ZT&0x02)!=0x02)
{
ZT = ad5933_read(0x8f);
delay_ms(5);
ad5933_write ( 0x80, 0x40);
delay_ms(5);
}
P = ad5933_read(0x80);//控制寄存器
P1 = ad5933_read(0x84);//实值低四位
R[0] = ad5933_read(0x94);//实值低四位
R[1] = ad5933_read(0x95);//实值高四位
I[0] = ad5933_read(0x96);//虚值低四位
I[1] = ad5933_read(0x97);//虚值高四位

I2C函数

#include <msp430x16x.h>

#define SDA_1 P3OUT |= BIT1 //串行数据线,SDA = 1
#define SDA_0 P3OUT &=~ BIT1 //SDA = 0
#define SCL_1 P3OUT |= BIT3 //串行时钟线,SCL = 1
#define SCL_0 P3OUT &=~ BIT3 //SCL = 0

#define SDADIR_IN P3DIR &=~ BIT1 //SDA,I/O口为输入
#define SDADIR_OUT P3DIR |= BIT1 //I/0口为输出
#define SDA_IN ((P3IN >> 1) & 0x01) //Read SDA

#define SCLDIR_IN P3DIR &=~ BIT3 //SCL,I/O口为输入
#define SCLDIR_OUT P3DIR |= BIT3 //I/0口为输出
#define SCL_IN ((P3IN >> 3) & 0x01) //Read SCL

#define CPU_F ((double)8000000)#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))

/*当BRCLK=CPU_F时用下面的公式可以计算,否则要根据设置加入分频系数*/
#define baud 9600 //设置波特率的大小
#define baud_setting (uint)((ulong)CPU_F/((ulong)baud)) //波特率计算公式
#define baud_h (uchar)(baud_setting>>8) //提取高位
#define baud_l (uchar)(baud_setting) //低位

#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

#define SLAVEADDR 0x0D;

int tx_count;
int rx_count;
unsigned int i;
unsigned char I2CBuffer[3];
unsigned int n=3;

/*——————————————————–
—I2C初始化函数
———————————————————-*/
void I2c_Init(void)
{
//将P3.1和P3.3设置为I2C管脚
//P3SEL |= 0X0A; //设置P3.1和P3.3管脚的方向
P3DIR |= 0x0A;
SDA_1;
SCL_1;
P3SEL |= 0X0A; for(i= 0; i <9 ; i++) { P3OUT |= BIT3; __delay_cycles(8000); P3OUT &= ~BIT3; __delay_cycles(8000); } //选择为I2C模式
U0CTL |= I2C + SYNC; //禁止I2C模块
U0CTL &= ~I2CEN; //设置I2C为7位地址模式,不使用DMA,
//字节模式,时钟源为SMCLK,
//设置成传输模式
I2CTCTL = I2CTRX + I2CSSEL_2; //定义从器件地址
I2CSA = SLAVEADDR; //设置本身的地址
I2COA = 0x01A5; //I2C时钟为SMCLK / 160
I2CPSC = 159; //SCL 高电平为:5 *I2C 时钟
I2CSCLH = 0x03; //SCL 低电平为:5 *I2C 时钟
I2CSCLL = 0x03; //I2C 模块有效
U0CTL |= I2CEN;
tx_count = 0;
rx_count = 0;

}

//—————— MSP430 I2C 写数据初始化 ————-
/*——————————————————–
–功能描述:对于从器件的写操作是置成主模式并置位中断使能.
———————————————————-*/
void I2CWriteInit(void){
//主(Master)模式
U0CTL |= MST; //传输模式,R/W 为:0
I2CTCTL |= I2CTRX; //清除中断标志
I2CIFG &= ~TXRDYIFG;
//发送中断使能
I2CIE = TXRDYIE;
}
//—————— MSP430 I2C 读数据初始化 ————-
/*——————————————————–
–功能描述:对于从器件的写操作是置成主模式并置位中断使能.
———————————————————-*/

void I2CReadInit(void)
{
//接收模式,R/W 为:1
I2CTCTL &= ~I2CTRX;
//接收中断使能
I2CIE = RXRDYIE;
}

//—————– AD5933 写入数据 ——————–
/*——————————————————–
–功能描述:向从器件中nAddr地址,写入nVal数据
———————————————————-*/
void ad5933_write(unsigned char nAddr, unsigned char nVal)
{
//等待I2C模块完成所有操作 while (I2CDCTL&I2CBUSY) ; //设置地址数据
I2CBuffer[1] = nAddr; //设置数据
I2CBuffer[0] = nVal;
//设置缓冲区指针
tx_count = 1; //写数据初始化
I2CWriteInit(); //设置为主模式
//发送数据的长度
//一共2个字节,包括1个地址字节,1个数据字节
I2CNDAT = 2; //开始和停止条件产生
//开始I2C通信
I2CTCTL |= I2CSTT+I2CSTP; //delay_ms(5);
return;
}

//—————– AD5933 读出数据 ——————–
/*——————————————————–
–功能描述:从器件中nAddr地址读数据
———————————————————-*/

unsigned char ad5933_read(unsigned char nAddr)
{
//等待I2C模块完成所有操作 while (I2CDCTL&I2CBUSY) ; //指针命令代码
I2CBuffer[1] = 0xb0; //设置数据(指针指向寄存器地址)
I2CBuffer[0] = nAddr;
//设置缓冲区指针
tx_count = 1; //写数据初始化
I2CWriteInit(); //设置为主模式
//发送数据的长度
//一共2个字节,包括1个指针命令代码,1个缓冲区指针
I2CNDAT = 2; //开始条件产生
//开始I2C通信
I2CTCTL |= I2CSTT; //I2CNDAT = 1;
//清除中断标志
//I2CIFG &= ~ARDYIFG;
//开始接收,产生重新起始和停止条件
delay_ms(5);
while ((~I2CIFG)&ARDYIFG); //读操作初始化
I2CReadInit();
//接收一个字节的数据
I2CNDAT = 1;
//清除中断标志
//I2CIFG &= ~ARDYIFG;
//开始接收,产生重新起始和停止条件
I2CTCTL |= I2CSTT + I2CSTP; //等待传输完成
while ((~I2CIFG)&ARDYIFG); //返回数据
//I2CBuffer[0]=I2CDRB;
delay_ms(5);
return I2CBuffer[0];
}

#pragma vector=USART0TX_VECTOR //IIC中断向量,包括八个中断标志位
__interrupt void ISR_I2C(void)
{
switch (I2CIV) //中断向量寄存器,决定了IIC中具体哪个中断被出发
{ case I2CIV_AL:
{
//仲裁中断
break;
}
case I2CIV_NACK: //无应答信号中断
{
//NACK中断
P3OUT |=BIT2;
delay_ms(10);
P3OUT &=~BIT2;
break;
}
case I2CIV_OA: {
//自己地址中断
break;
}
case I2CIV_ARDY: {
//访问准备好中断
break;
}
case I2CIV_RXRDY: {
//接收准备好中断
I2CBuffer[0]=I2CDRB; break;
}
case I2CIV_TXRDY: {
//发送准备好中断
I2CDRB = I2CBuffer[tx_count];
tx_count = tx_count – 1;
if (tx_count < 0)
{
//禁止发送中断
I2CIE &= ~TXRDYIE; }
break;
} case I2CIV_GC: {
//一般调用中断
break;
}
case I2CIV_STT:
{

//起始条件中断
break;
}
}
}

黄色部分为程序卡死的部分

灰小子:

楼主你好,你观察过通讯时序了吗?

赞(0)
未经允许不得转载:TI中文支持网 » MSP430f169I2C通信,I2CBUSY始终显示1的问题
分享到: 更多 (0)