手头有个ADIS16465,没事做了个两轮车,从网上down了段代码,对照数据手册后发现代码有bug,自己修改了下,把驱动部分贴出来,采用硬件SPI
原理图部分:
主要代码,使用时先imuInit(),然后用burstRead连续读取主要使用部分数据,要读其他寄存器数据用普通读即可,请自行查阅数据手册,请注意SPI速度不能太高 ,具体请仔细看手册。
#define ADI_RST PORTB_PB6
#define ADI_CS PTS_PTS7
void spiInit(void)
{
MODRR = 0;
SPI0CR1 = 0x5E;//SPI0CR1_SPE | SPI0CR1_MSTR | SPI0CR1_CPHA | SPI0CR1_CPOL | SPI0CR1_SSOE; // master mode
SPI0CR2 = 0x50;// SPI0CR2_MODFEN;// | SPI0CR2_XFRW; // 16bit
// SPI0BR = 0x22; //SPI0BR_SPPR2 | SPI0BR_SPR1; // (0x22)1.33M (0x42)800 Kbit/s (0x08)1M for busclock 32m
SPI0BR = 0x62; //SPI0BR_SPPR2 | SPI0BR_SPR1; // (0x23)892K for busclock 50M
}
void burstRead(int *buf)
{
unsigned char i = 0;
ADI_CS = 0;
while(!SPI0SR_SPTEF);
SPI0DR = GLOB_CMD;
while(!SPI0SR_SPIF);
i = SPI0DRL;
for(i=0; i<10; i++)
{
while(!SPI0SR_SPTEF);
SPI0DR = 0x0000;
while(!SPI0SR_SPIF);
*buf++ = SPI0DR;
}
ADI_CS = 1;
}
unsigned int spiReadReg(unsigned int address)
{
unsigned int data;
ADI_CS = 0;
while(!SPI0SR_SPTEF);
SPI0DR = address;
while(!SPI0SR_SPIF);
data = SPI0DR;
ADI_CS = 1;
return data;
}
void spiWriteReg(unsigned char address,unsigned char data)
{
unsigned int value;
value = address | 0x80;
value <<= 8;
value |= data;
ADI_CS = 0;
while(!SPI0SR_SPTEF);
SPI0DR = value;
while(!SPI0SR_SPIF);
value = SPI0DR;
ADI_CS = 1;
_delay_us(63);
}
unsigned char adiReadID(void)
{
if(0x4051 != spiReadReg(PROD_ID))
return 0;
else
return 1;
}
void globalCommands(unsigned char data)
{
spiWriteReg(GLOB_CMD_L,data);
spiWriteReg(GLOB_CMD_H,0x00);
}
void imuInit(void)
{
unsigned int data = 0;
_delay_ms(250);
for(;;)
{
spiWriteReg(NULL_CNFG_L,0x0A); // 启动加速度计偏差校准
spiWriteReg(NULL_CNFG_H,0x3F);
data = spiReadReg(NULL_CNF);
_delay_us(50);
data = spiReadReg(NULL_CNF);
if(0x3F0A == data)
break;
_delay_us(200);
}
for(;;)
{
spiWriteReg(DEC_RATE_L, 0x09); // 配置采集速率为200Hz,即5ms读取一次
spiWriteReg(DEC_RATE_H, 0x00);
data = spiReadReg(DEC_RATE);
_delay_us(50);
data = spiReadReg(DEC_RATE);
if(9 == data)
break;
_delay_us(200);
}
_delay_ms(250);
}
头文件,借用了其他人的成果,特此声明。
#ifndef _ADIS16465_H
#define _ADIS16465_H
/* Private typedef -----------------------------------------------------------*/
#define sADIS_ID 0X4051 //ADIS16465
/* Private define ------------------------------------------------------------*/
/**************寄存器定义-开头**************/
#define DIAG_STAT 0x0200
#define X_GYRO_LOW 0x0400
#define X_GYRO_OUT 0x0600
#define Y_GYRO_LOW 0x0800
#define Y_GYRO_OUT 0x0A00
#define Z_GYRO_LOW 0x0C00
#define Z_GYRO_OUT 0x0E00
#define X_ACCL_LOW 0x1000
#define X_ACCL_OUT 0x1200
#define Y_ACCL_LOW 0x1400
#define Y_ACCL_OUT 0x1600
#define Z_ACCL_LOW 0x1800
#define Z_ACCL_OUT 0x1A00
#define TEMP_OUT 0x1C00
#define TIME_STAMP 0x1E00
#define DATA_CNTR 0x2200
#define X_DELTANG_LOW 0x2400
#define X_DELTANG_OUT 0x2600
#define Y_DELTANG_LOW 0x2800
#define Y_DELTANG_OUT 0x2A00
#define Z_DELTANG_LOW 0x2C00
#define Z_DELTANG_OUT 0x2E00
#define X_DELTVEL_LOW 0x3000
#define X_DELTVEL_OUT 0x3200
#define Y_DELTVEL_LOW 0x3400
#define Y_DELTVEL_OUT 0x3600
#define Z_DELTVEL_LOW 0x3800
#define Z_DELTVEL_OUT 0x3A00
#define XG_BIAS_LOW 0x4000
#define XG_BIAS_HIGH 0x4200
#define YG_BIAS_L 0x44
#define YG_BIAS_H 0x45
#define YG_BIAS_H_L 0x46
#define YG_BIAS_H_H 0x47
#define ZG_BIAS_LOW 0x4800
#define ZG_BIAS_HIGH 0x4A00
#define XA_BIAS_LOW 0x4C00
#define XA_BIAS_HIGH 0x4E00
#define YA_BIAS_LOW 0x5000
#define YA_BIAS_HIGH 0x5200
#define ZA_BIAS_LOW 0x5400
#define ZA_BIAS_HIGH 0x5600
#define RANG_MDL 0x5E00
#define MSC_CTRL 0x6000
#define UP_SCALE 0x6200
#define FILT_CTRL_L 0x5C
#define FILT_CTRL_H 0x5D
#define DEC_RATE 0x6400
#define DEC_RATE_L 0x64
#define DEC_RATE_H 0x65
#define NULL_CNF 0x6600
#define NULL_CNFG_L 0x66
#define NULL_CNFG_H 0x67
#define GLOB_CMD 0x6800
#define GLOB_CMD_L 0x68
#define GLOB_CMD_H 0x69
#define FIRM_REV 0x6C00
#define FIRM_DM 0x6E00
#define FIRM_Y 0x7000
#define PROD_ID 0x7200
#define SERIAL_NUM 0x7400
#define USER_SCR_1 0x7600
#define USER_SCR_2 0x7800
#define USER_SCR_3 0x7A00
#define FLSHCNT_LOW 0x7C00
#define FLSHCNT_HIGH 0x7E00
#define BURST_READ 0x6800
#define Dummy_Byte 0x0FFF
/*******Global Commands (GLOB_CMD)命令***********/
#define SOFTWARE_RESET 0x80
#define FLASH_MEMORY_TEST 0x10
#define FLASH_MEMORY_UPDATE 0x08
#define SENSOR_SELF_TEST 0x04
#define FACTORY_CALIBRATION_RESTORE 0x02 //工厂校准恢复
#define BIAS_CORRECTION_UPDATE 0x01 //偏差纠正更新
#define PI 3.1415
void burstRead(int *buf);
unsigned int spiReadReg(unsigned int address);
void spiWriteReg(unsigned char address,unsigned char data);
void globalCommands(unsigned char data);
void imuInit(void);
#endif /* __SPI_ADIS_H */