SC7A20三轴加速度传感器驱动教程

使用的时候需要找对文档,之前文档不对,导致读取的数据计算角度一直不成功,发现要关闭高通滤波,由于高通滤波寄存器里面的滤波阈值没有文档说明,我直接关闭掉就可以使用了,代码与硬件平台无关,需要底层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;
}

 

/*************************************************************************************************************
 * 文件名:			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);
	}

}	

 

 

 

物联沃分享整理
物联沃-IOTWORD物联网 » SC7A20三轴加速度传感器驱动教程

发表评论