wk316 发表于 2013-3-22 19:32:15

十万火急啊!关于LSM303DLH 地磁获取

后天老板就要数据了啊!现在只能获取到LSM303DLH的加速度信息,而地磁信息无法获取,跪求各位大侠指点啊
代码如下
#include<C8051F310.H>       
#include<math.h>    //Keil library
#include<stdio.h>   //Keil library       
#include<INTRINS.H>
#define   uchar unsigned char
#define   uint unsigned int       
#define WHO_AM_I 0x0F
#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
#define CTRL_REG5 0x24
#define REFERENCE 0x25
#define OUT_TEMP 0x26
#define STATUS_REG 0x27
#define OUT_X_L 0x28
#define OUT_X_H 0x29
#define OUT_Y_L 0x2A
#define OUT_Y_H 0x2B
#define OUT_Z_L 0x2C
#define OUT_Z_H 0x2D
#define FIFO_CTRL_REG 0x2E
#define FIFO_SRC_REG 0x2F
#define INT1_CFG 0x30
#define INT1_SRC 0x31
#define INT1_TSH_XH 0x32
#define INT1_TSH_XL 0x33
#define INT1_TSH_YH 0x34
#define INT1_TSH_YL 0x35
#define INT1_TSH_ZH 0x36
#define INT1_TSH_ZL 0x37
#define INT1_DURATION 0x38

#define        CRA_REG_M 0x00
#define        CRB_REG_M 0x01
#define       MR_REG_M 0x02
#define       OUTXH_M0X03
#define       OUTXL_M0x04
#define       OUTYH_M0x05
#define       OUTYL_M0x06
#define       OUTZH_M0x07
#define       OUTZL_M0x08
#defineSR_REG_MOx09

sbit          SCL = P0^0;      //IIC时钟引脚定义
sbit           SDA = P0^1;      //IIC数据引脚定义
sbit          TE = P2^0;

#define        LSM303A_SlaveAddress   0x30          //定义器件在IIC总线中的从地址,(加速度)根据ALTADDRESS地址引脚不同修改 0x30(ADDRESS=0)                                 
#define        LSM303M_SlaveAddress   0x3C   //定义器件在IIC总线中的从地址,(磁场)根据ALT    ADDRESS地址引脚不同修改
#define        SlaveAddress1   0xD2          //定义器件在IIC总线中的从地址,根据ALTADDRESS地址引脚不同修改

typedef unsigned charBYTE;
typedef unsigned short WORD;

BYTE BUF;                         //接收数据缓存区             
intdis_data;                     //变量

void delay(unsigned int k);
voidSingle_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //单个写入数据
uchar Single_Read(uchar SlaveAddress,uchar REG_Address);                   //单个读取内部寄存器数据
voidMultiple_Read1(uchar,uchar);                                          //连续的读取内部寄存器数据
//------------------------------------
void Delay5us();
//void Delay5ms();
void LSM303_Start();
void LSM303_Stop();
void LSM303_SendACK(bit ack);
bitLSM303_RecvACK();
void LSM303_SendByte(BYTE dat);
BYTE LSM303_RecvByte();
void LSM303_ReadPage();
void LSM303_WritePage();

//-----------------------------------
/*******************************/
void delay(unsigned int k)       
{                                               
unsigned int i,j;                               
for(i=0;i<k;i++)
{                       
for(j=0;j<245;j++)                       
{;}}                                               
}       
/**************************************
不同的工作环境,需要调整此函数,注意时钟过快时需要修改
当改用1T的MCU时,请调整此延时函数
**************************************/
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
       
}
/**************************************/
void LSM303_Start()
{
    SDA = 1;                  //拉高数据线
    SCL = 1;                  //拉高时钟线
    Delay5us();               //延时
    SDA = 0;                  //产生下降沿
    Delay5us();               //延时
    SCL = 0;                  //拉低时钟线
}

