加速度计与陀螺仪的驱动和数据处理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
由于SCA3000和ADIS16255的SPI时序有些差异,因此只能采取模拟SPI的方式进行通讯。本驱动,下载后可以根据MCU具体的引脚定义进行修改。16255需要进行设置以后,偏差小了很多。SCA3000基本上不需要进行参数设置。
附图1,陀螺数据处理后对比图片:
上部分(绿色)曲线为以陀螺仪数据变化量为纵向刻度,离中线最近的开始,依次为1次平均值滤波,2次平均值滤波,3次平均值滤波,4次平均值滤波。
中间部分为陀螺仪原值曲线,底部部分(红色)为多次平均值滤波后的陀螺仪数据值。
左转弯后再右转弯回到原来方向,不超过5度
附图2,陀螺数据处理图片:
多次转弯图,不超过5度
/********************************************************************
SPI.H
********************************************************************/
#ifndef __SPI0_H__
#define __SPI0_H__
#include
#include
#define SPI0_CLK (1<<1) //定义SPI时钟脚
#define SPI0_MISO (1<<2) //定义SPI从件输出脚
#define SPI0_MOSI (1<<3) //定义SPI从件输入脚
/// SPI Control Register (S0SPCR - 0xE0020000)
#define CPHA 3
#define CPOL 4
#define MSTR 5
#define LSBF 6
#define SPIE 7
/// SPI Status Register (S0SPSR - 0xE0020004)
#define ABRT 3
#define MODF 4
#define ROVR 5
#define VCOL 6
#define SPIF 7 // SPI transfer complete flag.
#define SPISetCLK() (IOSET0 |= SPI0_CLK)
#define SPIClearCLK() (IOCLR0 |= SPI0_CLK)
#define SPIWriteBit(Data) {if(Data) IOSET0 |= SPI0_MOSI; else IOCLR0 |= SPI0_MOSI;}
#define SPIReadBit() (0 < (int)(((unsigned long)SPI0_MISO) & IOPIN0))
void SetIdleSPI(void);
void WaitIdleSPI(void);
void SPIInit(void);
#endif
/********************************************************************
SPI.C
********************************************************************/
#include "SPI.h"
int IsBusySPI = 0;
void WaitIdleSPI(void)
{
while(IsBusySPI)//等待空闲
os_dly_wait(1);//OS不同,可以修改此句
IsBusySPI = 1;//获得设置忙标志
}
void SetIdleSPI(void)
{
IsBusySPI = 0;
}
/*void SPIDelayNS(int Time)
{
//一个时钟周期约为18ns(主频:11.0592 * 5),一条指令按一个时钟周期算
//本循环大约有8个指令,一指令占一个时钟周期来算
Time = (Time / 18) - 4;//进入循环前,使用了4条指令
while(Time > 0)//判断到退出使用2条指令,因此超过 18 × 6 纳秒的时间本函数方可有效,
Time -= 4; // 每个循环使用4条指令
}*/
void SPIInit(void)
{
//设置SPI总线引脚输入输出模式
PINSEL0 &= 0xFF;
//设置引脚输入输出方向
IODIR0 &= ~((unsigned long)SPI0_MISO); //从件输出脚
IODIR0 |= (SPI0_CLK | SPI0_MOSI); //从件输入脚
SPISetCLK();
}
/*******
*************************************************************
GRRO.C
GYRO.h引用SPI.h
********************************************************************/
#include "GYRO.h"
//定义陀螺仪片选引脚
#define GYRO_PIN (1 << 1)
#define GYRO_CS() IOCLR1 = GYRO_PIN
#define GYRO_UNCS() IOSET1 = GYRO_PIN
#define DelayTCLKH() {NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();NOP();}
unsigned short GYROReadWrite16Bit(unsigned short Data)
{
int i;
WaitIdleSPI();
//IntLock(); 关闭中断源
PINSEL0 &= ~0x0000ff00; // config P0.7~P0.4 as GPIO
IODIR1 |= GYRO_PIN;
IODIR0 &= ~((unsigned long)SPI0_MISO);
IODIR0 |= (SPI0_CLK|SPI0_MOSI);
SPISetCLK();
GYRO_CS();
DelayTCLKH();
for( i = 0; i < 16; i++)
{
SPIClearCLK();
//DelayTCLKL();
DelayTCLKH();
SPIWriteBit(Data & 0x8000);
Data <<= 1;
Data |= SPIReadBit();
SPISetCLK();
//DelayTCLKH();
DelayTCLKH();
}
SPISetCLK();
GYRO_UNCS();
IntUnlock(); //打开中断源
SetIdleSPI();
return(Data);
}
unsigned short GYRORead(int Addr)
{
GYROReadWrite16Bit(Addr << 8);
return(GYROReadWrite16Bit(0));
}
void GYROWrite(int Addr, int Data)
{
unsigned short AddrData;
///////////////////////////////////
Addr &= 0x3f;
Addr |= 0x80; //写标志
///////////////////////////////////
AddrData = Addr;
AddrData <<= 8;
AddrData |= Data;
GYROReadWrite16Bit(AddrData);
}
void GYROInit(void)
{
PINSEL1 &= ~GYRO_PIN;//设置引脚模式
IODIR1 |= GYRO_PIN;//设置引脚方向
GYRO_UNCS();
}
/******************************************************************** Accel.C Accel.h引用SPI.h********************************************************************/
include "Accel.h"
//定义加速度计片选引脚
#define ACCEL_PIN (1 << 1)
#define ACCEL_CS() IOCLR1 = ACCEL_PIN
#define ACCEL_UNCS() IOSET1 = ACCEL_PIN
void DoAccelWrite8Bit(unsigned long Data)
{
int i;
for( i = 0; i < 8; i++)
{
SPIWriteBit(Data & 0x80);
Data <<= 1;
SPISetCLK();
SPIClearCLK();
}
}
void DoAccelWrite16Bit(unsigned long Data)
{
int i;
for( i = 0; i < 16; i++)
{
SPIWriteBit(Data & 0x8000);
Data <<= 1;
SPISetCLK();
SPIClearCLK();
}
}
unsigned long DoAccelRead8Bit(void)
{
int i;
unsigned long Data = 0;
for( i = 0; i < 8; i++)
{
Data <<= 1;
SPISetCLK();
Data |= SPIReadBit();
SPIClearCLK();
}
return Data;
}
unsigned long DoAccelRead16Bit(void)
{
int i;
unsigned long Data = 0;
for( i = 0; i < 16; i++)
{
Data <<= 1;
SPISetCLK();
Data |= SPIReadBit();
SPIClearCLK();
}
return Data;
}
unsigned long AccelRead8Bit(unsigned long Addr)
{
unsigned long Data = 0;
WaitIdleSPI();
SPIClearCLK();
ACCEL_CS();
DoAccelWrite8Bit(Addr << 2);
Data = DoAccelRead8Bit();
ACCEL_UNCS();
SetIdleSPI();
return(Data);
}
unsigned long AccelRead16Bit(unsigned long Addr)
{
unsigned long Data = 0;
WaitIdleSPI();
SPIClearCLK();
ACCEL_CS();
DoAccelWrite8Bit(Addr << 2);
Data = DoAccelRead16Bit();
ACCEL_UNCS();
SetIdleSPI();
return(Data);
}
void AccelWrite8Bit(unsigned long Addr, unsigned long Data)
{
Addr <<= 10;
Addr |= 0x0200;
Addr |= Data;
WaitIdleSPI();
SPIClearCLK();
ACCEL_CS();
DoAccelWrite16Bit(Addr);
ACCEL_UNCS();
SetIdleSPI();
}
void AccelInit(void)
{
PINSEL1 &= ~ACCEL_PIN; //设置引脚模式
IODIR1 |= ACCEL_PIN; //设置引脚方向
ACCEL_UNCS();
}