K60 + L3G4200 LPLD的库(已解决)
本帖最后由 FSL_TICS_ZJJ 于 2014-1-20 13:08 编辑#ifndef __DEV_L3G4200_H__
#define __DEV_L3G4200_H__
#include "common.h"
#include "HW_I2C.h"
/********用户可修改值 开始***********/
//连接L3G4200用到的I2C通道
#define L3G4200_I2CX (I2C1)
//连接L3G4200用到的SCL引脚
#define L3G4200_SCLPIN(PTC10)
//连接L3G4200用到的SDA引脚
#define L3G4200_SDAPIN(PTC11)
/********用户可修改值 结束***********/
//定义SCL Bus Speed取值,外设总线为50Mhz时的计算结果
#define L3G4200_SCL_50KHZ (0x33)
#define L3G4200_SCL_100KHZ (0x2B)
#define L3G4200_SCL_150KHZ (0x28)
#define L3G4200_SCL_200KHZ (0x23)
#define L3G4200_SCL_250KHZ (0x21)
#define L3G4200_SCL_300KHZ (0x20)
#define L3G4200_SCL_400KHZ (0x17)
//=========MMA8451 功能参数==================//
#define L3G4200_DEV_ADDR 0x69 //定义器件地址,可根据硬件修改
#define L3G4200_DEV_WRITE 0xD2
#define L3G4200_DEV_READ 0xD3
#define L3G4200_DEV_ID 0xD3 //设备ID
//L3G4200 内部寄存器地址
#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
//=========L3G4200 STATUS寄存器 寄存器位==================//
#define L3G4200_STATUS_X_READY 0x01
#define L3G4200_STATUS_Y_READY 0x02
#define L3G4200_STATUS_Z_READY 0x04
#define L3G4200_STATUS_XYZ_READY 0x08
#define L3G4200_STATUS_X_OW 0x10
#define ML3G4200_STATUS_Y_OW 0x20
#define L3G4200_STATUS_Z_OW 0x40
#define L3G4200_STATUS_XYZ_OW 0x80
//函数声明
uint8L3G4200_Init(void);
voidL3G4200_WriteReg(uint8, uint8);
uint8 L3G4200_ReadReg(uint8);
int16 L3G4200_GetResult(uint8, uint8);
#endif
#include "dev_l3g4200.h"
static void L3G4200_Delay(void);
uint8 L3G4200_Init(void)
{
I2C_InitTypeDef i2c_init_param;
uint8 device_id=0;
//初始化L3G4200_I2CX
i2c_init_param.I2C_I2Cx = L3G4200_I2CX ; //在DEV_L3G4200.h中修改该值
i2c_init_param.I2C_IntEnable = FALSE;
i2c_init_param.I2C_ICR = L3G4200_SCL_200KHZ;//可根据实际电路更改SCL频率
i2c_init_param.I2C_SclPin = L3G4200_SCLPIN; //在DEV_MMA8451.h中修改该值
i2c_init_param.I2C_SdaPin = L3G4200_SDAPIN; //在DEV_MMA8451.h中修改该值
i2c_init_param.I2C_Isr = NULL;
LPLD_I2C_Init(i2c_init_param);
//读取设备ID
device_id = L3G4200_ReadReg(WHO_AM_I);
//进行寄存器配置
L3G4200_WriteReg(CTRL_REG1, 0x0f); //100hz 0xff(800hz)
L3G4200_WriteReg(CTRL_REG2, 0x00);
L3G4200_WriteReg(CTRL_REG3, 0x08);
L3G4200_WriteReg(CTRL_REG4, 0x30);//+-2000dps , Data LSB @ lower address
L3G4200_WriteReg(CTRL_REG5, 0x00);
return device_id ;
}
/*
* L3G4200_WriteReg
* 该函数用于配置L3G4200的寄存器
*
* 参数:
* RegisterAddress
* |__ L3G4200寄存器地址
* Data
* |__ 具体写入的字节型数据
*/
voidL3G4200_WriteReg(uint8 RegisterAddress, uint8 Data)
{
//发送从机地址
LPLD_I2C_StartTrans(L3G4200_I2CX,L3G4200_DEV_ADDR, I2C_MWSR);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//写L3G4200寄存器地址
LPLD_I2C_WriteByte(L3G4200_I2CX, RegisterAddress);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//向寄存器中写具体数据
LPLD_I2C_WriteByte(L3G4200_I2CX, Data);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
LPLD_I2C_Stop(L3G4200_I2CX);
L3G4200_Delay();
}
/*
* L3G4200_ReadReg
* 该函数用于读取L3G4200的数据
*
* 参数:
* RegisterAddress
* |__ MMA8451寄存器地址
* 返回值
* 加速传感器的测量值
*/
uint8 L3G4200_ReadReg(uint8 RegisterAddress)
{
uint8 result=0;
//发送从机地址
LPLD_I2C_StartTrans(L3G4200_I2CX,L3G4200_DEV_ADDR, I2C_MWSR);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//写L3G4200_I2CX寄存器地址
LPLD_I2C_WriteByte(L3G4200_I2CX, RegisterAddress);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//再次产生开始信号
LPLD_I2C_ReStart(L3G4200_I2CX);
//发送从机地址和读取位
LPLD_I2C_WriteByte(L3G4200_I2CX , L3G4200_DEV_READ);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//转换主机模式为读
LPLD_I2C_SetMasterWR(L3G4200_I2CX, I2C_MRSW);
//关闭应答ACK
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_OFF);//关闭ACK
// Dummy read 虚假读取
result =LPLD_I2C_ReadByte(L3G4200_I2CX);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//发送停止信号
LPLD_I2C_Stop(L3G4200_I2CX);
//读IIC数据
result = LPLD_I2C_ReadByte(L3G4200_I2CX);
L3G4200_Delay();
return result;
}
/*
* 函数功能:读L3G4200加速度输出
* 参数
* Status - 数据寄存器状态
* Regs_Addr - 数据寄存器地址
* 函数返回值:加速度值(int16)
*/
int16 L3G4200_GetResult(uint8 Status, uint8 Regs_Addr)
{
uint8 ret=0;
uint16 cnt=0;
int16 result,temp;
// 等待转换完成并取出值
while(!(ret&Status))
{
ret = L3G4200_ReadReg( STATUS_REG);
if(++cnt>500)
//break;
;
}
temp= L3G4200_ReadReg( Regs_Addr); //低字节数据
result= L3G4200_ReadReg( Regs_Addr+1);//高字节
result=result<<8;
result=result|temp;
return result;
}
/*
* 延时函数
*/
static void L3G4200_Delay(void){
int n;
for(n=1;n<200;n++) {
asm("nop");
}
}
求救啊,为嘛我读出来的数据,全是0xFF ,
器件地址应该是对啊,LPLD 底层库有进行移位操作啊,器件也是好的
CS 和SA 都接的高
为嘛我读MMA8451可以读出来,读L3G4200 就读不出来 你可以参考一下L3G4200 的相关应用,检查一下不代码和这款芯片对应应用的区别。 看到其他地方一个建议操作,不过那边后来也没有回应,你可以试试看其他网友的建议操作。
“请将SDA管脚配置为open drain输出试试看看。
PortxPCR寄存器中ODE位。” FSL_TICS_ZJJ 发表于 2014-1-10 14:39
看到其他地方一个建议操作,不过那边后来也没有回应,你可以试试看其他网友的建议操作。
“请将SDA管脚配置 ...
刚看了下,那个引脚的开漏输出已经使能了啊在底层库里面
boolean ode = i2c_init_structure.I2C_OpenDrainEnable; 孤独stranger 发表于 2014-1-10 15:13
刚看了下,那个引脚的开漏输出已经使能了啊在底层库里面
boolean ode = i2c_init_structure.I2C_OpenDrai ...
只是其他网友的建议,
我没有用过LPLD库,既然飞思的加速度传感器可以使用,
建议你还是去看看这个L3G4200的一些典型应用,是不是外围,或者控制时序方面有差异。 FSL_TICS_ZJJ 发表于 2014-1-10 15:29
只是其他网友的建议,
我没有用过LPLD库,既然飞思的加速度传感器可以使用,
建议你还是去看看这个L3G420 ...
之前拿M3的板子,用IO口模拟IIC,都可以读出来,现在不管是用M3的硬件IIC,还是K60的硬件IIC,配置的都可以读出其它IIC器件,就是读不出来L3G4200 {:cry:} ,求解决方案啊 孤独stranger 发表于 2014-1-11 13:12
,求解决方案啊
楼主现在怎么样; ,期待你能够采集出信号,分享经验。。我的也是不行啊,NEC-03 温漂的厉害啊。。 传几个资料,希望打什么可以帮忙解决一下,在此表示十分的感谢 孤独stranger 发表于 2014-1-10 17:23
之前拿M3的板子,用IO口模拟IIC,都可以读出来,现在不管是用M3的硬件IIC,还是K60的硬件IIC,配置的都可 ...
建议你可以把你的通信波形抓出来,然后资讯一下L3G4200公司的技术支持!
(正解)
本帖最后由 FSL_TICS_ZJJ 于 2014-1-20 13:09 编辑湛泸骏驰 发表于 2014-1-11 22:17
楼主现在怎么样; ,期待你能够采集出信号,分享经验。。我的也是不行啊,NEC-03 温漂的厉害啊。。 ...
现在搞定了,当时有人提出是SDA管脚要开漏,
我没仔细看,就以为它默认的是开漏
过了两天,我再仔细看,发现默认的是FALSE
改成TRUE就行了 本帖最后由 FSL_TICS_ZJJ 于 2014-1-13 13:37 编辑
孤独stranger 发表于 2014-1-13 10:58
现在搞定了,当时有人提出是SDA管脚要开漏,
我没仔细看,就以为它默认的是开漏
过了两天,我再仔细看, ...
恭喜楼主解决问题,同时也感谢你分享经验!
另外楼主如果问题解决了,请将标题加上“已解决” 孤独stranger 发表于 2014-1-13 10:58
现在搞定了,当时有人提出是SDA管脚要开漏,
我没仔细看,就以为它默认的是开漏
过了两天,我再仔细看, ...
一个不小心给烧了,哎。。你的程序仅仅只是加了一句 i2c_init_param.I2C_OpenDrainEnable=TRUE;对吧。。谢谢了。
已解决
本帖最后由 孤独stranger 于 2014-1-13 14:11 编辑湛泸骏驰 发表于 2014-1-13 13:56
一个不小心给烧了,哎。。你的程序仅仅只是加了一句 i2c_init_param.I2C_OpenDrainEnable=TRUE;对吧 ...
额,有钱人啊,烧一个一百多啊!!
是的,就加那一句话就可以了 孤独stranger 发表于 2014-1-13 14:03
额,有钱人啊,烧一个一百多啊!!
是的,就加那一句话就可以了
我的这个没有那多,也心疼啊 之前我测VCC和GND他们是导通的 ,现在又,没有问题了,可以我的CS 一接3.3V 就冒烟,你遇到这样的问题了吗?
湛泸骏驰 发表于 2014-1-13 18:35
之前我测VCC和GND他们是导通的 ,现在又,没有问题了,可以我的CS 一接3.3V 就冒烟,你遇到这样的问题了吗 ...
木有发现这个问题额,我还以为你是主控板烧了呢,传感器烧了是小事 本帖最后由 湛泸骏驰 于 2014-1-13 21:27 编辑
int16 resultx,resulty,resultz;
uint8 device_id;
void delay(void);
void main (void)
{
//初始化L3G4200D底层驱动及寄存器
device_id=L3G4200_Init();
if(device_id==L3G4200_DEV_ID)
{
printf("L3G4200D init succeed!\r\n");
printf("Device ID :0x%X\r\n,device_id") ;
}
else
{
printf("L3G4200D Init failed !\r\n");
printf("Device ID :0x%x\r\n,device_id");
while(1);
}
while(1)
{
resultx=L3G4200_GetResult(L3G4200_STATUS_X_READY,OUT_X_L);
resulty=L3G4200_GetResult(L3G4200_STATUS_Y_READY,OUT_Y_L) ;
resultz=L3G4200_GetResult(L3G4200_STATUS_Z_READY,OUT_Z_L);
printf("XYZ:\t%d\t%d\t%d\r\n", resultx, resulty, resultz);
}
}
void delay(void)
{
int16 i,n;
for (i=0;i<30000;i++)
{
for (n=0;n<200;n++)
{
asm("nop");
}
}
}
孤独stranger 发表于 2014-1-13 20:41
木有发现这个问题额,我还以为你是主控板烧了呢,传感器烧了是小事
在CS 端接10K电阻后接3.3V没有冒烟,不接就会冒烟的,现在还是不能正确的读取ID{:cry:} {:cry:}
给看看是不是这里有问题呢,
我刚刚测了一下CS端的电压,电压比较低。但是如果我不在电路中串入电阻的话,传感器就会冒烟的,我是使用的lm117-3.3 V的稳压芯片。 湛泸骏驰 发表于 2014-1-13 20:58
在CS 端接10K电阻后接3.3V没有冒烟,不接就会冒烟的,现在还是不能正确的读取ID
给看看 ...
悬空试试? 理论上直接接3.3V 是没有问题的,或者是你那块板子有问题 孤独stranger 发表于 2014-1-14 12:53
悬空试试? 理论上直接接3.3V 是没有问题的,或者是你那块板子有问题
等我的传感器到了,如果不行的话。在请教一下你哈。。 /**
* @file DEV_L3G4200D.h
* @version 0.1
* @date 2013-11-9
* @brief L3G4200三轴陀螺仪设备驱动程序
*/
#ifndef __DEV_L3G4200D_H__
#define __DEV_L3G4200D_H__
#include "common.h"
#include "HW_I2C.h"
/********用户可修改值 开始***********/
//连接L3G4200用到的I2C通道
#define L3G4200_I2CX (I2C1)
//连接L3G4200用到的SCL引脚
#define L3G4200_SCLPIN(PTC10)
//连接L3G4200用到的SDA引脚
#define L3G4200_SDAPIN(PTC11)
/********用户可修改值 结束***********/
//定义SCL Bus Speed取值,外设总线为50Mhz时的计算结果
#define L3G4200_SCL_50KHZ (0x33)
#define L3G4200_SCL_100KHZ (0x2B)
#define L3G4200_SCL_150KHZ (0x28)
#define L3G4200_SCL_200KHZ (0x23)
#define L3G4200_SCL_250KHZ (0x21)
#define L3G4200_SCL_300KHZ (0x20)
#define L3G4200_SCL_400KHZ (0x17)
//=========MMA8451 功能参数==================//
#define L3G4200_DEV_ADDR 0x69//0X68//0x69 //定义器件地址,可根据硬件修改
#define L3G4200_DEV_WRITE 0xD2//0XD0//0xD2
#define L3G4200_DEV_READ 0XD3//0XD1//0xD3
#define L3G4200_DEV_ID 0xD3 //设备ID
//L3G4200 内部寄存器地址
#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
//=========L3G4200 STATUS寄存器 寄存器位==================//
#define L3G4200_STATUS_X_READY 0x01
#define L3G4200_STATUS_Y_READY 0x02
#define L3G4200_STATUS_Z_READY 0x04
#define L3G4200_STATUS_XYZ_READY 0x08
#define L3G4200_STATUS_X_OW 0x10
#define ML3G4200_STATUS_Y_OW 0x20
#define L3G4200_STATUS_Z_OW 0x40
#define L3G4200_STATUS_XYZ_OW 0x80
//函数声明
uint8L3G4200_Init(void);
voidL3G4200_WriteReg(uint8, uint8);
uint8 L3G4200_ReadReg(uint8);
int16 L3G4200_GetResult(uint8, uint8);
#endif
/**
* @file DEV_L3G4200D.h
* @version 0.1
* @date 2013-11-9
* @brief L3G4200三轴陀螺仪设备驱动程序
*/
#include "DEV_L3G4200D.h"
static void L3G4200_Delay(void);
uint8 L3G4200_Init(void)
{
I2C_InitTypeDef i2c_init_param;
uint8 device_id=0;
//初始化L3G4200_I2CX
i2c_init_param.I2C_I2Cx = L3G4200_I2CX ; //在DEV_L3G4200.h中修改该值
i2c_init_param.I2C_IntEnable = FALSE;
i2c_init_param.I2C_ICR = L3G4200_SCL_200KHZ;//可根据实际电路更改SCL频率
i2c_init_param.I2C_SclPin = L3G4200_SCLPIN; //在DEV_MMA8451.h中修改该值
i2c_init_param.I2C_SdaPin = L3G4200_SDAPIN; //在DEV_MMA8451.h中修改该值
i2c_init_param.I2C_OpenDrainEnable=TRUE;
i2c_init_param.I2C_Isr = NULL;
LPLD_I2C_Init(i2c_init_param);
//读取设备ID
device_id = L3G4200_ReadReg(WHO_AM_I);
//进行寄存器配置
L3G4200_WriteReg(CTRL_REG1, 0x0f); //100hz 0xff(800hz)
L3G4200_WriteReg(CTRL_REG2, 0x00);
L3G4200_WriteReg(CTRL_REG3, 0x08);
L3G4200_WriteReg(CTRL_REG4, 0x30);//+-2000dps , Data LSB @ lower address
L3G4200_WriteReg(CTRL_REG5, 0x00);
return device_id ;
}
/*
* L3G4200_WriteReg
* 该函数用于配置L3G4200的寄存器
*
* 参数:
* RegisterAddress
* |__ L3G4200寄存器地址
* Data
* |__ 具体写入的字节型数据
*/
voidL3G4200_WriteReg(uint8 RegisterAddress, uint8 Data)
{
//发送从机地址
LPLD_I2C_StartTrans(L3G4200_I2CX,L3G4200_DEV_ADDR, I2C_MWSR);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//写L3G4200寄存器地址
LPLD_I2C_WriteByte(L3G4200_I2CX, RegisterAddress);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//向寄存器中写具体数据
LPLD_I2C_WriteByte(L3G4200_I2CX, Data);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
LPLD_I2C_Stop(L3G4200_I2CX);
L3G4200_Delay();
}
/*
* L3G4200_ReadReg
* 该函数用于读取L3G4200的数据
*
* 参数:
* RegisterAddress
* |__ MMA8451寄存器地址
* 返回值
* 加速传感器的测量值
*/
uint8 L3G4200_ReadReg(uint8 RegisterAddress)
{
uint8 result=0;
//发送从机地址
LPLD_I2C_StartTrans(L3G4200_I2CX,L3G4200_DEV_ADDR, I2C_MWSR);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//写L3G4200_I2CX寄存器地址
LPLD_I2C_WriteByte(L3G4200_I2CX, RegisterAddress);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//再次产生开始信号
LPLD_I2C_ReStart(L3G4200_I2CX);
//发送从机地址和读取位
LPLD_I2C_WriteByte(L3G4200_I2CX , L3G4200_DEV_READ);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//转换主机模式为读
LPLD_I2C_SetMasterWR(L3G4200_I2CX, I2C_MRSW);
//关闭应答ACK
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_OFF);//关闭ACK
// Dummy read 虚假读取
result =LPLD_I2C_ReadByte(L3G4200_I2CX);
LPLD_I2C_WaitAck(L3G4200_I2CX, I2C_ACK_ON);
//发送停止信号
LPLD_I2C_Stop(L3G4200_I2CX);
//读IIC数据
result = LPLD_I2C_ReadByte(L3G4200_I2CX);
L3G4200_Delay();
L3G4200_Delay();
L3G4200_Delay();
return result;
}
/*
* 函数功能:读L3G4200加速度输出
* 参数
* Status - 数据寄存器状态
* Regs_Addr - 数据寄存器地址
* 函数返回值:加速度值(int16)
*/
int16 L3G4200_GetResult(uint8 Status, uint8 Regs_Addr)
{
uint8 ret=0;
uint16 cnt=0;
int16 result,temp;
// 等待转换完成并取出值
while(!(ret&Status))
{
ret = L3G4200_ReadReg( STATUS_REG);
if(++cnt>500)
//break;
;
}
temp= L3G4200_ReadReg( Regs_Addr); //低字节数据
result= L3G4200_ReadReg( Regs_Addr+1);//高字节
result=result<<8;
result=result|temp;
return result;
}
/*
* 延时函数
*/
static void L3G4200_Delay(void){
int n;
for(n=1;n<200;n++) {
asm("nop");
}
}
/**
* --------------基于"拉普兰德K60底层库V3"的工程(L3G4200D)-----------------
* @file L3G4200D.c
* @version 0.0
* @date 2013-9-29
* @brief 关于该工程的描述
*
* 版权所有:北京拉普兰德电子技术有限公司
* http://www.lpld.cn
* mail:support@lpld.cn
* 硬件平台:LPLD K60 Card / LPLD K60 Nano
*
* 本工程基于"拉普兰德K60底层库V3"开发,
* 所有开源代码均在"lib"文件夹下,用户不必更改该目录下代码,
* 所有用户工程需保存在"project"文件夹下,以工程名定义文件夹名,
* 底层库使用方法见相关文档。
*
*/
#include "common.h"
#include "DEV_L3G4200D.h"
int16 resultx,resulty,resultz;
uint8 device_id;
void delay(void);
void main (void)
{
//初始化L3G4200D底层驱动及寄存器
device_id=L3G4200_Init();
if(device_id==L3G4200_DEV_ID)
{
printf("L3G4200D init succeed!\r\n");
printf("Device ID :0x%X\r\n,device_id") ;
}
else
{
printf("L3G4200D Init failed !\r\n");
printf("Device ID :0x%x\r\n,device_id");
while(1);
}
while(1)
{
resultx=L3G4200_GetResult(L3G4200_STATUS_X_READY,OUT_X_L);
resulty=L3G4200_GetResult(L3G4200_STATUS_Y_READY,OUT_Y_L) ;
resultz=L3G4200_GetResult(L3G4200_STATUS_Z_READY,OUT_Z_L);
printf("XYZ:\t%d\t%d\t%d\r\n", resultx, resulty, resultz);
}
}
void delay(void)
{
int16 i,n;
for (i=0;i<30000;i++)
{
for (n=0;n<200;n++)
{
asm("nop");
}
}
}
好人楼主,能给测试一下L3G4200D吗?我这里使用你的代码还是读不出ID 啊。新来的传感器。,。帮忙测一下,代码能否读取ID 吧,顺便给来张截图,,
页:
[1]