ADXL345是一种三轴加速度计。
具有+/-2g,+/-4g,+/-8g,+/-16g可变的测量范围;最高13bit分辨率;固定的4mg/LSB灵敏度;3mm*5mm*1mm超小封装;40-145uA超低功耗;标准的I2C或SPI数字接口;32级FIFO存储;以及内部多种运动状态检测和灵活的中断方式等特性。
1、读取加速度
2、让单片机和加速度计ADXL345处于睡眠状态,当该加速度计被摇一摇的时候,触发最大阈值,从睡眠模式唤醒并从中断引脚输出高电平唤醒单片机。
看数据手册中的寄存器来写代码。
这个芯片有中文的数据手册,看起来比较爽,但有的翻译怪眉日眼的,不是很明确,有的地方写的也不是很明确,我会在后面把一些不是很好看的寄存器写出来。
使用STM32单片机,在KEIL环境C语言编程
直接看代码吧,不详细说了
void ADXL345_Init(void)
{
unsigned char devid = 0, val = 0;
DelayUs(300);
I2C_ReadByte(ADXL345_ADDRESS, 0x00, &devid); //读ID 且每次读写之前都需要读ID
DelayUs(300);
val = 0x2B;
I2C_WriteByte(ADXL345_ADDRESS, DATA_FORMAT_REG, &val); //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程
DelayUs(50);
val = 0x0A;
I2C_WriteByte(ADXL345_ADDRESS, BW_RATE, &val); //数据输出速度为100Hz
DelayUs(50);
val = 0x28;
I2C_WriteByte(ADXL345_ADDRESS, POWER_CTL, &val); //链接使能,测量模式
DelayUs(50);
val = 0;
I2C_WriteByte(ADXL345_ADDRESS, INT_ENABLE, &val); //不使用中断
DelayUs(50);
DelayXms(20);
//软件偏移校准,视上电时为平放状态,x=0,y=0,z=1=====================
ADXL345_GetValue();
ofz_X = 0 - adxlInfo.incidence_X;
ofz_Y = 0 - adxlInfo.incidence_Y;
ofz_Z = 256 - adxlInfo.incidence_Z;
}
PS:比例因子62.5mg是因为这是一个8位的寄存器最多存放256个值,而该芯片最大量程为16g=62.5mg*256
下面这个寄存器需要在主函数while(1)里面不断的读,最好用串口输出一下,观察各个事件是否触发
带中断唤醒的代码如下:
/*
*/
void ADXL345_Int_Init(void)
{
unsigned char devid = 0, val = 0;
DelayUs(300);
I2C_ReadByte(ADXL345_ADDRESS, 0x00, &devid); //读ID 且每次读写之前都需要读ID
DelayUs(300);
val = 0x1B;
I2C_WriteByte(ADXL345_ADDRESS, DATA_FORMAT_REG, &val); //低电平中断输出,13位全分辨率,输出数据右对齐,16g量程
DelayUs(50);
val = 0x0A;
I2C_WriteByte(ADXL345_ADDRESS, BW_RATE, &val); //数据输出速度为100Hz
DelayUs(50);
val = 0x38; //自动休眠模式,休眠时以8HZ的频率采样
I2C_WriteByte(ADXL345_ADDRESS, POWER_CTL, &val);
DelayUs(50);
val = 0;
I2C_WriteByte(ADXL345_ADDRESS, INT_ENABLE, &val); //先关中断
val = 0x10; //睡眠激活activity阈值,当大于这个值的时候唤醒,其中10代表1g
I2C_WriteByte(ADXL345_ADDRESS, 0x24, &val);
val = 0x02; // val = 0x10; //睡眠开始inactivity阈值,当小于这个值的时候睡眠,其中02代表0.2g
I2C_WriteByte(ADXL345_ADDRESS, 0x25, &val);
val = 0x02; //当小于inactivity值时间超过这个值的时候进入睡眠,其中02代表2秒
I2C_WriteByte(ADXL345_ADDRESS, 0x26, &val);
val = 0xCC; //直流交流触发配置,XYZ使能触发配置,此处选用X交流触发
I2C_WriteByte(ADXL345_ADDRESS, 0x27, &val);
val = 0x10; //中断引脚选择,此处我们将activity映射到INT2
I2C_WriteByte(ADXL345_ADDRESS, 0x2F, &val);
DelayUs(50);
val = 0xFF; //打开中断
I2C_WriteByte(ADXL345_ADDRESS, 0x2E, &val);
DelayXms(20);
//软件偏移校准,视上电时为平放状态,x=0,y=0,z=1=====================
ADXL345_GetValue();
ofz_X = 0 - adxlInfo.incidence_X;
ofz_Y = 0 - adxlInfo.incidence_Y;
ofz_Z = 256 - adxlInfo.incidence_Z;
}
结构体
(还没写)
&的用法
为了观察0x30中的activity事件是否触发,其他位是否触发我们暂时不用管,杨叫兽直接写了一行if就把所有的情况都概括进去了,NB
{
I2C_ReadByte(ADXL345_ADDRESS, 0x30, &Data);
if(Data&0x10)
UsartPrintf(USART1,”0x30: %x \r\n”,Data);
}
写代码得一点一点加,不能一次写太多,应该在测试正常后再继续写