This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5438A,I2C通信问题

最近写了一个430的I2C通信程序,单片机下挂了两个传感器,但读传感器的时候感觉值一直不对,然后我就去读我配置传感器的数据去验证I2C通信是否正常:

( MEMS_ReadReg(LSM303ACC,CTRL_REG1_A, &value)),单步运行的时候我发现进入中断读值的时候,读完一个字节,他还在中断里面:
#pragma vector = USCI_B3_VECTOR
__interrupt void USCI_B3_ISR(void)
 if(UCB3IFG & UCRXIFG)                      // 接收中断 
  { 
    if(strIIC.DATALEN > 1)
    {
       *strIIC.pBUF++ = UCB3RXBUF;
    }
    else if(1 == strIIC.DATALEN)
    {
      
       *strIIC.pBUF++ = UCB3RXBUF;
       UCB3CTL1 |= UCTXSTP + UCTXNACK;        // 发送停止位和NACK位
   
    }
    --strIIC.DATALEN;                         // 接收数据长度自减          
  } 
}
在里面又执行了两遍,但并没有往 *strIIC.pBUF里写值,但我继续读下一个配置的时候 MEMS_ReadReg(LSM303ACC,CTRL_REG4_A, &value),进入中断读值的时候,读完一个字节,他还在中断里面: 但这次他却往 *strIIC.pBUF里写值了,不知道为什么?下面是部分代码:
typedef unsigned char u8;
#define LSM303ACC 0
#define LSM303MAG 1
struct str_IIC          //I2C数据结构
{
u8  R_W;                 //I2C收发模式
u8  SLA;       //从设备的器件地址
u8 ADDR;       //从设备的寄存器数据地址
u8 *pBUF;       //数据缓冲区指针
u8 DATALEN;      //数据长度       
}strIIC;
/**********************************************************
函数名称:I2C读写多字节程序
函数出口:无
函数入口:R_W  --0写操作。1读操作
sla  --器件地址
addr --器件子地址
*ptr --读写数据缓冲区
len  -- 读写数据长度
***********************************************************/
u8 IIC_RW(u8 R_W,u8 sla,u8 addr,u8 *ptr,u8 len)
{
    u8 i;
    strIIC.R_W      = R_W;
  strIIC.SLA      = sla;
    strIIC.ADDR     = addr;
    strIIC.pBUF     = ptr;
    strIIC.DATALEN  = len;
    UCB3I2CSA = strIIC.SLA;                   //从器件地址
    if(0 == strIIC.R_W)                           //写操作
    {
        while(UCB3CTL1 & UCTXSTP);                //总线是否空闲
        UCB3CTL1  |= UCTXSTT + UCTR;              //启动I2C,发送
        
        UCB3TXBUF  = strIIC.ADDR;       //发送器件子地址 
           while(!(UCB3IFG & UCTXIFG))          //判断是否发送完毕
           {
              if((UCB3IFG & UCNACKIFG) == 1)      //从设备无应答则返回
                  return 1;
           } 
       
        for(i=0; i<strIIC.DATALEN; i++)            //发送数据
        {
           UCB3TXBUF = *strIIC.pBUF++;
           while((UCB3IFG & UCTXIFG) == 0)
           {
               if((UCB3IFG & UCNACKIFG) == 1)     //从设备无应答则返回
                  return 1;
           }
        }
        UCB3CTL1 |= UCTXSTP;                       //发送停止位
        while(UCB3CTL1 & UCTXSTP);                 //总线是否空闲
    }
    if (1 == strIIC.R_W)                       //读操作
    {
        while(UCB3CTL1 & UCTXSTP);                 //总线是否空闲
        UCB3CTL1  |= UCTXSTT + UCTR;               //启动I2C,发送 
        
        UCB3TXBUF  = strIIC.ADDR;      //发送器件子地址
          while((UCB3IFG & UCTXIFG) == 0)
             {
                  if((UCB3IFG & UCNACKIFG) == 1)  //从设备无应答则返回
                     return 1;
             }
       
        UCB3CTL1  &= ~UCTR;                        //确定为接收 
        //while (UCB3CTL1 & UCTXSTP);               //判断总线是否被释放 
        UCB3CTL1  |= UCTXSTT;                      //重新发送起始位 
        while((UCB3CTL1 & UCTXSTT) == 1);         //判断起始位是否发送成功 
         
    }
   delay_us(300);延时一段时间
    return 0;
}
/*********************************************************
函数名称:I2C_Init()
函数功能:I2C初始化
入口参数:无
出口参数:无
备注:
**********************************************************/
void I2C_Init(void)
{
  P10SEL |= 0x06;   //P10.2(SCK),P10.1(SDA)                  
UCB3CTL1 |= UCSWRST;                      //Ready for configurating I2C register  
UCB3CTL0 |= UCMST+UCMODE_3 +UCSYNC;    //I2C、 主机、同步模式
//================= Starting Of I2C FUNCTION CONFIGURATION========================//
UCB3CTL1 = UCSSEL_2 + UCSWRST;            //时钟源MCLK
UCB3BR0  =120;                          //100KHz,12MHz
UCB3BR1  = 0;
UCB3CTL1 &= ~UCSWRST;
  UCB3IE |= UCRXIE;                  //使能接收中断
//================= End Of I2C FUNCTION CONFIGURATION========================// 
}
/*********************************************************
函数名称:USCI_B3_ISR
函数功能:I2C接收中断
入口参数:无
出口参数:无
备注:
**********************************************************
#pragma vector = USCI_B3_VECTOR
__interrupt void USCI_B3_ISR(void)
 if(UCB3IFG & UCRXIFG)                      // 接收中断 
  { 
   //Sendbyte(UCB3RXBUF);
    if(strIIC.DATALEN > 1)
    {
       *strIIC.pBUF++ = UCB3RXBUF;
    }
    else if(1 == strIIC.DATALEN)
    {
      
       *strIIC.pBUF++ = UCB3RXBUF;
       UCB3CTL1 |= UCTXSTP + UCTXNACK;        // 发送停止位和NACK位
   
    }
    --strIIC.DATALEN;                         // 接收数据长度自减          
  } 
}
/*
函数:MEMS_WriteReg()
功能:向传感器的某个内部寄存器写入数据
参数:
ICID:传感器器件ID
dat:要写入的数据
RegAddr:器件内部寄存器地址
返回:
0:正常
1:访问传感器时出现异常
*/
unsigned char MEMS_WriteReg(unsigned char ICID,unsigned char RegAddr, unsigned char dat)
{
unsigned char  b;
switch(ICID)
{
case LSM303ACC:
b=   IIC_RW(0,LSM303ACC_I2C_ADDR,RegAddr,&dat,1);
break;
case LSM303MAG:
b=  IIC_RW(0,LSM303MAG_I2C_ADDR,RegAddr,&dat,1);
break;
}
return b;
}
/*
函数:MEMS_ReadReg()
功能:向传感器的某个内部寄存器读出数据
参数:
ICID:传感器器件ID
dat:要写入的数据
RegAddr:器件内部寄存器地址
返回:
0:正常
1:访问传感器时出现异常
*/
unsigned char  MEMS_ReadReg(unsigned char ICID,unsigned char RegAddr, unsigned char *dat)
{
unsigned char b;
switch(ICID)
{
case LSM303ACC:
b=   IIC_RW(1,LSM303ACC_I2C_ADDR,RegAddr,dat,1);
break;
case LSM303MAG:
b=   IIC_RW(1,HMC5883L_I2C_ADDR,RegAddr,dat,1);
break;
}
return b;
}
void LSM303AccCFG()
{
while( MEMS_WriteReg(LSM303ACC,CTRL_REG1_A, 0X67));
while( MEMS_WriteReg(LSM303ACC,CTRL_REG4_A, 0X18));
}
 MEMS_ReadReg(LSM303ACC,CTRL_REG1_A, &value)
  • IIC不建议你用中断,一般的项目中,中断还是有几个的,所以使用端口模拟吧,我一开始就用模拟的,后来硬件调试成功后,也用模拟,程序移植方便。你这程序这么多,太费解了。

  • 你好,你的问题解决了嘛?我也在寻找可靠的F5438A I2C代码,恳请指教!谢谢

  • 参考例子中相关内容

    msp430x54xA_uscib0_i2c_04.c USCI_B0 I2C Master RX single bytes from MSP430 Master
    msp430x54xA_uscib0_i2c_05.c USCI_B0 I2C Slave TX single bytes to MSP430 Slave
    msp430x54xA_uscib0_i2c_06.c USCI_B0 I2C Master TX single bytes to MSP430 Slave
    msp430x54xA_uscib0_i2c_07.c USCI_B0 I2C Slave RX single bytes from MSP430 Master
    msp430x54xA_uscib0_i2c_08.c USCI_B0 I2C Master TX multiple bytes to MSP430 Slave
    msp430x54xA_uscib0_i2c_09.c USCI_B0 I2C Slave RX multiple bytes from MSP430 Master
    msp430x54xA_uscib0_i2c_10.c USCI_B0 I2C Master RX multiple bytes from MSP430 Slave
    msp430x54xA_uscib0_i2c_11.c USCI_B0 I2C Slave TX multiple bytes to MSP430 Master
    msp430x54xA_uscib0_i2c_12.c USCI B0 I2C Master TX/RX multiple bytes to/from MSP430 Slave Repeated Start
    msp430x54xA_uscib0_i2c_13.c USCI B0 I2C Slave RX/TX multiple bytes from/to MSP430 Master Repeated Start

    slac375j.zip