前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >蓝桥杯嵌入式之MEME传感器(LIS302DL、三轴加速度传感器)讲解

蓝桥杯嵌入式之MEME传感器(LIS302DL、三轴加速度传感器)讲解

作者头像
用户5935416
发布2019-08-01 10:12:00
1.8K0
发布2019-08-01 10:12:00
举报
文章被收录于专栏:IT界的小白帽IT界的小白帽

扩展板提供了一个三轴加速度传感器(LIS302DL)。由于该模块的知识非常多,所以可以参考网上的教程。在这里只是讲解如何使用。

LIS302DL可以进行IIC通信和SPI通信,但因为线路的连接而只能使用IIC通信。LIS302DL的电路连接图为

由于P2中的5—6和7—8引脚是LIS302DL中断引脚,例程中并没有使用,所以本次讲解也没有使用到。

IIC初始化

由于在比赛的时候会给IIC的驱动代码,但是因为EEPROM的通信方式也是IIC通信,所以在LIS302DL中使用IIC通信的话需要修改I/O的选择。IIC和SPI的通信方式由CS引脚选择,但是CS的引脚接成高电平,所以默认为IIC的通信方式,只需对IIC进行初始化即可。

IIC初始化代码为

代码语言:javascript
复制
//I2C总线初始化
void i2c_init()
{
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = SDA_Pin | SCL_Pin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // **

  GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}

由于IIC的通信方式需要I/O既做输入,又做输出,需要不断的转换,所以不能只修改IIC初始化的I/O选择,而应该设置宏定义或者所有的地方都进行修改。

LIS302DL的初始化

LIS302DL的初始化代码为

代码语言:javascript
复制
void LIS302DL_Config(void)
{
  LIS302DL_Write(CTRL_REG1,0x47);
  LIS302DL_Write(CTRL_REG2,0x00);
  LIS302DL_Write(CTRL_REG3,0xC1);
  LIS302DL_Write(FF_WU_THS_1,0x28);    
  LIS302DL_Write(FF_WU_DURATION_1,40);    
//  LIS302DL_Write(FF_WU_CFG_1,0x10);    
}

只需第一句的代码也可以正常使用LIS302DL。这些代码都是对一些寄存器进行赋值,具体的寄存器使用说明可以参考LIS302DL的使用手册。其中相关的宏定义为

代码语言:javascript
复制
#define CTRL_REG1       0x20
#define CTRL_REG2       0x21
#define CTRL_REG3       0x22
#define FF_WU_THS_1     0x32
#define FF_WU_DURATION_1   0x33
#define FF_WU_CFG_1     0x30

下面是对一些寄存器赋值的说明(依据LIS302DL初始化代码为例)

代码语言:javascript
复制
void LIS302DL(void)
{
  LIS302DL_Write(CTRL_REG1,0x47);
  //DR=0,加速度的采集频率为 200Hz;
  //PD=1,LIS302DL工作在普通功耗模式;
  //FS=0,最大测量范围为 2g(2.3g),灵敏度为 18mg/LSB(16.2),受温度影响为 0.01%, 在0加速度时.飘移为 40mg;
  //STP=0,STM=0,表示 LIS302DL 工作在普通模式,即非自检模式;
  //Zen=1,表示使能 Z 轴方向加速度采集; 
  //Yen=1,表示使能 Y 轴方向加速度采集; 
  //Xen=1,表示使能 X 轴方向加速度采集; 
  LIS302DL_Write(CTRL_REG2,0x00);
  //SIM=0,表示 SPI 口为 4 总线;(这个要先看cs决定)
  //BOOT=0,表示不要刷新存储器的内容,为普通模式;
  //FDS=0,表示禁用高通滤器;
  //HP_FF_W_U2=0, 禁用自由落体/唤醒高通滤波器 2;
  //HP_FF_W_U1=0, 禁用自由落体/唤醒高通滤波器 1;
  //HP_coeff2=0,HP_coeff1=0,DR=0, 表示自由落体/唤醒高通滤波器的输出截止频率为 2Hz;
  LIS302DL_Write(CTRL_REG3,0xC1);
  //IHL=1,表示在中断发生时,中断脚(INT1 和 INT2)输出低电平;
  //PP_OD=1,表示中断脚开漏输出;
  //I2CFG2=0,I2CFG1=0,I2CFG0=0,表示 INT2 脚输出低电平;
  //I1CFG2=0,I1CFG1=0,I1CFG0=1,表示 INT1 脚是根据自由落体/唤醒 1 寄存器的输出而发生变化;
  LIS302DL_Write(FF_WU_THS_1,0x28);
  //DCRM=0,表示在不再有中断发生时,持续时间计数器会被复位到初值;
  //THS0~THS6,用来设置自由落体/唤醒的下限值--720mg;  
  LIS302DL_Write(FF_WU_DURATION_1,40);  
  //当 DR=1 时,加速度的采集频率为 ;  
  LIS302DL_Write(FF_WU_CFG_1,0x10);    
  //AOI=1,表示所有中断事件相或后输出;
  //LIR=0,表示将中断请求不锁存;
  //ZHIE=0,表示在 Z 输出寄存器的值大于 Z 轴的设置值时,将不会使能 Z 轴中断;
  //ZLIE=1,表示在 Z 输出寄存器的值小于 Z 轴的设置值时,将不使能中断请求;
  //YHIE=0,表示在 Y 输出寄存器的值大于 Y 轴的设置值时,将不会使能 Y 轴中断;
  //YLIE=1,表示在 Y 输出寄存器的值小于 Y 轴的设置值时,将不会使能 Y 轴中断;
  //XHIE=1,表示在 X 输出寄存器的值大于 X 轴的设置值时,将不会使能 X 轴中断;
  //XLIE=0,表示在 X 输出寄存器的值小于 X 轴的设置值时,将不会使能 X 轴中断;
}

