Bootstrap

SC7A20获取三轴加速度值

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