STM32F103C8T6二氧化碳传感器JW01-CO2的使用方法和代码驱动
文档结尾有代码下载
🎯 实现效果


🌟 传感器用途
ADXL345 作为一款高性能三轴加速度传感器,凭借其高精度、低功耗、小尺寸的特性,在众多领域中都有着广泛且关键的应用
1. 电子领域
- 在消费电子领域,它是智能穿戴设备的核心组件之一。比如智能手环和手表,依靠它实现精准计步,通过检测手臂摆动的加速度变化来统计步数;还能监测用户的运动强度,根据不同的加速度值判断是散步、跑步还是剧烈运动。在智能手机中,ADXL345 用于实现屏幕自动旋转功能,当手机倾斜时,传感器感知到加速度的变化,进而触发屏幕横竖屏的切换;在体感游戏里,它能捕捉玩家的肢体动作,将其转化为游戏中的操作指令,提升游戏的互动性和趣味性。
2. 工业领域
- 工业领域中,ADXL345 常用于设备状态监测。对于各种旋转机械、机床等,设备运行时的振动情况是判断其是否正常工作的重要依据,该传感器可以实时监测振动的加速度变化,当振动超出正常范围时,及时发出预警,便于维护人员提前排查故障,减少设备停机时间和维修成本。在机器人技术方面,它能为机器人提供姿态信息,帮助机器人保持平衡,比如在扫地机器人避障和路径规划过程中,通过感知机器人的倾斜和振动,确保其稳定运行。
3. 汽车电子行业
- 汽车电子行业,ADXL345 发挥着重要的安全保障作用。在汽车碰撞检测系统中,当汽车发生碰撞时,传感器能瞬间检测到巨大的加速度变化,迅速将信号传递给安全气囊控制单元,促使安全气囊及时弹出,保护驾乘人员的安全。此外,它还用于汽车的车身稳定系统,实时监测车身的倾斜和振动情况,辅助系统调整刹车力度和悬挂系统,提高汽车行驶的稳定性和安全性。
4. 医疗健康领域
- 医疗健康领域,该传感器也有独特的应用。在康复医疗设备中,如用于肢体康复训练的器械,ADXL345 可以监测患者肢体运动的加速度和角度,帮助医生评估患者的康复进度和训练效果。在睡眠监测设备中,它能感知用户睡眠时的翻身等动作,记录睡眠状态,为睡眠质量分析提供数据支持。
5. 航空航天领域
- 航空航天领域,ADXL345 可用于航天器的姿态控制和振动监测。在卫星和飞船的运行过程中,传感器实时监测其加速度变化,为姿态调整提供精确的数据,确保航天器按预定轨道运行。同时,它还能监测航天器在发射和运行过程中的振动情况,保障设备的正常工作和宇航员的安全。
6. 物联网领域
- 物联网领域,智能家具也能用到该传感器。比如智能台灯,当用户触摸或倾斜台灯时,传感器感知到动作,实现灯光的开关和亮度调节;智能门窗系统中,通过检测门窗的振动和加速度变化,判断是否有异常开启,从而触发报警装置。
🌟 传感器的介绍
ADXL345 是由 ADI(Analog Devices)公司研发生产的一款高性能三轴 MEMS(微机电系统)加速度传感器,它融合了先进的微机电技术和精密的电路设计,具有出色的性能和广泛的适用性。
- 该传感器的测量范围可灵活配置,包括 ±2g、±4g、±8g 和 ±16g(g 为重力加速度,1g 约等于 9.8m/s²),能够满足不同场景下对测量精度和范围的需求。在 ±2g 量程下,其分辨率高达 3.9mg/LSB(最低有效位),这意味着它可以检测到非常微小的加速度变化,为高精度测量提供了保障。
- 通信接口方面,ADXL345 支持 I2C 和 SPI 两种通信方式。其中,I2C 接口的最高速率可达 400kHz,SPI 接口的最高速率更是能达到 5MHz,能够快速与各种单片机、微处理器等进行数据传输,兼容主流的嵌入式系统。
- ADXL345 还内置了丰富的功能模块,包括自由落体检测、活动 / 静止检测、单击 / 双击检测等中断功能。这些功能可以通过寄存器配置来实现,当满足特定条件时,传感器会输出中断信号,从而减少微处理器的运算量和资源占用,提高系统的响应速度和效率。
- 从结构上看,ADXL345 采用小型 LGA 封装,尺寸仅为 3mm×5mm×1mm,非常适合在空间受限的设备中使用。它还内置了温度补偿电路,能够在 - 40℃至 85℃的宽温度范围内保持稳定的性能,确保在各种恶劣环境下都能准确测量。
- 此外,ADXL345 的输出数据速率可在 0.1Hz 至 3200Hz 之间灵活调整,用户可以根据实际应用需求,在响应速度和功耗之间进行平衡选择。无论是需要快速响应的动态测量场景,还是对功耗要求严格的长期监测任务,它都能很好地适应。
🎯 单片机连接硬件图