LIS302DL的读写函数

LIS302DL的写函数为

代码语言:javascript
复制
void LIS302DL_Write(unsigned char reg,unsigned char info)
{  
  I2CStart(); 
  I2CSendByte(0x38);  
  I2CWaitAck();     
  I2CSendByte(reg);  
  I2CWaitAck(); 
  I2CSendByte(info); 
  I2CWaitAck();
  I2CStop();
}

由于LIS302DL的地址选择都接地,所以LIS302DL的地址为0x38。

LIS302DL的读函数

代码语言:javascript
复制
uint8_t LIS302DL_Read(uint8_t address)
{
  unsigned char val;
  I2CStart(); 
  I2CSendByte(0x38);  
  I2CWaitAck();     
  
  I2CSendByte(address);  
  I2CWaitAck(); 
  
  I2CStart();
  I2CSendByte(0x39); 
  I2CWaitAck();
  val = I2CReceiveByte(); 
  I2CSendNotAck();
  I2CStop();
  
  return(val);
}

读指令为0x39。

其读写代码和EEPROM的差不多,但是指令不一样,容易混淆。

LIS302DL是否存在判断

在使用前先判断LIS302DL是否存在,虽然代码非常简单,但是其重要性不言而喻的。模块不存在而直接使用的话会有一些错误的数据,造成错误的行为。

LIS302DL是否存在的代码为

代码语言:javascript
复制
if(LIS302DL_Check() == 1)
{
  LCD_DisplayStringLine(Line3, (u8 *)" MEMS STATUS: OK");
}
else
{
  LCD_DisplayStringLine(Line3, (u8 *)" MEMS STATUS: ERROR");        
}

函数LIS302DL_Check的定义为

代码语言:javascript
复制
uint8_t LIS302DL_Check(void)
{
  if(LIS302DL_Read(0x0f))
  {
    return 1;
  }
  else
  {
    return 0;
  }
}

LIS302DL显示讲解

LIS302DL显示的代码为

代码语言:javascript
复制
ptr = Lis302DL_Output();
      
snprintf((char *)str, sizeof(str), " X Reg:%d    ", ptr[0]);
LCD_DisplayStringLine(Line6,str);
snprintf((char *)str, sizeof(str), " Y Reg:%d    ", ptr[1]);
LCD_DisplayStringLine(Line7,str);
snprintf((char *)str, sizeof(str), " Z Reg:%d    ", ptr[2]);
LCD_DisplayStringLine(Line8,str);  
Delay_Ms(200);

指针ptr的定义为

代码语言:javascript
复制
u8 *ptr;

函数Lis302DL_Output的定义为

代码语言:javascript
复制
u8* Lis302DL_Output(void)
{
  if((LIS302DL_Read(0x27) & 0x08) != 0)
  {
    
    alz[0] = (LIS302DL_Read(0x29));  //x
    alz[1] = (LIS302DL_Read(0x2B));  //y
    alz[2] = (LIS302DL_Read(0x2D));  //z
  }

  return alz;
}

其分别读出相应寄存器的值,这些寄存器的使用说明为

测试各个方向的加速度的话需要将读取到的数据除以18。如果只测偏移度的话,数组ptr的值不变。

数组在相应文件的定义为

代码语言:javascript
复制
u8 alz[3] ;
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT界的小白帽 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档