msp430与LSM303DLH的IIC通信收到错误的OXff

2019-07-15 15:10发布

调了好几天了没结果,现在的问题是收到的全是错误的OXff,LSM303_RecvACK()没有应答,地址左移、右移一位都试过,增加延时也尝试过无果,实在是没办法来寻求大神帮助
#include "msp430x22x4.h"
#define uchar unsigned char
#define uint unsigned int
int Byte_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);
uchar Random_Read(uchar SlaveAddress,uchar REG_Address);
#define         LSM303A_SlaveAddress   0x30        //定义器件在IIC总线中的从地址,(加速度)根据ALT  ADDRESS地址引脚不同修改 0x30(ADDRESS=0)                                 
#define         LSM303M_SlaveAddress   0x3C   //定义器件在IIC总线中的从地址,(磁场)根据ALT    ADDRESS地址引脚不同修改        
void delayms(uint x)
{
    uint a,b;
    for(a=x;a>0;a--)
      for(b=110;b>0;b--);
}
void main()
{
  WDTCTL = WDTPW + WDTHOLD;//关看门狗定时器
  uchar num1,num2;
  P3SEL &= ~(BIT0+BIT1);//P3.0  P3.1设置为普通IO口
  Byte_Write(LSM303A_SlaveAddress,0x20,0x27);
  delayms(10);
  //Byte_Write(LSM303M_SlaveAddress,0x02,0x00);
// delayms(10);
  num1=Random_Read(LSM303A_SlaveAddress,0x28);
  num2=Random_Read(LSM303A_SlaveAddress,0x29);
}
/************IIC初始化***************
分析:以P3.0控制SDA,P3.1控制SCL方式编写
连线:P3.0~SDA
      P3.1~SCL
************************************/
void delay()
{
  ;;
}
/*=============总线初始化==============*/
void init()
{
    P3DIR |= BIT0+BIT1;//P3.0  P3.1端口方向设置为输出
    P3OUT |= BIT1; //SCL=1,时钟线置高
    delay();
    P3OUT |= BIT0;//SDA=1,数据线置高
    delay();
}
/*==============启动信号===========*/
void start()  
{
    P3OUT |= BIT1;  //SCL=1
    P3OUT |= BIT0;  //SDA=1
    delay();//延时时间要大于4.7us
    P3OUT &= ~BIT0;  //SDA=0
    delay();//延时时间应大于4us
    P3OUT &= ~BIT1;  //SCL=0
}
/*============终止信号==========*/
void stop()  
{
    P3OUT |= BIT1;  //SCL=1
    P3OUT &= ~BIT0; //SDA=0
    delay();//延时时间应大于4us
    P3OUT |= BIT0;  //SDA=1
    delay();//延时时间应大于4.7us
}
/*============应答信号=============*/
void Ask()
{
    P3OUT &= ~BIT0; //SDA=0
    delay();
    P3OUT |= BIT1; //SCL=1
    delay();//延时时间应大于4us
    P3OUT &= ~BIT1; //SCL=0
    delay();
}
/*=============非应答信号============*/
void NoAsk()
{
    P3OUT |= BIT0; //SDA=1
    delay();
    P3OUT |= BIT1; //SCL=1
    delay();//应大于4us
    P3OUT &= ~BIT1; //SCL=0
    delay();
}
/*=============检测是否有应答信号============*/
int LSM303_RecvACK(){   
    int nTemp=1;  
    _NOP();
    _NOP();
    P3OUT &=~ BIT1;    //时钟置低;
    delay();
    P3OUT |= BIT0;    //数据置高
    delay();
    P3DIR &= ~BIT0;//SDA端口方向改为输入,因为此后要读入数据
    P3OUT |= BIT1;  //时钟置高
    delay();
    nTemp = (int)(P3IN&BIT0);        //获得SDA数据
    P3OUT&= ~BIT1;    //时钟置低;
    return (nTemp);
}
/*==========写一个字节=================*/
void write_byte(uchar Data)
{
    uchar i;//i用以计算发送的位数
    for(i=0;i<8;i++)
    {
      P3OUT &= ~BIT1; //SCL=0,SCL为低时,允许数据变化
      delay();
      if(Data&0x80)
        P3OUT|= BIT0;//送1位数据
      else
        P3OUT &= ~BIT0;
      Data<<=1;
      delay();
      P3OUT |= BIT1; //SCL=1,SCL为1时,要求数据稳定,将数据写入内存
      delay();
    }
    P3OUT &= ~BIT1; //SCL=0
    delay();
    //P3OUT |= BIT0; //SDA=1,释放数据线
    //delay();
}
/*=========读取一个字节=========
在每次SCL由0变1时,读取一位,
读8位,一字节
==============================*/
uchar read_byte()
{
    uchar i,temp=0;
    P3OUT &= ~BIT1; //SCL=0
    delay();
    P3OUT |= BIT0; //SDA=1
    delay();
    P3DIR &= ~BIT0;//SDA端口方向改为输入,因为此后要读入数据
    for(i=0;i<8;i++)
    {
       P3OUT |= BIT1; //SCL=1
       delay();
       temp<<=1;
       if(P3IN&BIT0)
          temp|=0x01;//获取P2.0口读回的数
     //  P3OUT &= ~BIT1; //SCL=0
     //  delay();
    }
    P3OUT &= ~BIT1; //SCL=0
    delay();
   // P3DIR |= BIT0; //读完1Byte数据,SDA口方向设置为输出
    return temp;
}
/********写操作*********/
int Byte_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
{
    int ntemp;
    P3DIR |= BIT0+BIT1;//P3.0  P3.1端口方向设置为输出
    start();//启动IIC
    //ntemp = LSM303_RecvACK();
    //if(ntemp) return 0;
    write_byte(SlaveAddress);//写器件地址,实验板上器件高4位为1010,低3位接了地,最地位为R/W,现在是写,最低位也为0
    ntemp = LSM303_RecvACK();
    if(ntemp) return 0;
    Ask();
    write_byte(REG_Address);//写数据地址,即欲将该数据存放于何处,address在0~255取值
    Ask();
    write_byte(REG_data);
    Ask();
    stop();
}
/********读操作***********************
说明:随机读取,程序分析参见操作时序
*************************************/
uchar Random_Read(uchar SlaveAddress,uchar REG_Address)
{
    P3DIR |= BIT0+BIT1;//P3.0  P3.1端口方向设置为输出
    uchar Data;
    start();
    write_byte(SlaveAddress);//写器件地址最低位为0
    Ask();
    write_byte(REG_Address);//广播数据存放的地方
    Ask(); //得到应答后开始读数据
    start();
    write_byte(SlaveAddress+1);//器件地址最低位为read,为1,表明此时24C02将发送数据,MCU接收数据
    Ask();
    Data=read_byte();//读取数据赋给Data
    NoAsk();
    stop();
    return Data;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
珠海易胜
2019-07-16 07:42
你的delay();函数是空的,这样的延时时间够么?如果是空函数,会不会被编译器优化掉了?从而没有提供IIC时序足够的延时时间?没有接收到ACK就说明传感器没有正确识别你发送的命令,后面的数据是不会有变化的。

一周热门 更多>