ADIS16220调试入门程序
0赞
发表于 1/14/2012 10:09:24 PM
阅读(4115)
了解了ADIS16220的基本原理后,就可以通过编程来应用了,我们可以采用ADI公司的模拟微控制器ADUC7026作为主机对ADIS16220进行数据读取,主要采用ADUC7026的SPI接口,下面给出ADI公司的一段程序供大家参考。
/*********************************************************************
Author : Carey Merritt, Analog Devices
Date : 02/19/2009
File : main.c
Hardware : ADuC7026 Eval Board with ADiS16220 70G Programmable
Digital Vibration Sensor
Description : Basic SPI commands for communicating with the ADiS16220
using the ADuC7026 Microcontroller. Includes an example
method for triggering a manual capture of 1024 samples,
and downloading data.
ADuC7026 ADiS16220
_ _
| |
SCLK/P1.4 |<-------->| SCLK
MISO/P1.5 |<---------| DOUT
MOSI/P1.6 |--------->| DIN
P2.0 |--------->| /CS
P3.0 |<---------| DIO1
P3.1 |--------->| DIO2
P3.2 |--------->| /RST
_| |_
*********************************************************************/
#include
//--------------------- Global Variables ----------------------------//
// timer flag used for delay counter
volatile unsigned char TIMER1_FLAG = 0;
// local storage for status register
unsigned short STATUS;
// 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);
// 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
short 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();
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();
// delay 1 second and repeat process
delay_ms(1000); // 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
SPIDIV = 0x07; // 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
}
// 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(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
short int spi_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); // 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
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);
}
}
