【CH579M-R1】+求助:驱动LSM303DLH磁场传感器不成功
[复制链接]
网购的一块LSM303DLH磁场传感器模块,准备用CH579M-R1开发板来驱动,下面是模块的照片:
模块上有8个引脚,其中4个是I2C通讯用的(包括电源正负极),另外4个分别是ADDR(加速度地址选择)、INT1、INT2、DRY(磁场数据准备好检测)。
通过分析商家提供的资料及STM32驱动代码,只有I2C通讯的内容,因此我只连接了I2C的SDA和DCK以及3.3V电源,其他引脚空置未连接。
范例中对LSM303DLH的初始化仅仅操作了3个寄存器,代码如下:
*********************************************
* 函数名称:InitLSM303D(void)
* 函数功能:初始化LSM303D
* 入口参数:无
* 出口参数:无
* 备 注:根据需要请参考数据手册,进行修改
*********************************************/
void InitLSM303D(void)
{
I2C_8bitSingle_Write(M_SlaveAddress,0x00,0x14);
I2C_8bitSingle_Write(M_SlaveAddress,0x02,0x00);
I2C_8bitSingle_Write(M_SlaveAddress,0x20,0x2F); //测量范围,正负2g,16位模式0x27
}
其中的第三行原来写入的是0x27,即正常模式、50Hz传输率,在测试中我修改为0x2F,即传输率改为100Hz。
模块中磁场传感器的数据读取地址与运动传感器的数据读取地址不同,我查阅了数据手册,是正确的。读取数据的代码如下:
/*********************************************
* 函数名称:InitLSM303D(void)
* 函数功能:磁场数据和加速度数据读取
* 入口参数:无
* 出口参数:无
* 备 注:根据需要请参考数据手册,进行修改
*********************************************/
void LSM303D_Read(void)
{
//磁场数据读取
I2C_8bitAddrRead(M_SlaveAddress,0x03,6,(uint8_t *)BUF);//OUT_X_M
M_x=(BUF[0] << 8) | BUF[1]; //合成16位数据
M_y=(BUF[2] << 8) | BUF[3]; //合成16位数据
M_z=(BUF[4] << 8) | BUF[5]; //合成16位数据
// angle= atan2(M_y,M_x) * (180 / 3.14159265) + 180; //角度(度)angle in degrees
// DATA_printf(TX_DATA,angle); //转换角度轴数据到数组
// Send_data('M'); //发送数据,M:磁场0-360
DATA_printf(TX_DATA,M_x);
LCD_write_ASCII(0,2,1,TX_DATA);
DATA_printf(TX_DATA,M_y);
LCD_write_ASCII(0,3,1,TX_DATA);
DATA_printf(TX_DATA,M_z);
LCD_write_ASCII(0,4,1,TX_DATA);
// LCD_write_value(0,2,5,0,0,M_x);
// LCD_write_value(0,3,5,0,0,M_y);
// LCD_write_value(0,4,5,0,0,M_z);
//加速度数据读取
BUF[0]=I2C_8bitSingle_Read(A_SlaveAddress,0x28);//OUT_X_A
BUF[1]=I2C_8bitSingle_Read(A_SlaveAddress,0x29);//OUT_X_A
BUF[2]=I2C_8bitSingle_Read(A_SlaveAddress,0x2A);//OUT_Y_A
BUF[3]=I2C_8bitSingle_Read(A_SlaveAddress,0x2B);//OUT_Y_A
BUF[4]=I2C_8bitSingle_Read(A_SlaveAddress,0x2C);//OUT_Z_A
BUF[5]=I2C_8bitSingle_Read(A_SlaveAddress,0x2D);//OUT_Z_A
A_x=(BUF[1] << 8) | BUF[0]; //合成16位数据
A_y=(BUF[3] << 8) | BUF[2]; //合成16位数据
A_z=(BUF[5] << 8) | BUF[4]; //合成16位数据
A_x/=16.383; //mg
A_y/=16.383; //mg
A_z/=16.383; //mg
// DATA_printf(TX_DATA,A_x); //转换X轴数据到数组
// Send_data('x'); //发送数据,mg为单位
// DATA_printf(TX_DATA,A_y); //转换X轴数据到数组
// Send_data('y'); //发送数据,mg为单位
// DATA_printf(TX_DATA,A_z); //转换X轴数据到数组
// Send_data('z'); //发送数据,mg为单位
// USART1_SendData(0X0D); //换行
// USART1_SendData(0X0A); //回车
DATA_printf(TX_DATA,A_x);
LCD_write_ASCII(40,2,1,TX_DATA);
DATA_printf(TX_DATA,A_y);
LCD_write_ASCII(40,3,1,TX_DATA);
DATA_printf(TX_DATA,A_z);
LCD_write_ASCII(40,4,1,TX_DATA);
// LCD_write_value(40,2,5,0,0,A_x);
// LCD_write_value(40,3,5,0,0,A_y);
// LCD_write_value(40,4,5,0,0,A_z);
Delayms(1);
}
原代码是将读取的数据通过串口发送,我修改成显示在LCD屏幕中。
代码编译通过后,下载到开发板上测试,磁场和加速度三个轴数值全部相同,分别是514和31,无论如何移动模块方位都不会变化:
用商家提供的范例直接编译,提示缺少库文件:
在论坛里下载到虾版的测试帖子,也是提示缺少文件而无法编译:
花了两天时间仔细查阅数据手册,也没有找到解决问题的方法。另外分析商家提供的代码,发现定义了不少模块中的寄存器地址,但没有找到何处引用这些定义的:
#ifndef __LSM303D_H
#define __LSM303D_H
//磁场内部寄存器***********************************
/* Magnetometer registers磁力计寄存器 */
#define CRA_REG_M 0x00 /* Configuration register A */
#define CRB_REG_M 0x01 /* Configuration register B */
#define MR_REG_M 0x02 /* Mode register */
/* resume state index恢复状态索引 */
#define RES_CRA_REG_M 0 /* Configuration register A */
#define RES_CRB_REG_M 1 /* Configuration register B */
#define RES_MR_REG_M 2 /* Mode register */
/* Output register start address输出寄存器起始地址 */
#define OUT_X_M 0x03
/* Magnetic Sensor Operation Mode磁传感器操作模块 */
#define NORMAL_MODE 0x00
#define POS_BIAS 0x01
#define NEG_BIAS 0x02
#define CC_MODE 0x00
#define SC_MODE 0x01
#define SLEEP_MODE 0x03
//加速度内部寄存器***********************************
#define AXISDATA_REG 0x28
#define WHOAMI_LSM303DLH_ACC 0x32 /* Expctd content for WAI */
/* CONTROL REGISTERS */
#define WHO_AM_I 0x0F /* WhoAmI register */
#define CTRL_REG1 0x20 /* */
#define CTRL_REG2 0x21 /* */
#define CTRL_REG3 0x22 /* */
#define CTRL_REG4 0x23 /* */
#define CTRL_REG5 0x24 /* */
#define INT_CFG1 0x30 /* interrupt 1 config */
#define INT_SRC1 0x31 /* interrupt 1 source */
#define INT_THS1 0x32 /* interrupt 1 threshold */
#define INT_DUR1 0x33 /* interrupt 1 duration */
#define INT_CFG2 0x34 /* interrupt 2 config */
#define INT_SRC2 0x35 /* interrupt 2 source */
#define INT_THS2 0x36 /* interrupt 2 threshold */
#define INT_DUR2 0x37 /* interrupt 2 duration */
#define M_SlaveAddress 0x3C
#define A_SlaveAddress 0x30
void InitLSM303D(void); //传感器初始化
void LSM303D_Read(void); //读取传感器数据
#endif
在上面的定义中真正用到的仅仅是两个I2C地址,其他的没有发现在哪引用。
在淘宝搜索了同类产品,发现他们提供的资料完全一致,应该都是同一出处的。
我现在的疑问是:
1、模块上的ADDR,INT1,INT2,DRY引脚该如何连接(我暂时只需要读取磁场传感器数据,尚未涉及运动传感器数据)?
2、上述的模块初始化代码是否还缺少,导致模块尚未进入正常工作?
3、读取数据前是否还有先决条件?
补充内容 (2020-10-16 13:07):
经过各位的热心帮助,已经基本可以读出数据了,关键还是要对模块加热。
|