使用的时候需要找对文档,之前文档不对,导致读取的数据计算角度一直不成功,发现要关闭高通滤波,由于高通滤波寄存器里面的滤波阈值没有文档说明,我直接关闭掉就可以使用了,代码与硬件平台无关,需要底层IIC接口支持,软件IIC或HC32的硬件IIC可以查阅我其他博客;
连续读取的时候,需要将寄存器地址最高位置1;
/*************************************************************************************************************
* 文件名: SC7A20.c
* 功能: SC7A20 三轴加速度传感器支持
* 作者: cp1300@139.com
* 创建时间: 2022-07-01
* 最后修改时间: 2022-07-01
* 详细: https://www.doc88.com/p-80659792307153.html?r=1
* 如果想一次读写多个寄存器,需要将寄存器地址最高位置1,也就是寄存器地址|0x80
*************************************************************************************************************/
#include "system.h"
#include "SC7A20.h"
#include "math.h"
#include <stdio.h>
#define SC7A20_REG_WHO_AM_I 0x0F
#define SC7A20_REG_CTRL_1 0x20
#define SC7A20_REG_CTRL_2 0x21
#define SC7A20_REG_CTRL_3 0x22
#define SC7A20_REG_CTRL_4 0x23
#define SC7A20_REG_X_L 0x28
#define SC7A20_REG_X_H 0x29
#define SC7A20_REG_Y_L 0x2A
#define SC7A20_REG_Y_H 0x2B
#define SC7A20_REG_Z_L 0x2C
#define SC7A20_REG_Z_H 0x2D
#define SC7A20_REG_STATUS 0x27
/*************************************************************************************************************************
*函数 : bool SC7A20_Init(SC7A20_HANDLE *pHandle, u8 SlaveAddr,
bool (*IIC_ReadReg)(u8 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum),
bool (*IIC_WriteReg)(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum))
*功能 : SC7A20初始化
*参数 : pHandle:句柄;SlaveAddr:芯片IIC写地址;IIC_ReadReg:IIC读取接口;IIC_WriteReg:IIC写入接口;
*返回 : TRUE:初始化成功;FALSE:初始化失败
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2022-07-01
*最后修改时间 : 2022-07-01
*说明 :
*************************************************************************************************************************/
bool SC7A20_Init(SC7A20_HANDLE *pHandle, u8 SlaveAddr,
bool (*IIC_ReadReg)(u8 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum),
bool (*IIC_WriteReg)(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum))
{
u16 i,j;
u8 tempreg;
u8 buff[16];
if(pHandle == NULL)
{
ERROR_S("无效的句柄\r\n");
SYS_DelayMS(5000);
return FALSE;
}
pHandle->SlaveAddr = SlaveAddr; //记录地址
pHandle->IIC_ReadReg = IIC_ReadReg; //IIC接口
pHandle->IIC_WriteReg = IIC_WriteReg; //IIC接口
tempreg = 0;
Delay_MS(50);
for (i = 0; i < 10; i++)
{
buff[0] = buff[1] = 0;
if (pHandle->IIC_ReadReg(pHandle->SlaveAddr, SC7A20_REG_WHO_AM_I, buff, 1) == FALSE)
{
INFO_S("Sensor通讯失败\r\n");
}
else if(buff[0] == 0x11)
{
break;
}
else
{
INFO_S("无效的id0x%02X\r\n", buff[0]);
}
SYS_DelayMS(100);
}
tempreg = 0x47;
pHandle->IIC_WriteReg(pHandle->SlaveAddr, SC7A20_REG_CTRL_1, &tempreg, 1);//50Hz+正常模式xyz使能
tempreg = 0x00;
pHandle->IIC_WriteReg(pHandle->SlaveAddr, SC7A20_REG_CTRL_2, &tempreg, 1);//关闭滤波器,手册上面没有滤波器截止频率设置说明,开启后无法测量静止状态下的重力加速度
tempreg = 0x00;
pHandle->IIC_WriteReg(pHandle->SlaveAddr, SC7A20_REG_CTRL_3, &tempreg, 1); //关闭中断
tempreg = 0x88;
pHandle->IIC_WriteReg(pHandle->SlaveAddr, SC7A20_REG_CTRL_4, &tempreg, 1); //读取完成再更新,小端模式,、2g+正常模式,高精度模式
if (i < 10) return TRUE;
return FALSE;
}
s16 SC7A20_12bitComplement(uint8_t msb, uint8_t lsb)
{
s16 temp;
temp = msb << 8 | lsb;
temp = temp >> 4; //只有高12位有效
temp = temp & 0x0fff;
if (temp & 0x0800) //负数 补码==>原码
{
temp = temp & 0x07ff; //屏弊最高位
temp = ~temp;
temp = temp + 1;
temp = temp & 0x07ff;
temp = -temp; //还原最高位
}
return temp;
}
/*************************************************************************************************************************
*函数 : bool SC7A20_ReadAcceleration(SC7A20_HANDLE* pHandle, s16* pXa, s16* pYa, s16* pZa)
*功能 : SC7A20读取加速度值
*参数 : pHandle:句柄;pXa,pYa,pZa 三轴加速度值
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2022-07-01
*最后修改时间 : 2022-07-01
*说明 :
*************************************************************************************************************************/
bool SC7A20_ReadAcceleration(SC7A20_HANDLE* pHandle, s16* pXa, s16* pYa, s16* pZa)
{
u8 buff[6];
u8 i;
s16 temp;
memset(buff, 0, 6);
if (pHandle->IIC_ReadReg(pHandle->SlaveAddr, SC7A20_REG_X_L|BIT7, buff, 6) == FALSE)
{
return FALSE;
}
else
{
pHandle->IIC_ReadReg(pHandle->SlaveAddr, 0x27, &i, 1);
/*for (i = 0; i < 6; i++)
{
uart_printf("%02X ",buff[i]);
}
uart_printf("r\n");*/
//X轴
*pXa = buff[1];
*pXa <<= 8;
*pXa |= buff[0];
*pXa >>= 4; //取12bit精度
//Y轴
*pYa = buff[3];
*pYa <<= 8;
*pYa |= buff[2];
*pYa >>= 4; //取12bit精度
//Z轴
*pZa = buff[5];
*pZa <<= 8;
*pZa |= buff[4];
*pZa >>= 4; //取12bit精度
return TRUE;
}
}
#define PI 3.1415926535898
/*************************************************************************************************************************
*函数 : bool SC7A20_GetZAxisAngle(SC7A20_HANDLE* pHandle, s16 AcceBuff[3], float* pAngleZ)
*功能 : SC7A20 获取Z轴倾角
*参数 : pHandle:句柄;AcceBuff:3个轴的加速度;pAngleZ:Z方向倾角
*返回 : TRUE:成功;FALSE:失败
*依赖 : 底层宏定义
*作者 : cp1300@139.com
*时间 : 2022-07-02
*最后修改时间 : 2022-07-02
*说明 :
*************************************************************************************************************************/
bool SC7A20_GetZAxisAngle(SC7A20_HANDLE* pHandle, s16 AcceBuff[3], float* pAngleZ)
{
double fx, fy, fz;
double A;
s16 Xa, Ya, Za;
if (SC7A20_ReadAcceleration(pHandle, &Xa, &Ya, &Za) == FALSE) return FALSE; //ADXL362 读取加速度数据
//uart_printf("Xa:%d \tYa:%d \tZa:%d \r\n",Xa,Ya,Za);
AcceBuff[0] = Xa; //x轴加速度
AcceBuff[1] = Ya; //y轴加速度
AcceBuff[2] = Za; //z轴加速度
fx = Xa;
fx *= 2.0 / 4096;
fy = Ya;
fy *= 2.0 / 4096;
fz = Za;
fz *= 2.0 / 4096;
//uart_printf("fx:%.04f\tfy:%.04f\tfz:%.04f\t\r\n",fx,fy,fz);
//Z方向
A = fx * fx + fy * fy;
A = sqrt(A);
A = (double)A / fz;
A = atan(A);
A = A * 180 / PI;
*pAngleZ = A;
uart_printf("=======角度:%.04f\r\n",*pAngleZ);
return TRUE;
}
文章来源地址https://www.toymoban.com/news/detail-516406.html
/*************************************************************************************************************
* 文件名: SC7A20.h
* 功能: SC7A20 三轴加速度传感器支持
* 作者: cp1300@139.com
* 创建时间: 2022-07-01
* 最后修改时间: 2022-07-01
* 详细:
*************************************************************************************************************/
#ifndef _SC7A20_H_
#define _SC7A20_H_
#include "system.h"
//SC7A20 句柄
typedef struct
{
bool (*IIC_ReadReg)(u8 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum); //IIC读取寄存器接口
bool (*IIC_WriteReg)(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum); //IIC写入寄存器接口
u8 SlaveAddr;
u8 ModeConfigData; //记录模式配置值
}SC7A20_HANDLE;
//SC7A20初始化
bool SC7A20_Init(SC7A20_HANDLE *pHandle, u8 SlaveAddr,
bool (*IIC_ReadReg)(u8 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum),
bool (*IIC_WriteReg)(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum));
bool SC7A20_ReadAcceleration(SC7A20_HANDLE* pHandle, s16* pXa, s16* pYa, s16* pZa);//SC7A20读取加速度值
bool SC7A20_GetZAxisAngle(SC7A20_HANDLE* pHandle, s16 AcceBuff[3], float* pAngleZ);//SC7A20 获取Z轴倾角
#endif /*_SC7A20_H_*/
测试代码
/*************************************************************************************************************
* 文件名: SC7A20_Test.c
* 功能: SC7A20测试
* 作者: cp1300@139.com
* 创建时间: 2022-07-01
* 最后修改时间: 2022-07-01
* 详细:
*************************************************************************************************************/
#include "system.h"
#include "hc32f46x_system.h"
#include "test.h"
#include "SoftwareIIC.h"
#include "board.h"
#include "SC7A20.h"
static SC7A20_HANDLE sg_Temp_SC7A20_Handle;
//读取寄存器接口
static bool SC7A20_IIC_ReadReg(u8 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum)
{
if (IIC_MasterReadReg(SC7A20_IIC_CH, SlaveAddr, RegAddr, TRUE, pDataBuff, ByteNum) != IIC_OK) return FALSE;
else return TRUE;
}
//写寄存器接口
static bool SC7A20_IIC_WriteReg(u16 SlaveAddr, u8 RegAddr, u8 *pDataBuff, u16 ByteNum)
{
if (IIC_MasterWriteReg(SC7A20_IIC_CH, SlaveAddr, RegAddr, TRUE, pDataBuff, ByteNum) != IIC_OK) return FALSE;
else return TRUE;
}
//SC7A20测试
void SC7A20_Test(void)
{
u8 buff[7];
s16 acc[3];
float zAngle;
SC7A20_IO_Init();
IIC_Init(SC7A20_IIC_CH, 300, 100);//硬件IIC初始化
//SC7A20初始化
SC7A20_Init(&sg_Temp_SC7A20_Handle, SC7A20_ADDR, SC7A20_IIC_ReadReg, SC7A20_IIC_WriteReg);
while (1)
{
if (FALSE == SC7A20_GetZAxisAngle(&sg_Temp_SC7A20_Handle, acc, &zAngle))//SC7A20读取加速度值
{
INFO_S("加速度数据读取失败\r\n");
}
else
{
INFO_S("Z:%f\r\n", zAngle);
}
SYS_DelayMS(500);
}
}
文章来源:https://www.toymoban.com/news/detail-516406.html
到了这里,关于SC7A20 三轴加速度传感器 驱动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!