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);
	}

}	

 

 

 

### 回答1: CentOS 7上启动httpd服务失败可能有多种原因,以下是一些常见的解决方法: 1. 检查httpd配置文件是否正确:可以使用命令`httpd -t`检查httpd配置文件是否正确,如果有错误,需要修改配置文件。 2. 检查端口是否被占用:可以使用命令`netstat -tlnp`查看端口是否被占用,如果被占用需要释放端口或修改httpd配置文件中的端口号。 3. 检查httpd服务是否安装:可以使用命令`rpm -qa | grep httpd`查看httpd服务是否安装,如果没有安装需要先安装httpd服务。 4. 检查httpd服务是否启动:可以使用命令`systemctl status httpd`查看httpd服务是否启动,如果没有启动需要使用命令`systemctl start httpd`启动httpd服务。 5. 检查SELinux是否开启:如果SELinux开启,可能会导致httpd服务启动失败,需要使用命令`setenforce 0`关闭SELinux,或者修改SELinux策略。 以上是一些常见的解决方法,如果以上方法都无法解决问题,可以查看httpd服务日志文件,找到具体的错误信息,然后根据错误信息进行解决。 ### 回答2: CentOS 7上的httpd服务启动失败可能有多种原因。以下列出了一些常见问题和解决方法: 1. 端口被占用 当httpd试图占用已被其他程序占用的端口时会启动失败。此时可以通过使用`netstat -tunlp`命令检查端口占用情况,然后杀死占用该端口的进程及时释放端口。或者修改httpd的配置文件,将端口修改为未被占用的端口。 2. 配置文件错误 有时httpd服务的配置文件中可能出现错误,例如语法错误或路径错误等等。在启动httpd服务之前,可以使用`apachectl configtest`命令进行检查,如果输出“Syntax OK”,则表示配置文件没有错误。如果出现错误,则需要根据错误提示进行相应修改。 3. 依赖关系问题 如果httpd依赖的其他程序或库缺失,也会导致启动失败。可以通过使用`systemctl status httpd.service`命令来查看httpd服务状态,如果输出“Failed to start”或“Loaded: failed”,则需要检查依赖关系是否完整。 4. SELinux问题 当SELinux启用时,有时会导致httpd服务启动失败。在这种情况下,可以在SELinux上禁用httpd服务,或者修改httpd配置文件解决SELinux相关的问题。 5. 用户权限问题 httpd服务的启动可能需要特定的用户权限。如果使用的用户权限不够,则无法启动。可以尝试使用root用户启动httpd服务,或者根据需要修改相应的用户权限。 ### 回答3: CentOS 7中的Apache HTTP服务器(httpd)是一个常见的Web服务器,如果遇到httpd服务启动失败的情况,可能会影响服务器正常的工作和对外服务的稳定性。本文将提供一些可能会导致httpd服务启动失败的原因,并给出相应的解决方法。 1. 端口被占用 如果端口被其他进程占用,httpd服务就无法启动。可以通过 netstat -tulpn 命令查看端口占用情况,并杀死占用该端口的进程。如果端口被 httpd 服务自身占用,可以通过 systemctl restart httpd 命令重启 httpd 服务;如果是其他进程占用了端口,可以通过 kill 命令杀死该进程或更改 httpd.conf 文件配置,将 httpd 服务的端口改为其他空闲端口,重新启动。 2. 配置文件错误 httpd 服务的配置文件通常是 /etc/httpd/conf/httpd.conf,如果其中存在语法错误、权限问题或者其它配置错误,可能会导致 httpd 服务启动出错。可以通过将 httpd.conf 文件备份后删掉,重新执行 yum install httpd 命令安装 httpd 服务,然后手动修改 httpd.conf 文件,逐个检查每个配置项是否正确,确认无误后重启 httpd 服务。 3. SELinux 问题 SELinux 是 CentOS 7中提供的一种安全模块,它可以对系统文件和应用程序进行安全管控。如果 SELinux 配置不正确,可能会阻止 httpd 服务正常启动。可以通过修改 /etc/selinux/config 文件中 SELINUX=disabled 来暂时关闭 SELinux,然后重新启动 httpd 服务;或者一个更优的方式是,根据日志确定问题原因,使用命令 semanage 或者 setsebool 等工具将相关目录或者配置加入到 SELinux 许可列表中,重新启动 httpd 服务,以恢复服务正常工作。 4. 防火墙问题 如果你的 CentOs 7 服务器启用了防火墙,有可能会导致 httpd 服务启动失败。可以通过检查防火墙相关配置来确定问题原因,解决方案是修改防火墙规则,将端口 80 或者 443 等 httpd 服务需要的端口放行,重新启动 httpd 服务。 总之,当遇到 httpd 服务启动失败时,不要慌张,可以先通过日志或者执行命令查看错误信息,找到错误原因,然后根据错误原因一步一步解决问题。在解决问题过程中注意备份原始配置文件,以免造成不必要的损失。
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cp1300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值