/**************************************
停止信号
**************************************/
void LSM303_Stop()
{
    SDA = 0;                  //拉低数据线
    SCL = 1;                  //拉高时钟线
    Delay5us();               //延时
    SDA = 1;                  //产生上升沿
    Delay5us();               //延时
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void LSM303_SendACK(bit ack)
{
    SDA = ack;                  //写应答信号
    SCL = 1;                  //拉高时钟线
    Delay5us();               //延时
    SCL = 0;                  //拉低时钟线
    Delay5us();               //延时
}

/**************************************
接收应答信号
**************************************/
bit LSM303_RecvACK()
{
    SCL = 1;                  //拉高时钟线
    Delay5us();               //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                  //拉低时钟线
    Delay5us();               //延时

    return CY;
}

/**************************************
向IIC总线发送一个字节数据
**************************************/
void LSM303_SendByte(BYTE dat)
{
    BYTE i;

    for (i=0; i<8; i++)         //8位计数器
    {
      dat <<= 1;            //移出数据的最高位
      SDA = CY;               //送数据口
      SCL = 1;                //拉高时钟线
      Delay5us();             //延时
      SCL = 0;                //拉低时钟线
      Delay5us();             //延时
    }
    LSM303_RecvACK();
}

/**************************************
从IIC总线接收一个字节数据
**************************************/
BYTE LSM303_RecvByte()
{
    BYTE i;
    BYTE dat = 0;

    SDA = 1;                  //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
      dat <<= 1;
      SCL = 1;                //拉高时钟线
      Delay5us();             //延时
      dat |= SDA;             //读数据               
      SCL = 0;                //拉低时钟线
      Delay5us();             //延时
    }
    return dat;
}

//单字节写入LSM303内部数据*******************************

void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
{
    LSM303_Start();                  //起始信号
    LSM303_SendByte(SlaveAddress);   //发送设备地址+写信号
    LSM303_SendByte(REG_Address);    //内部寄存器地址
    LSM303_SendByte(REG_data);       //内部寄存器数据
    LSM303_Stop();                   //发送停止信号
}

//单字节读取LSM303内部数据********************************
uchar Single_Read(uchar SlaveAddress,uchar REG_Address)
{uchar REG_data;
    LSM303_Start();                        //起始信号
    LSM303_SendByte(SlaveAddress);         //发送设备地址+写信号
    LSM303_SendByte(REG_Address);            //发送存储单元地址       
    LSM303_Start();                        //起始信号
    LSM303_SendByte(SlaveAddress+1);         //发送设备地址+读信号
    REG_data=LSM303_RecvByte();            //读出寄存器数据
        LSM303_SendACK(1);   
        LSM303_Stop();                           //停止信号
    return REG_data;
}
//*********************************************************
//连续读出LSM303内部数据
//*********************************************************
void Multiple_read1(uchar SlaveAddress,uchar ST_Address)
{   uchar i;
           LSM303_Start();                     //起始信号
    LSM303_SendByte(SlaveAddress);      //发送设备地址+写信号
    LSM303_SendByte(ST_Address);          //发送存储单元地址
        LSM303_Start();                        //起始信号
    LSM303_SendByte(SlaveAddress+1);         //发送设备地址+读信号
       for (i=0; i<6; i++)                     //连续读取6个地址数据,存储中BUF
    {
      BUF = LSM303_RecvByte();          //BUF存储
      if (i == 5)
         {
         LSM303_SendACK(1);                //最后一个数据需要回NOACK
         }
      else
      {
          LSM303_SendACK(0);                //回应ACK
       }
   }
    LSM303_Stop();                        //停止信号
}       
void I2C_SendByte(unsigned char addr , unsigned char dat8)
{
        unsigned char i;
        SDA = 1;                  //拉高数据线
    SCL = 1;                  //拉高时钟线
    Delay5us();               //延时
    SDA = 0;                  //产生下降沿
    Delay5us();               //延时
    SCL = 0;                  //拉低时钟线
        addr = (addr << 1) & 0xfe;
        for(i = 8 ; i > 0 ; i --)
        {
                SCL = 0;
                Delay5us();               //延时
                SDA = (addr >> (i - 1 )) & 0x01;
                Delay5us();               //延时
                SCL = 1;
                Delay5us();               //延时
        }

        SCL = 0;
        SDA = 0;
        Delay5us();
        SCL = 1;
        Delay5us();
        Delay5us();
       
        //if(SDA == 0) I2C_SendByte(addr,dat8);
        //dat8 = 0xff;
        for(i = 8 ; i > 0 ; i --)
        {
                SCL = 0;
                Delay5us();
                SDA = (dat8 >> (i - 1 )) & 0x01;
                Delay5us();               //延时
                SCL = 1;
                Delay5us();               //延时
        }
        SCL = 0;
        SDA = 0;
        Delay5us();
        SCL = 1;
        Delay5us();
        Delay5us();
        SCL = 0;

    SDA = 0;                  //拉低数据线
    SCL = 1;                  //拉高时钟线
    Delay5us();               //延时
    SDA = 1;                  //产生上升沿
    Delay5us();               //延时

}
       
