yanniwang

ADI公司ADXL312加速度计入门程序(为大家配了中文注释)

0
阅读(4697)

ADXL312是ADI公司推出的一款超小型高精度数字加速度计,其用法和大家熟知的ADXL345类似。下面是ADXL312三轴数字加速度计读数程序,主机采用ADUC7026,ADXL312作为从机,采用I2C通信,硬件上需要两根引脚,即ADUC7026上的SDA和SCL,为方便大家阅读,关键代码已经为大家配上了中文注释。

/*-----------------------ADI Show Three Axis Acceleration Reference Design Source Code--------------------

Author: 		ADI CAST (China Application Support Team)
Date:			2011-03-29
Rev:			V1.0
Description:	Realize Show Three Axis Acceleration Algorithm,Use ADuC7026 as MCU,
							Use ADXL312 as Acceleration Sensor,Development Tool: KEIL C
Platform:   EVAL-ADXL312-M
---------------------------------------------------------------------------------------------------------*/
#include 
#include "XL312.h"
#include "XL312_IO.h"


//三轴加速度变量
#define		X_CHANNEL		0		
#define		Y_CHANNEL		1
#define		Z_CHANNEL		2

unsigned	char 	iTemp = 0;					//临时变量
unsigned	char	Calculate_Sign = 0;			//数据就绪标志
unsigned	int		Acceleration[3] = {0,0,0};	//三轴加速度初值

//Reigster for ADXL312										
unsigned	char	DataX_High, DataX_Low;		//数据寄存器 X的高字节和低字节	
unsigned	char	DataY_High, DataY_Low;		//数据寄存器 Y的高字节和低字节
unsigned	char	DataZ_High, DataZ_Low;		//数据寄存器 Z的高字节和低字节
unsigned	char	INT_Source, Dev_ID;			//中断源寄存器和设备ID寄存器

unsigned	char	UartDataReceived;			//接收到的数据
unsigned	char	UartInterrupt;				//中断状态

union{unsigned int ui;unsigned char uc[4];}un;
unsigned	char	buf[8];

void IRQ_Handler() __irq
{		
	if(0 != (IRQSTA & XIRQ0_BIT))			//外部中断IRQ3(IRQ3->INT2 pin of ADXL312)
	{
		Calculate_Sign = 1;					//设标志位
		xl312Read(6, XL312_DATAX0, buf);	//读取XYZ数据寄存器
		DataX_Low = buf[0];
		DataX_High = buf[1];
		DataX_High &= 0x1F;
		DataY_Low = buf[2];
		DataY_High = buf[3];
		DataY_High &= 0x1F;
		DataZ_Low = buf[4];
		DataZ_High = buf[5];
		DataZ_High &= 0x1F;
	}
	IRQCLR = IRQCLR|XIRQ0_BIT;
}

/****************************************************************************
	DAC_Config Function - 配置DAC输出
						  DAC0	: VS1, Gained up by 3 after Amp
						  DAC1	: VS2, Gained up by 3 after Amp 
						  DAC2	: REF for AD8220, No Gain
****************************************************************************/
void DAC_Config(void)
{
	uint32	DAC0_Val = 0x40E;
	uint32	DAC1_Val = 0x2EC;
	uint32	DAC2_Val = 0x5D4;
	
	DAC0CON = 0x13;				// 正常模式, 0 V to AVdd
	DAC1CON = 0x13;				
	DAC2CON = 0x13;				
	DAC0DAT = (uint32)DAC0_Val << 16;	// 初始化 VS1
	DAC1DAT = (uint32)DAC1_Val << 16;	// 初始化 VS2
	DAC2DAT = (uint32)DAC2_Val << 16;	// 初始化 REF
}


void ADuC7026_Initiate(void)
{
	//Clock Initial
	POWKEY1 = 0x01;					
	POWCON = 0x00;					//设置系统主频 = 41.78MHz
	POWKEY2 = 0xF4;		

	GP1CON = 0x00002211;			//为I2C和 UART选择复用端口
	GP2DAT = GP2DAT | 0x04040000;	//禁用 LCD;
	GP0DAT = GP0DAT | 0x02020000;	//禁用 LED;

  //串口初始化,波特率 = 9600
	COMCON0 = 0x080;  
	COMDIV0 = 0x088;    		
	COMDIV1 = 0x000;
	COMCON0 = 0x007;    
		 
	//I2C Initial
	I2C1CFG = 0x00000082;       	// 使能主机并设置时钟频率
	I2C1DIV = 0x3232;        		// 0x3232 = 400kHz	

    //Interrupt Set Up
}
//ADXL312 初始化
void ADXL312_Initiate()
{
  FIQEN = SM_MASTER1_BIT;			    //I2C1 主机中断
	buf[0] = XL312_BW_12_5;				//数据输出频率: 12.5Hz
	xl312Write(1,XL312_BW_RATE, buf);
	buf[0] = XL312_FULL_RESOLUTION | XL312_RANGE_16G;//数据格式: +/-16g 范围
	xl312Write(1, XL312_DATA_FORMAT, buf);
	buf[0] = XL312_DATAREADY;			//INT使能: 数据就绪
	xl312Write(1, XL312_INT_ENABLE, buf);
	buf[0] = XL312_DATAREADY;			//INT_映射:
	xl312Write(1, XL312_INT_MAP, buf);
}

void main(void)
{
	ADuC7026_Initiate();				//ADuC7026 初始化

	DAC_Config();								// 为ADXL312 供电
	ADXL312_Initiate();					//ADXL312 初始化

	xl312Read(1,XL312_DEVID,buf); 		//获取设备ID
	Dev_ID = buf[0];
	COMIEN0 = 0x01;						//使能接收缓存满中断						
  IRQEN =  XIRQ0_BIT ;	//使能 IRQ0 中断 (IRQ0->INT2 pin of ADXL312)

	buf[0] = XL312_MEASURE;				
	xl312Write(1, XL312_POWER_CTL, buf);

	while(1)
	{
		  if(1 == Calculate_Sign)
			{
				Calculate_Sign = 0;
		   
				Acceleration[X_CHANNEL] = DataX_High;
				Acceleration[X_CHANNEL] = (Acceleration[X_CHANNEL]<<8) | DataX_Low;
	
				Acceleration[Y_CHANNEL] = DataY_High;
				Acceleration[Y_CHANNEL] = (Acceleration[Y_CHANNEL]<<8) | DataY_Low;
	
				Acceleration[Z_CHANNEL] = DataZ_High;
				Acceleration[Z_CHANNEL] = (Acceleration[Z_CHANNEL]<<8) | DataZ_Low;
					
				//数据格式转换	(256+4096)->1g, (4096-256)->(-1)g										  
				for(iTemp=X_CHANNEL;iTemp<=Z_CHANNEL;iTemp++)
				{
					if(Acceleration[iTemp] < 4096)
					{
						Acceleration[iTemp] = Acceleration[iTemp] + 4096;	
					}
					else if(Acceleration[iTemp] >= 4096)
					{
						Acceleration[iTemp] = Acceleration[iTemp] - 4096;	
					}
					un.ui = Acceleration[iTemp];
					putchar(un.uc[1]);//高位
					putchar(un.uc[0]);//低位
				}	
			IRQEN =  XIRQ0_BIT;
	    }
	}
}