搜索
bottom↓
回复: 2

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

[复制链接]

出0入0汤圆

发表于 2013-3-22 19:32:15 | 显示全部楼层 |阅读模式
后天老板就要数据了啊!现在只能获取到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_M  0X03
#define         OUTXL_M  0x04
#define         OUTYH_M  0x05
#define         OUTYL_M  0x06
#define         OUTZH_M  0x07
#define         OUTZL_M  0x08
#define  SR_REG_M  Ox09

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

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

BYTE BUF[16];                         //接收数据缓存区             
int  dis_data;                       //变量

void delay(unsigned int k);
void  Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data);   //单个写入数据
uchar Single_Read(uchar SlaveAddress,uchar REG_Address);                   //单个读取内部寄存器数据
void  Multiple_Read1(uchar,uchar);                                          //连续的读取内部寄存器数据
//------------------------------------
void Delay5us();
//void Delay5ms();
void LSM303_Start();
void LSM303_Stop();
void LSM303_SendACK(bit ack);
bit  LSM303_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[i] = LSM303_RecvByte();          //BUF[0]存储
        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;
void  hs(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);
     }                                                                                                  
        }         
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-3-22 19:33:40 | 显示全部楼层
自己顶一下,求指点啊

出0入0汤圆

发表于 2013-3-24 13:50:17 | 显示全部楼层
改成
Multiple_Read1(LSM303M_SlaveAddress,0x83);
試試看
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 00:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表