freedomhit

ADIS16130的通讯程序(一)

0
阅读(4247)
#include 
#include
#include

//--------------------- Global Variables ----------------------------//

// timer flag used for delay counter
volatile unsigned char TIMER1_FLAG = 0;			
// local storage for status register
unsigned short STATUS;
float X_Angle = 0.0;							

// local storage for capture buffers
short int CAPT_BUF1[1024];
short int CAPT_BUF2[1024];
short int CAPT_BUF3[1024];

//--------------------- Local Functions -----------------------------//

// Initialize MCLK, I/O, and SPI interface
void system_init(void);
// Initialize ADIS16130
void ADIS16130_Initiation();
// start manual capture	and transfer data
unsigned short manual_capture(void);

// SPI write register value to specified address (automatically handles adding write bit to MSB)
void spi_write_reg(unsigned char address, unsigned char value);

// SPI read register definded by specified address
int spi_read_reg(unsigned char address);

// read all three capture buffers
void spi_read_buffers(void);

// SPI read/write - send a byte and receive a byte
char spi_rw(char data);

// send a wakeup pulse to adis16220
void wakeup(void);

// wait for busy flag to lower indicating device is free (use after a command is sent)
void busy_wait(void);

// delay for 'time' in microseconds
void delay_us(unsigned long time);

// delay for 'time' in milliseconds	
void delay_ms(unsigned long time);

//------------------------ Main Loop ---------------------------------//

int main(void) 
{	

	system_init();
	ADIS16130_Initiation();
	
	while(1)
	{  	
		// blink green led so we still know the code is running
		GP4DAT ^= 0x00040000;						// Complement P4.2 (blink Green LED on eval board)	
	
		// send capture command (manual capture)
//		manual_capture();						
		X_Angle = spi_read_reg(0x48);
		sendfloatdata(&X_Angle);
//		printf("%f\n",X_Angle);
//		senddata(X_Angle);
		
		// delay 1 second and repeat process		
		delay_ms(10);					 			// delay for 1s
	}
}

//-------------------- End Main Loop ---------------------------------//

// start manual capture with SPI command, use busy flag, read data ready from STATUS reg, read captured data from buffers
unsigned short manual_capture(void)
{
	// put in manual mode CAPT_CTRL = 0x00
	// start capture and,
	// wait for busy flag
	// grab data when done and store

	// initialize capture to manual mode
	spi_write_reg(0x1C,0x00);		  	// write 0 to capture control register lower byte
	spi_write_reg(0x1D,0x00);		  	// write 0 to capture control register upper byte
	spi_write_reg(0x38,0x04);			// write 4 to average count for 64 averages	(Sample Rate = 100kHz/64)
	spi_write_reg(0x36,0x0F);			// enable busy indicator and DIO1/DIO2 polarity active high	

	// start manual capture
	spi_write_reg(0x3F,0x08);		  	// write start command to command register
	
	busy_wait();						// wait for capture to complete
	// can replace busy wait with delay_ms(time) if busy indicator not used

	// check data ready flag
	STATUS = spi_read_reg(0x3C);
	
	// if data ready then grab data
	if(STATUS & 0x0080)
	{
		spi_read_buffers();
	}
	
	return (STATUS & 0x0080) == 0x0080;

}

// read all three capture buffers
void spi_read_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 < 1024; i++)
	{
		CAPT_BUF1[i] = spi_read_reg(0x14);				// read CAPT_BUF1 register	
	}
	// read values from capture buffer 2

	for(i = 0; i < 1024; i++)
	{
		CAPT_BUF2[i] = spi_read_reg(0x16);				// read CAPT_BUF2 register
	}	
	// read values from capture buffer 3
	for(i = 0; i < 1024; i++)
	{
		CAPT_BUF3[i] = spi_read_reg(0x18);				// read CAPT_BUF3 register
	}	
}

// 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 P0.7 on ADIS16220)
	while(GP3DAT & 0x00000001);
}


// send a wakeup pulse to adis16220
void wakeup(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
	
	//delay_us(2100);							// delay for 2.1 ms to allow device to wake up (other option instead of using busy flag
	
	GP2DAT |= 0x00010000;            			// raise !CS pin
}

// Initialize CLK, I/O, and SPI interface
void system_init(void)
{
	// setup system clock to run at 41.78MHz
	POWKEY1 = 0x01;
	POWCON = 0x00;		   		    	// 41.78MHz
	POWKEY2 = 0xF4;

	// initialize General Purpose I/O for LED, DIO1, DIO2, and /RST
	GP4DAT = 0x04040000;				// P4.2 configured as an output. LED is turned off
//	GP3DAT = 0x06040000;				// P3.0/DIO1 input , P3.1/DIO2 output (default zero), P3.2/RST 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
	UART_Initiate();
	SPIDIV = 0xCC;						// set SPI clock 41,780,000/(2x(1+SPIDIV)), 0x07 = 2.61 MHz (0x05 = 3.48MHz is the max master clock speed)										
	SPICON = 0x104F;                    // enable SPI master in continuous transfer mode, idle high clock polarity, phase										  	

	delay_ms(150);						// wait for 150 ms to give ADIS16220 time to startup
}

void ADIS16130_Initiation()
{
	spi_write_reg(0x01,0x38);
	spi_write_reg(0x28,0x0A);
	spi_write_reg(0x30,0x05);
	spi_write_reg(0x2A,0x0A);
	spi_write_reg(0x32,0x05);
	spi_write_reg(0x38,0x20);
}

// write register value to specified address (automatically handles adding write bit to MSB)
// user can specify address of register without adding MSB
void spi_write_reg(unsigned char address, unsigned char value)
{
	GP2DAT &= ~0x00010000;            // lower !CS pin
//	spi_rw(0x80 + address);			  // send address byte with MSB = 1 for write
	spi_rw(address);
	spi_rw(value);					  // send data to write
	GP2DAT |= 0x00010000;             // raise !CS pin	

	delay_us(15);					  // stall time added for successive write commands
}

// read register definded by specified address
int spi_read_reg(unsigned char address)
{
	int data;
	short int hi_byte, lo_byte;

	GP2DAT &= ~0x00010000;            // lower !CS pin
	
	// send address (1st two bytes)
	spi_rw(address);				  // send address to read
//	spi_rw(0x00);					  // send dummy byte (next two bytes will be data)

	delay_us(15);	 				  // stall time of approx. 15us

	// send dummy bytes for data (2nd two bytes)
	hi_byte = spi_rw(0x00);			  // get MSByte
	lo_byte = spi_rw(0x00);			  // get LSByte

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

	data = (hi_byte << 8) | lo_byte;  // combine hi and lo bytes into a single 16 bit value
//	if(data & 0x8000)
//	{
//		data = data - 0xFFFF - 1;
//	}
	
	delay_us(15);					  // stall time of approx. 15us	

	return data;
}

// spi read/write - send a byte and receive a byte
char spi_rw(char data)
{
	SPITX = data;				      // transmit byte
 	while ((SPISTA & 0x08) != 0x08);  // wait for data received status bit
	return SPIRX;					  // return received byte
}

// delay for 'time' in microseconds
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;
}

// delay for 'time' in milliseconds
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);
	}
}

 

以前一直想要个ADIS16130的程序,可惜一直没有,终于搞定了。附件里附上ADIS的数据手册啊!