找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3600|回复: 0
打印 上一主题 下一主题
收起左侧

6轴传感器LSM330DLC的底层驱动

[复制链接]
跳转到指定楼层
楼主
ID:105323 发表于 2016-2-21 15:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      这几天发现有几个同行在论坛发帖说LSM330DLC访问不了,所以将自己的底层调试过程贴出来,和大家一起讨论学习,有说不清楚的地方,还请砖下留人!      
     LSM330DLC是意法半导体的一款6轴传感器芯片,可以采用I2C接口或者SPI接口,在这个项目中,使用了I2C接口。MCU使用的是STM32F103。?
       I2C的调试主要关注的是如下几个参数:I2C1使用的是APB1时钟,该项目中APB1的时钟是24M,所以I2C1->CR2|=24;  I2C1->CCR =0X801E,各位的含义如下:?
1,采用快速模式?
2,最后12位为分频系数,通过分频将24M分频成I2C设备能接受的时钟信号。?由于CCR寄存器使用的是快速模式,且DUTY=0,即Tlow/Thigh =2?,所以看看LSTM330DLC的手册可以知道低电平持续的时间是1.3us,而高电平持续的时间是0.6us,SCL的时钟频率是最大400KHz,

3、根据公式1计算CCR的值为 24000000/2/400K =30,而SCL和SDA的最大上升时间是0.3us,所以可以因此确定TRISE寄存器的值为300/(1000/24)=7+1 =8,其实我调试时,用了一个比较大的值。??
下面就是读写的方法:读写的方法,数据手册给了一幅图:?


从图上可以看出,字节是需要ACK的,最后一个字节是不需要ACK的。?
另外需要注意的是加速度寄存器的地址是0X30,而角速度传感器的设备地址是0XD4?
u8 I2C_EE_ByteRead(u8 devAddr,u8 ReadAddr)
{
u8 result;
I2C_EE_ArrayRead(devAddr,&result, ReadAddr,1);
return result;
}
void I2C_EE_ByteWrite( u8 devAddr, u8* pBuffer, u8WriteAddr)
{
I2C_GenerateSTART(ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(devAddr
WRITE_CMD, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//I2C_SendData((u8)(WriteAddr>>8));
//while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData( WriteAddr);
while(! I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData( *pBuffer);
while(!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(ENABLE);
}
void I2C_EE_ArrayWrite(u8 devAddr,u8* pBuffer, u8 WriteAddr, u8NumByteToWrite)
{
while(I2C_GetFlagStatus(I2C_FLAG_BUSY));
I2C_GenerateSTART( ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(devAddr
WRITE_CMD, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//I2C_SendData((u8)(WriteAddr>>8));
//while(! I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData( WriteAddr
ADDR_AUTO_INC);
while(! I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED));
while(NumByteToWrite--)
{
I2C_SendData(*pBuffer);
pBuffer++;
while (!I2C_CheckEvent( I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
I2C_GenerateSTOP( ENABLE);
}
void I2C_EE_ArrayRead(u8 devAddr,u8* pBuffer, u8 ReadAddr, u32NumByteToRead)
{
while(I2C_GetFlagStatus( I2C_FLAG_BUSY));
I2C_GenerateSTART( ENABLE);
while(!I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(devAddr
WRITE_CMD, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_Cmd(ENABLE);
//I2C_SendData((u8)(ReadAddr>>8));
//while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(ReadAddr
ADDR_AUTO_INC);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART( ENABLE);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(devAddr
READ_CMD, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while(NumByteToRead)
{
if(NumByteToRead == 1)
{
I2C_AcknowledgeConfig(DISABLE);
I2C_GenerateSTOP( ENABLE);
return;
}
if(I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
{
*pBuffer = I2C_ReceiveData();
pBuffer++;
NumByteToRead--;
}
}
I2C_AcknowledgeConfig(ENABLE);
}
void I2C_EE_WaitEepromStandbyState( u8 devAddr )
{
volatile u16 SR1_Tmp = 0;
do
{
I2C_GenerateSTART(ENABLE);
SR1_Tmp = I2C_ReadRegister(I2C_Register_SR1);
I2C_Send7bitAddress(devAddr
WRITE_CMD, I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(I2C_Register_SR1) &0x0002));
I2C_ClearFlag(I2C_FLAG_AF);
I2C_GenerateSTOP(ENABLE);
}
调试阶段,代码行没整理,希望对大家有所帮助。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩

相关帖子

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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