ADIS16130的通讯程序(一)
0赞
发表于 10/23/2011 10:21:42 AM
阅读(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的数据手册啊!