//******************
//初始化LSM303A(加速度)**************
void Init_LSM303A()
{
   Single_Write(LSM303A_SlaveAddress,0x20,0x27);   //测量范围,正负2g,16位模式
}

//初始化LSM303M(磁场)
void Init_LSM303M()
{
   Single_Write(LSM303M_SlaveAddress,0x02,0x00);//
}

//**************************************************************
void Port_IO_Init()
{
    P0MDOUT   = 0x10;
    XBR0      = 0x01;
    XBR1      = 0x40;
        P1MDOUT          =        0x40;
        P1 =0xE3;       

}
void Oscillator_Init()
{
    OSCICN    = 0x83;
}
// Initialization function for device,
// Call Init_Device() from your main program
/****************************************************************
*
*UART0初始化函数
*****************************************************************/
void UART0_Init (void)
{
   SCON0    |= 0x10;                                                      
   CKCON   = 0x08;
   TH1       = 0x96;                        //波特率为115200
   TL1       = TH1;                        
   TMOD      = 0x20;                     
   TR1       = 1;                           
   TI0       = 1;
   /*EA      = 1;
   ES0       = 1;   */               
}       
void Init_Device(void)
{
    Port_IO_Init();
    Oscillator_Init();
        UART0_Init();
        TE = 1;
}

//*********************************************************
//******主程序********
//*********************************************************
//unsigned char ii;
voidhs(int j)
{
          j = (0x01<<j);
          I2C_SendByte(0x70,j);
   //Multiple_Read1(LSM303A_SlaveAddress,0xA8);
          Multiple_Read1(LSM303M_SlaveAddress,0x03);
          BUF0 =
          //Multiple_readL3G4200D(0xA8);
}

void main()
{
        int i,j;
            PCA0MD &= ~0x40;                            //清看门狗
        delay(5);                            //上电延时
        Init_Device();
        P1 = 0;
       for(i=0;i<=7;i++)
        {
          j = (0x01<<i);
          I2C_SendByte(0x70,j);
          //Init_LSM303A();      //初始化LSM303 加速度
          Init_LSM303M();                  //初始化LSM303 磁场
        }            
        while(1)
        {
   for(i=0;i<=7;i++)
   {
           hs(i);
           Frame_Send(i,&BUF);
   }                                                                                                  
        }       
}

wk316 发表于 2013-3-22 19:33:40

自己顶一下,求指点啊

john800422 发表于 2013-3-24 13:50:17

改成
Multiple_Read1(LSM303M_SlaveAddress,0x83);
試試看
页: [1]
查看完整版本: 十万火急啊!关于LSM303DLH 地磁获取