yanniwang

三轴数字振动传感器ADIS16227应用指南

0
阅读(11155)

     ADIS16227 iSensor® 是一款完整的振动检测系统,集宽带宽、三轴加速度检测与先进的时域和频域信号处理于一体。时域信号处理包括可编程抽取滤波器和可选的窗函数。频域处理包括针对各轴的512点实值FFT和FFT求均值功能,后一功能可减少噪底变化,从而提高分辨率。通过可存储16条记录的FFT存储系统,用户可以追踪长时间变化,并利用多个抽取滤波器设置捕获FFT。

22 kHz传感器谐振和100.2 kSPS采样速率提供频率响应,适合机器健康状况检测应用。铝芯可实现与MEMS加速度传感器的出色机械耦合。在所有操作中,均由内部时钟驱动数据采样和信号处理系统,无需外部时钟源。数据捕获功能具有三种模式,提供多个选项,以满足不同应用的需要。

利用SPI和缓冲结构可以方便地访问宽带宽传感器数据。ADIS16227还提供数字温度传感器和数字电源测量功能。

ADIS16227采用15 mm × 15 mm × 15 mm模块封装,配有用于10-32UNF螺栓安装的螺纹孔。灵活的双排、1 mm、14引脚连接器可实现简单易行的用户接口和安装。ADIS16227与ADIS16223尺寸兼容且引脚兼容。工作温度范围为−40°C至+125°C。

功能框图

应用

振动分析

状态监控

机械健康状况

仪器仪表、诊断

安全关断检测

与处理器通信方式

ADIS16227采用SPI接口与主机(单片机、DSP等)进行通信,框图如下:

应用代码

下面是用ADUC7026单片机作为主机,读取ADIS16227数据的代码

 

/*********************************************************************

 Author        : Carey Merritt

 Date          : July 2011

 File          : main.c

 Hardware      : ADuC7026 Eval Board EVAL-ADUX7026SQZ 
                 
 Description   : Demo code for ADIS16227. This code sends a command
 				 to start a fft record, waits for completion, reads 
				 record from device, and prints data to uart. The data
				 can be captured in a Hyperterminal type software using
				 a PC serial port. Settings for hyperterminal need to be
				 Baud: 115200 bps, 8-N-1, 8 bits, No parity, 1 stop bit
				 and no flow control.
		
*********************************************************************/


#include 
#include "stdio.h"
#include 						// Register definitions
#include 						// Macro definitions

// Local global variables
volatile long TIME_MS = 0;
volatile unsigned char TIMER1_FLAG = 0;
volatile unsigned char TIMER2_FLAG = 0;
char buffer [80];						  	// serial buffer
unsigned char buffer_size = 0;			  	// serial buffer size

// ------------------ External subroutines ----------------------//
extern void usart_init(void);
extern void serial_send_reg(unsigned char address, short data);
extern void usart_tx_byte(char data);
extern void usart_tx_bytes(char * data, unsigned char length);
extern void usart_tx_hex_int(short data);

// -------------------- Local prototypes -------------------------//				
void print_fft_data(void);
void print_time_data(void);
void manual_fft_record(unsigned short rec_ctrl, unsigned short fft_avg);
void manual_time_record(unsigned short rec_ctrl);
void read_fft_buffers(void);
void read_time_buffers(void);
void get_regs(void);
void busy_wait(void);
void wakeup_device(void);
void system_init(void);
void write_reg(unsigned char address, unsigned char value);
void write_reg_int(unsigned char address, unsigned short data);
short int read_reg(unsigned char address);
char spi_rw(char data);
void delay_us(unsigned long time);
void delay_ms(unsigned long time);


/*****************************************************************************
  Function		: 	main()

  Input			: 	void
		
  Returns		: 	n/a

  Description	: 	Main application loop. 

******************************************************************************/
int main(void) 
{	
	system_init();
	usart_init();	

/*
	// read registers example
	get_regs();				 				// get register values from device
*/

/*
	// fft record example
	manual_fft_record(0x1120, 0x0008);		// request fft record, window = hanning, sample rate option 0, average = 1 (100.19ksps), 20g input range, fft avg = 8
	print_fft_data();						// print fft record to uart (save to file using hyperterminal)
*/

	// time record example
	manual_time_record(0x1122);				// request time record, sample rate option 0, average = 1 (100.19ksps), 20g input range
	print_time_data();						// print time record to uart (save to file using hyperterminal)


	while(1)
	{
		GP4DAT ^= 0x00040000;				// Complement P4.2 (blink Green LED on eval board)	
	
		delay_ms(500);			    		// delay for 250 ms
	}
}

