打印
[方案相关]

SC7A20 三轴加速度传感器 驱动

[复制链接]
49|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2025-1-22 08:53 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
使用的时候需要找对文档,之前文档不对,导致读取的数据计算角度一直不成功,发现要关闭高通滤波,由于高通滤波寄存器里面的滤波阈值没有文档说明,我直接关闭掉就可以使用了,代码与硬件平台无关,需要底层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);
                       
                }
                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);
        }

}       








————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/cp1300/article/details/125605735

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2086

主题

16068

帖子

15

粉丝