🌟 驱动思路
ADXL345 的驱动核心在于通过 I2C 或 SPI 通信接口与传感器进行数据交互,完成传感器的初始化配置、数据读取和处理等操作
步骤 1:硬件初始化
- 首先进行 I2C 接口的初始化。配置 STM32F103C8T6 的 I2C,设置通信速率为 400kHz,使能 I2C 外设。在初始化过程中,需要配置相关的 GPIO 引脚为复用功能,设置 I2C 的时钟频率、地址模式等参数,确保 I2C 通信能够正常进行。接着进行传感器的上电检测。通过 I2C 通信读取 ADXL345 的 DEVICE_ID 寄存器(地址 0x00),该寄存器的默认值为 0xE5。如果读取到的值与默认值一致,则说明传感器连接正常;否则,表明传感器连接存在问题,需要检查硬件连接。
步骤 2:传感器配置
- 传感器配置主要是通过写入相应的寄存器来设置传感器的工作参数。
- 配置 DATA_FORMAT 寄存器(地址 0x31)以确定测量量程。例如,写入 0x00 表示选择 ±2g 量程,0x01 表示 ±4g 量程,0x02 表示 ±8g 量程,0x03 表示 ±16g 量程,可根据实际应用需求进行选择。
- 配置 BW_RATE 寄存器(地址 0x2C)来设置数据输出速率。该寄存器的不同值对应不同的输出速率,如 0x0A 对应 100Hz,0x0E 对应 400Hz 等。输出速率的选择需要综合考虑测量的实时性和功耗,输出速率越高,实时性越好,但功耗也会相应增加。
- 配置 POWER_CTL 寄存器(地址 0x2D)来设置传感器的工作模式。写入 0x08 可使传感器进入测量模式,此时传感器开始进行加速度测量;写入 0x00 则进入待机模式,传感器停止测量,以降低功耗。
步骤 3:数据读取
- 通过 I2C 连续读取 6 个数据寄存器(地址 0x32 至 0x37),这些寄存器分别存储了 X 轴低 8 位、X 轴高 8 位、Y 轴低 8 位、Y 轴高 8 位、Z 轴低 8 位、Z 轴高 8 位的数据。将每个轴的高 8 位和低 8 位数据组合起来,形成 16 位有符号整数,即为该轴的原始加速度数据。
步骤 4:数据转换与处理
- 将读取到的 16 位原始数据通过计算传感器的倾斜角度,利用 X、Y、Z 轴的加速度分量与重力加速度的关系,通过三角函数计算出传感器与水平面的夹角,从而实现姿态识别功能。
🎯 单片机程序代码
main.c
#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"
#include "delay.h"
#include "bsp_usart.h"
#include "oled.h"
#include "IIC.h"
#include "ADXL345.h"
char OledBuff[512];
int main(void)
{
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2);
SysTick_Init(72); //系统时钟初始化
usart1_init(115200);//串口1初始化
usart2_init(115200);//串口1初始化
usart3_init(115200);//串口3初始化
printf("USART OK!\r\n");
OLED_Init();
float angleX, angleY, angleZ;
ADXL345_init();
delay_ms(100);
OLED_ShowString(0,2,"ADXL345初始化成功");
OLED_Clear();
OLED_ShowString(36,0,"ADXL345");
printf("初始化成功!\r\n");
while(1)
{
delay_ms(1000);
get_angle(&angleX, &angleY, &angleZ); // 获取三轴偏移角度
printf("angle X:%.6f Y:%.6f Z:%.6f\n", angleX, angleY, angleZ);
sprintf(OledBuff,"X:%.6f",angleX);
OLED_ShowString(0,2,OledBuff);
sprintf(OledBuff,"Y:%.6f",angleY);
OLED_ShowString(0,4,OledBuff);
sprintf(OledBuff,"Z:%.6f",angleZ);
OLED_ShowString(0,6,OledBuff);
}
}
ADXL345.c
/*
ADXL345三轴倾斜度模块
*/
#include "ADXL345.h"
#include "IIC.h"
#include "stm32f10x.h"
#include "math.h"
#include "delay.h"
/**
* @brief ADXL345初始化
* @param None
* @retval None
*/
uint8_t ADXL345_init(void)
{
IIC_GPIO_Init();
if(ADXL345_read_reg(DEVICE_ID) == 0xE5)
{
ADXL345_write_reg(DATA_FORMAT,0X0B); // 低电平中断输出,13位全分辨率,输出数据右对齐,16g量程
ADXL345_write_reg(BW_RATE,0x0E); // 数据输出速度为100Hz
ADXL345_write_reg(POWER_CTL,0x08); // 链接使能,测量模式,省电特性
ADXL345_write_reg(INT_ENABLE,0x80); // 不使用中断
ADXL345_write_reg(OFSX,0x00);
ADXL345_write_reg(OFSY,0x00);
ADXL345_write_reg(OFSZ,0x05);
return 0;
}
return 1;
}
/**
* @brief ADXL345写寄存器
* @param None
* @retval None
*/
uint8_t ADXL345_write_reg(u8 addr,u8 val)
{
IIC_Start();
IIC_Send_Byte(slaveaddress); // 发送写器件指令
if(IIC_Wait_Ack())
{
return 1;
}
IIC_Send_Byte(addr); // 发送寄存器地址
if(IIC_Wait_Ack())
{
return 2;
}
IIC_Send_Byte(val); // 发送值
if(IIC_Wait_Ack())
{
return 3;
}
IIC_Stop(); // 产生一个停止条件
return 0;
}
/**
* @brief ADXL345读寄存器
* @param None
* @retval None
*/
u8 ADXL345_read_reg(u8 addr)
{
u8 temp=0;
IIC_Start();
IIC_Send_Byte(slaveaddress); // 发送写器件指令
if(IIC_Wait_Ack())
{
return 1;
}
IIC_Send_Byte(addr); // 发送寄存器地址
if(IIC_Wait_Ack())
{
return 2;
}
IIC_Start(); // 重新启动
IIC_Send_Byte(regaddress); // 发送读器件指令
if(IIC_Wait_Ack())
{
return 3;
}
temp=IIC_Read_Byte(0); // 读取一个字节,不继续再读,发送NAK
IIC_Stop(); // 产生一个停止条件
return temp;
}
/**
* @brief ADXL345读取数据
* @param None
* @retval None
*/
void ADXL345_read_data(short *x,short *y,short *z)
{
u8 buf[6];
u8 i;
IIC_Start();
IIC_Send_Byte(slaveaddress); // 发送写器件指令
IIC_Wait_Ack();
IIC_Send_Byte(0x32); // 发送寄存器地址(数据缓存的起始地址为0X32)
IIC_Wait_Ack();
IIC_Start(); // 重新启动
IIC_Send_Byte(regaddress); // 发送读器件指令
IIC_Wait_Ack();
for(i=0;i<6;i++)
{
if(i==5)buf[i]=IIC_Read_Byte(0); // 读取一个字节,不继续再读,发送NACK
else buf[i]=IIC_Read_Byte(1); // 读取一个字节,继续读,发送ACK
}
IIC_Stop(); // 产生一个停止条件
*x=(short)(((u16)buf[1]<<8)+buf[0]); // 合成数据
*y=(short)(((u16)buf[3]<<8)+buf[2]);
*z=(short)(((u16)buf[5]<<8)+buf[4]);
}
/**
* @brief ADXL345连读读取几次取平均值
* @param None
* @retval None
*/
void ADXL345_read_average(short *x,short *y,short *z,u8 times)
{
u8 i;
short tx,ty,tz;
*x=0;
*y=0;
*z=0;
if(times)//读取次数不为0
{
for(i=0;i<times;i++)//连续读取times次
{
ADXL345_read_data(&tx,&ty,&tz);
*x+=tx;
*y+=ty;
*z+=tz;
delay_ms(5);
}
*x/=times;
*y/=times;
*z/=times;
}
}
/**
* @brief ADXL345计算角度
* @param None
* @retval None
*/
void get_angle(float *x_angle,float *y_angle,float *z_angle)
{
short ax,ay,az;
ADXL345_read_average(&ax,&ay,&az,10);
*x_angle=atan(ax/sqrt((az*az+ay*ay)))*180/3.14;
*y_angle=atan(ay/sqrt((ax*ax+az*az)))*180/3.14;
*z_angle=atan(sqrt((ax*ax+ay*ay)/az))*180/3.14;
}
🎯 代码下载链接
https://download.csdn.net/download/qq_41954594/92122007
786

被折叠的 条评论
为什么被折叠?