/*****************************************************************************
  Function		: 	print_fft_data()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Print FFT record data to uart

******************************************************************************/
void print_fft_data(void)
{
	unsigned int i = 0;

	// print fft buffers to serial port (UART)
	for(i = 0; i < 256; i++)
	{
		buffer_size = sprintf(buffer,"%d,%d,%d\n",X_FFT[i],Y_FFT[i],Z_FFT[i]);
		usart_tx_bytes(buffer,buffer_size);
	}
}

/*****************************************************************************
  Function		: 	print_time_data()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Print time record data to uart

******************************************************************************/
void print_time_data(void)
{
	unsigned int i = 0;

	// print time buffers to serial port (UART)
	for(i = 0; i < 512; i++)
	{
		buffer_size = sprintf(buffer,"%d,%d,%d\n",X_DATA[i],Y_DATA[i],Z_DATA[i]);
		usart_tx_bytes(buffer,buffer_size);
	}
}

/*****************************************************************************
  Function		: 	manual_fft_record()

  Input			: 	rec_ctrl - record control settings (be sure to put in fft mode)
  					fft_avg - fft averages
		
  Returns		: 	void

  Description	: 	Capture a FFT record and read from device

******************************************************************************/
void manual_fft_record(unsigned short rec_ctrl, unsigned short fft_avg)
{
	unsigned char rec_ctrl_lo;
	unsigned char rec_ctrl_hi;

	// initialize capture to manual mode
	rec_ctrl_lo = (rec_ctrl & 0x00FF);
	rec_ctrl_hi = (rec_ctrl >> 8);
		
	write_reg(0x1C,rec_ctrl_lo);			// write to record control register lower byte
	write_reg(0x1D,rec_ctrl_hi);		  	// write to record control register upper byte 
	write_reg(0x0E,fft_avg);				// write FFT_AVG
	write_reg(0x36,0x0F);					// enable busy indicator	

	write_reg(0x3E,0x10);		  			// write clear status register command to command register	

	// start manual capture	
	write_reg(0x3F,0x08);		  			// write start command to command register
	
	busy_wait();							// wait for capture to complete

	REG.STATUS = 0;

	// check data ready flag
	REG.STATUS = read_reg(0x3C);
	// if data ready then grab data
	if(REG.STATUS & 0x0080)
	{
		read_fft_buffers();
	}


}

/*****************************************************************************
  Function		: 	manual_time_record()

  Input			: 	rec_ctrl - record control settings (be sure to put in time mode)
		
  Returns		: 	void

  Description	: 	Capture a time domain record and read from device

******************************************************************************/
void manual_time_record(unsigned short rec_ctrl)
{
	unsigned char rec_ctrl_lo;
	unsigned char rec_ctrl_hi;

	// initialize capture to manual mode
	rec_ctrl_lo = (rec_ctrl & 0x00FF);
	rec_ctrl_hi = (rec_ctrl >> 8);
		
	write_reg(0x1C,rec_ctrl_lo);			// write to record control register lower byte (manual time mode)
	write_reg(0x1D,rec_ctrl_hi);		  	// write to record control register upper byte 
	write_reg(0x36,0x0F);					// enable busy indicator	

	write_reg(0x3E,0x10);		  			// write clear status register command to command register	

	// start manual capture	
	write_reg(0x3F,0x08);		  			// write start command to command register
	
	busy_wait();							// wait for capture to complete

	REG.STATUS = 0;

	// check data ready flag
	REG.STATUS = read_reg(0x3C);
	// if data ready then grab data
	if(REG.STATUS & 0x0080)
	{
		read_time_buffers();
	}

}

