原文地址::SC7A20获取三轴加速度值_sc7a20敲击_QDDA的博客-CSDN博客
SC7A20获取三轴加速度值(I2C)
1. I2C.h
#ifndef __I2C_H
#define __I2C_H
#include "config.h"
sbit I2C_SCL=P3^2;//SCL
sbit I2C_SDA=P3^3;//SDA
#define I2C_SCL_Clr() I2C_SCL=0
#define I2C_SCL_Set() I2C_SCL=1
#define I2C_SDA_Clr() I2C_SDA=0
#define I2C_SDA_Set() I2C_SDA=1
//void Wait();
void Start();
void SendData(char dat);
void RecvACK();
char RecvData(u8 SF_Ack);
void SendACK();
void SendNAK();
void Stop();
#endif
2. I2C.c (IO口模拟I2C)
#include "I2C.h"
//延时
void I2C_delay(void)
{
u8 t=1;
while(t--);
}
void Start()
{
I2C_SDA_Set();
I2C_SCL_Set();
I2C_delay();
I2C_SDA_Clr();
I2C_delay();
I2C_SCL_Clr();
}
//========================================================================
// 函数: void SendData (char dat)
// 描述: I2C发送一个字节数据函数.
// 参数: 发送的数据.
// 返回: none.
//========================================================================
void SendData(u8 dat)
{
u8 i;
for(i=0;i<8;i++)
{
I2C_SCL_Clr();//将时钟信号设置为低电平
if(dat&0x80)//将dat的8位从最高位依次写入
{
I2C_SDA_Set();
}
else
{
I2C_SDA_Clr();
}
I2C_delay();
I2C_SCL_Set();
I2C_delay();
I2C_SCL_Clr();
dat<<=1;
}
}
//========================================================================
// 函数: void RecvACK (void)
// 描述: I2C获取ACK函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void RecvACK()
{
I2C_SDA_Set();
I2C_delay();
I2C_SCL_Set();
I2C_delay();
I2C_SCL_Clr();
I2C_delay();
}
//========================================================================
// 函数: char RecvData (void)
// 描述: I2C读取一个字节数据函数.
// 参数: none.
// 返回: 读取数据.
// 版本: V1.0, 2020-09-15
//========================================================================
char RecvData(u8 SF_Ack)
{
u8 Rb_Cnt = 0; //读数据位计数
u8 RByte = 0; //读字节
//I2C_SDA_Dir(0);//SDA设置为输入
for(Rb_Cnt=0; Rb_Cnt<8; Rb_Cnt++)
{
I2C_SCL_Clr(); //拉低时钟线 准备开始传送数据位
I2C_delay();
I2C_SCL_Set(); //拉高时钟线
RByte <<= 1; //数据移位
if(I2C_SDA)
{
RByte++;
}
I2C_delay();
}
if(!SF_Ack) //0 不发送Ack
{
SendNAK(); //发送NAck
}
else //1 发送Ack
{
SendACK(); //发送Ack
}
return RByte;
}
//========================================================================
// 函数: void SendACK (void)
// 描述: I2C发送ACK函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void SendACK()
{
I2C_SCL_Clr(); //拉低时钟线
// I2C_SDA_Dir(1);//I2C_SDA线输出
I2C_SDA_Clr(); //拉低数据线
I2C_delay();;
I2C_SCL_Set(); //拉高时钟线
I2C_delay();;
I2C_SCL_Clr(); //拉低时钟线
}
//========================================================================
// 函数: void SendNAK (void)
// 描述: I2C发送NAK函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void SendNAK()
{
I2C_SCL_Clr(); //拉低时钟线
// I2C_SDA_Dir(1);//I2C_SDA线输出
I2C_SCL_Set(); //拉高数据线
I2C_delay();;
I2C_SCL_Set(); //拉高时钟线
I2C_delay();;
I2C_SCL_Clr(); //拉低时钟线
}
//========================================================================
// 函数: void Stop (void)
// 描述: I2C总线停止函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-15
//========================================================================
void Stop()
{
I2C_SDA_Clr();
I2C_SCL_Set();
I2C_delay();
I2C_SDA_Set();
}
3. SC7A20.h
#ifndef __SC7A20_H
#define __SC7A20_H
#include "config.h"
#include "delay.h"
#define SC7A20_I2C_WADDR 0x30 //I2C写地址:7位I2C地址+一位写
#define SC7A20_I2C_RADDR 0x31 //I2C写地址:7位I2C地址+一位读
void SC7A20_Init();
#endif
4. SC7A20.c
#include "SC7A20.h"
#include "I2C.h"
#include "stdio.h" //使用printf打印数据到串口
/*
SC7A20向寄存器写一个字节
RAddr:寄存器地址
WData:数据
*/
void SC7A20_Write_Byte(u8 RAddr, u8 WData)
{
Start();
SendData(SC7A20_I2C_WADDR);
RecvACK();
SendData(RAddr);
RecvACK();
SendData(WData);
RecvACK();
Stop();
}
/*
SC7A20从寄存器读一个字节
RAddr:寄存器地址
RData:接收数据地址
*/
void SC7A20_Read_Byte(u8 RAddr, u8 *RData)
{
Start();
SendData(SC7A20_I2C_WADDR);
RecvACK();
SendData(RAddr);
RecvACK();
Start();
SendData(SC7A20_I2C_RADDR);
RecvACK();
*RData = RecvData(0);
Stop();
}
/*
SC7A20初始化
*/
void SC7A20_Init()
{
SC7A20_Write_Byte(0x20,0x77); //400Hz+正常模式xyz使能
SC7A20_Write_Byte(0x21,0x88); //高通滤波:正常模式,00+滤波使能
SC7A20_Write_Byte(0x23,0x88); //读取完成再更新、2g+正常模式
}
/*
SC7A20获取加速度值
accd_lsb:加速度值低寄存器地址
accd_msb:加速度值高寄存器地址
返回值accd_f:加速度值,单位mg
*/
int SC7A20_Get_ACCD(u8 accd_lsb,u8 accd_msb)
{
u8 accd_l,accd_m = 0;
unsigned int temp;
int accd;
SC7A20_Read_Byte(accd_lsb,&accd_l);
SC7A20_Read_Byte(accd_msb,&accd_m);
temp &= 0x0000;
temp |= accd_m;
temp <<= 8;
temp &= 0xff00;
temp |= accd_l;
if(temp&0x8000)
{
temp >>= 4;
temp |= 0xf000;
}
else
{
temp >>= 4;
temp &= 0x0fff;
}
accd = temp*1;
return accd;
}
/*
SC7A20获取xyz轴加速度值
*/
void SC7A20_GetInfo()
{
//获取三轴数据
int x,y,z = 0;
unsigned char i = 16;
for(i=8;i>0;i--)
{
x += SC7A20_Get_ACCD(0x28,0x29);
y += SC7A20_Get_ACCD(0x2A,0x2B);
z += SC7A20_Get_ACCD(0x2C,0x2D);
}
x /= 8;
y /= 8;
z /= 8;
printf("x:%hd mg, y:%hd mg, z:%hd mg \r\n",x,y,z);
}
————————————————
版权声明:本文为CSDN博主「QDDA」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43538613/article/details/118901748