/*****************************************************************************
  Function		: 	read_fft_buffers()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Read all three fft buffers (256 values each) from device

******************************************************************************/
void read_fft_buffers(void)
{
	unsigned short i = 0;

	// read values from capture buffer 1 (note: each read must be in a separate loop because of automatic indexing of capt_pntr)
	for(i = 0; i < 256; i++)
	{
		X_FFT[i] = read_reg(0x14);				// read BUF1 register	
	}
	// read values from capture buffer 2
	for(i = 0; i < 256; i++)
	{
		Y_FFT[i] = read_reg(0x16);				// read BUF2 register
	}	
	// read values from capture buffer 3
	for(i = 0; i < 256; i++)
	{
		Z_FFT[i] = read_reg(0x18);				// read BUF3 register
	}
}

/*****************************************************************************
  Function		: 	read_time_buffers()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Read all three time buffers (512 values each) from device

******************************************************************************/
void read_time_buffers(void)
{
	unsigned short i = 0;

	// read values from capture buffer 1 (note: each read must be in a separate loop because of automatic indexing of capt_pntr)
	for(i = 0; i < 512; i++)
	{
		X_DATA[i] = read_reg(0x14);				// read CAPT_BUF1 register	
	}
	// read values from capture buffer 2
	for(i = 0; i < 512; i++)
	{
		Y_DATA[i] = read_reg(0x16);				// read CAPT_BUF2 register
	}	
	// read values from capture buffer 3
	for(i = 0; i < 512; i++)
	{
		Z_DATA[i] = read_reg(0x18);				// read CAPT_BUF3 register
	}
}

/*****************************************************************************
  Function		: 	get_regs()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Read all user registers from device, store in REG structure,
  					and print to uart

******************************************************************************/
void get_regs(void)
{
	unsigned char i = 0;
	short value;
	unsigned short * reg_pntr;
	reg_pntr = (unsigned short *)((unsigned long)(®));

	usart_tx_byte('\n');
	usart_tx_byte('\r');

	usart_tx_bytes("----------------------------\n\r",30);

	// go through and send each value
	for(i = 0; i < 0x76; i+=2)
	{
		value = read_reg(i);
		*reg_pntr++ = value;				// store value in user register structure REG
		serial_send_reg(i,value);				
	}

}

/*****************************************************************************
  Function		: 	busy_wait()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Wait for busy flag to lower indicating device is free

******************************************************************************/
void busy_wait(void)
{
	// wait for busy flag to raise
	while((GP3DAT & 0x00000001) != 0x00000001);
	// wait for busy flag to drop (P3.0 Eval to DIO1 on device)
	while(GP3DAT & 0x00000001);
}

/*****************************************************************************
  Function		: 	busy_wait()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Send a wakeup pulse to device using the chip select pin

******************************************************************************/
void wakeup_device(void)
{
	// wake up device by lowering /CS		 
	GP2DAT &= ~0x00010000;           			// lower !CS pin	
	
	// wait for busy flag to go high
	while((GP3DAT & 0x00000001) != 0x00000001);	// comment out when using delay instead

	// wait for busy flag to go low
	while(GP3DAT & 0x00000001);					// comment out when using delay instead
		
	GP2DAT |= 0x00010000;            			// raise !CS pin
}

/*****************************************************************************
  Function		: 	system_init()

  Input			: 	void
		
  Returns		: 	void

  Description	: 	Initialize system, set core clock/pll to run from external
  					real time crystal (32.768kHz), configure i/o, and initialize
					the spi interface to communicate with device

******************************************************************************/
void system_init(void)
{

	unsigned long t2val_old;

	t2val_old = T2VAL;
	// set external 32k
	T2LD = 5;
	T2CON = 0x480;
	while ((T2VAL == t2val_old) || (T2VAL >3)) //ensures timer value loaded
	IRQEN = 0x10;
	//enable T2 interrupt
	PLLKEY1 = 0xAA;
	PLLCON = 0x01;						// select external 32k osc
	PLLKEY2 = 0x55;
	POWKEY1 = 0x01;
	POWCON = 0x27;
	// Set Core into Nap mode (wakes up when switched to external crystal
	POWKEY2 = 0xF4;
	IRQCLR = 0x10;		
	
	// setup system clock to run at 41.78MHz
	POWKEY1 = 0x01;
	POWCON = 0x00;		   		    	// 41.78MHz
	POWKEY2 = 0xF4;

	GP4DAT = 0x04040000;				// P4.2 configured as an output. LED is turned off
	GP3DAT = 0x06040000;				// P3.0 input DIO0, P3.1 output DIO1 (default zero), P3.2 output (/reset) set to 1
	
	// intialize SPI interface for master mode
	GP2DAT = 0x01010000;                // !CS - P2.0 configured as an output and default to high
	GP1CON = 0x22220000;				// configure SPI on SPM
	SPIDIV = 0x08;						// set SPI clock 41,780,000/(2x(1+SPIDIV)), 0x08 = 2.32MHz										
	SPICON = 0x104F;                    // enable SPI master in continuous transfer mode, idle high clock polarity, phase										  	

	delay_ms(300);						// wait for device to power up
}

/*****************************************************************************
  Function		: 	write_reg()

  Input			: 	address - 7 bit user register address
  					value - value to write to register at specified address
		
  Returns		: 	void

  Description	: 	Writes a byte to register located at 'address'

******************************************************************************/
void write_reg(unsigned char address, unsigned char value)
{
	GP2DAT &= ~0x00010000;            // lower !CS pin
	spi_rw(0x80 + address);
	spi_rw(value);
	GP2DAT |= 0x00010000;             // raise !CS pin	

	delay_us(30);
}

/*****************************************************************************
  Function		: 	write_reg_int()

  Input			: 	address - 7 bit user register address
  					value - value to write to register at specified address
		
  Returns		: 	void

  Description	: 	Writes an integer to register located at 'address'

******************************************************************************/
void write_reg_int(unsigned char address, unsigned short data)
{
	write_reg(address,data);
	write_reg(address+1,data>>8);
}

/*****************************************************************************
  Function		: 	read_reg()

  Input			: 	address - 7 bit user register address
		
  Returns		: 	short int - register value

  Description	: 	Reads an integer from register located at 'address'

******************************************************************************/
short int read_reg(unsigned char address)
{
	short int data;
	short int hi_byte, lo_byte;

	GP2DAT &= ~0x00010000;            	// lower !CS pin
	
	// send address (1st two bytes)
	spi_rw(address);	  
	spi_rw(0x00);	
	delay_us(15);						// 15 us stall time

	// send dummy bytes to get data
	hi_byte = spi_rw(0x00);
	lo_byte = spi_rw(0x00);

	GP2DAT |= 0x00010000;             	// raise !CS pin

	data = (hi_byte << 8) + lo_byte;	
	delay_us(15);						// 15 us stall time

	return data;
}

/*****************************************************************************
  Function		: 	spi_rw()

  Input			: 	data - data to write to spi
		
  Returns		: 	char - data read from spi during write

  Description	: 	SPI write/read 

******************************************************************************/
char spi_rw(char data)
{
	SPITX = data;				      // transmit byte
 	while ((SPISTA & 0x08) != 0x08);  // wait for data received status bit
	return SPIRX;					  // return received byte
}

/*****************************************************************************
  Function		: 	delay_us()

  Input			: 	time - time in us
		
  Returns		: 	void

  Description	: 	Delay method which uses timer1 with interrupts. Takes
  					time in microseconds and waits for 'time' to expire.

******************************************************************************/
void delay_us(unsigned long time)
{
	TIMER1_FLAG = 0;
	T1CON = 0;
										// T1LD = time (us) * freq (MHz) (e.g. 500us * 41.78 MHz = 20890-1) subtract 1 since includes zero
	T1LD = ((time * 42782) >> 10) - 1;	// 41.78 * 1024 = 42782, mult by time in (us) and divide by 1024										
	T1CON = 0x00C0;						// init timer 1, 41.78Mhz, down mode, periodic
	IRQEN |= GP_TIMER_BIT;				
	while(!TIMER1_FLAG);				// wait for timer flag	
	TIMER1_FLAG = 0;
	T1CON = 0;
	IRQCLR |= GP_TIMER_BIT;
}

/*****************************************************************************
  Function		: 	delay_ms()

  Input			: 	time - time in ms
		
  Returns		: 	void

  Description	: 	Delay method which uses timer1 with interrupts. Takes
  					time in milliseconds and waits for 'time' to expire. This
					method uses the delay_us to generate a millisecond.  

******************************************************************************/
void delay_ms(unsigned long time)
{
	unsigned short i = 0;	
	// wait for 1 ms each time through loop
	for(i = 0; i < time; i++)
	{
		delay_us(1000);
	}
}
  •