|
|
View previous topic :: View next topic |
Author |
Message |
Armer175
Joined: 13 Jan 2009 Posts: 12
|
ADIS16350 Driver Creation |
Posted: Wed Mar 11, 2009 5:02 pm |
|
|
Ok I am trying to read and write to an ADIS16350 accelerometer/gyro. I was having some problems getting the data and was advised to make a driver for it. I haven't programmed C in a long time so please forgive the appearence.
Datasheet:
http://www.analog.com/static/imported-files/data_sheets/ADIS16350_16355.pdf
Driver:
Code: |
// ADIS16350 Accel/Gyro Driver
// 3/11/09
//
//
//
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#DEFINE SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
//SPI Accel/Gyro
int16 supply_out=0;
int8 supply_out_low=0;
int8 supply_out_high=0;
int16 xgyro_out;
int16 ygyro_out;
int16 zgyro_out;
int8 xgyro_out_low, xgyro_out_high;
int8 ygyro_out_low, ygyro_out_high;
int8 zgyro_out_low, zgyro_out_high;
int16 xgyro_temp_out;
int16 ygyro_temp_out;
int16 zgyro_temp_out;
int8 xgyro_temp_out_low, xgyro_temp_out_high;
int8 ygyro_temp_out_low, ygyro_temp_out_high;
int8 zgyro_temp_out_low, zgyro_temp_out_high;
int16 xaccl_out;
int16 yaccl_out;
int16 zaccl_out;
int8 xaccl_out_low, xaccl_out_high;
int8 yaccl_out_low, yaccl_out_high;
int8 zaccl_out_low, zaccl_out_high;
float voltage;
//setup spi for transmission
// function for reterieving supply voltage
void Get_Supply_Voltage()
{
setup_spi2(SPI_MASTER|SPI_MODE_3|SPI_CLK_DIV_16); //MODE3
Output_Low(PIN_E7);
Spi_Write2(0x03);
supply_out_high=SPI_READ2(0);
Output_High(PIN_E7);
swap(supply_out_high);
Output_Low(PIN_E7);
Spi_Write2(0x02);
SUPPLY_OUT_LOW=SPI_READ2(0);
Output_High(PIN_E7);
swap(SUPPLY_OUT_LOW);
supply_out=MAKE16(supply_out_high, supply_out_low);
BIT_CLEAR(supply_out,15);
BIT_CLEAR(supply_out,14);
BIT_CLEAR(supply_out,13);
BIT_CLEAR(supply_out,12);
BIT_CLEAR(supply_out,11);
BIT_CLEAR(supply_out,10);
voltage=SUPPLY_OUT*1.8315e-3;
} |
Unfortunately this code above is not working correctly and I am not sure what I am doing wrong.
How does does the main program know to use my variables from this driver?
Main program referenced at:
http://www.ccsinfo.com/forum/viewtopic.php?t=38142
Last edited by Armer175 on Wed Mar 11, 2009 5:54 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 11, 2009 5:09 pm |
|
|
Also post a small test program that calls the driver functions.
The test program must have the #include statement for the PIC,
#fuses, #use delay(), and a main(). It must be a short program.
It must compile without errors. |
|
|
Armer175
Joined: 13 Jan 2009 Posts: 12
|
|
Posted: Wed Mar 11, 2009 5:56 pm |
|
|
Here is the test Program I created which had no errors when compiled. I did have lots of warnings for all the variables I havent used yet.
Code: |
#include <18F8723.h>
#device adc=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal Osc
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES MCU //Microcontroller Mode
#FUSES NOWAIT //Wait selections unavailable for Table Reads or Table Writes
#FUSES BW16 //16-bit external bus mode
#FUSES ABW16 //16-bit Address bus
#FUSES ECCPE //Enhanced CCP PWM outpts multiplexed with RE6 thorugh RE3
#use delay(clock=4000000)
#use rs232(stream=UART1,baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,UART1)
#use rs232(stream=UART2,baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,UART2)
#use i2c(Master,SDA=PIN_C4,SCL=PIN_C3,FORCE_HW)
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <ADIS16350.C>
Void main()
{
Get_Supply_Voltage();
fprintf(UART1,"total %lx voltage %2.5f \r\n",supply_out, voltage);
delay_ms(500);
} |
|
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Mar 11, 2009 11:16 pm |
|
|
To my opinion, you didn't understand the read operation with ADIS16350. It is reading 16 bit of data during one (NEXT) SPI access cycle. It's a bit unusual, I think you should read the datasheet a new rather than I try to retell it imperfectly.
P.S.: Also the swap() is wrong. Read of 16-Bit register 0x03/0x02 should proceed like below:
Code: | Output_Low(PIN_E7);
Spi_Write2(0x02);
Spi_Write2(0);
Output_High(PIN_E7);
Output_Low(PIN_E7);
supply_out_high=SPI_READ2(0);
supply_out_low=SPI_READ2(0);
Output_High(PIN_E7);
voltage=MAKE16(supply_out_high & 0x0f, supply_out_low)*1.8315e-3; |
|
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Thu Mar 12, 2009 3:05 am |
|
|
You also need to read page 14, you are clearing the upper 6 bits, which will not reduce the resolution, it will reduce the range, and it will not work on the 2's compliment(negative) output numbers.
Suggest reading http://www.ccsinfo.com/forum/viewtopic.php?t=38103 |
|
|
Armer175
Joined: 13 Jan 2009 Posts: 12
|
|
Posted: Thu Mar 12, 2009 7:06 am |
|
|
Thanks FvM and Sydney for your feedback. I will try your reading suggestion today. I only need to clear the upper 4 bits for the voltage reading since it is a 12 bit number.
My code compiled fine in CCS but when I go to compile it in mplab i get this error.....
*** Error 128 "C:\PROGRA~1\PICC\drivers\math.h" Line 36(1,21): A #DEVICE required before this line
When I click on it takes me into the math .h folder. Then if I comment out the #include <math.h> in the adis.c file it give the same error but in the string.h folder. and so on.
I don't know what it needs.
Ok did some research and just moved my adis16350.c from under source files to the other files folder. Seems to complile now. |
|
|
Armer175
Joined: 13 Jan 2009 Posts: 12
|
|
Posted: Thu Mar 12, 2009 9:55 am |
|
|
Ok I was able to get the code tested out. FvM your code worked but but the voltage was off a little bit. Plus I modified it a little.....as shown below. This gave a more accurate reading within 70mV. Also after reviewing the data sheet I found I was interpreting what LSB justified meant. So thats why I thought I had to swap bit order. The only problem I am still having is about every 10 readings I get one that says .184 volts then goes right back to showing 4.91v. I had the same problem even with your code. Any ideas what could be causing this.
Code: |
Output_Low(PIN_E7);
Spi_Write2(0x03);
Spi_Write2(0);
supply_out_high=SPI_READ2(0);
supply_out_low=SPI_READ2(0);
Output_High(PIN_E7);
voltage=MAKE16(supply_out_high & 0x0f , supply_out_low)*1.8315e-3; //thanks for this, its much easier than bitclears.
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 12, 2009 11:25 am |
|
|
Display the msb and lsb values, and the voltage. When the voltage
goes to 0.184v, look at the MSB and LSB and see if there is something
strange about the values.
One method to troubleshoot this type of problem is:
If the final result is strange (or unexpected), the problem could be
because the raw data is bad. Or, your code that calculates the result
has a bug. Either one of those could be bad, but only under certain
conditions. It might be a boundary condition, such as when a the sign
changes to negative. By looking at the raw data at the same time
as the calculated result, you can make a judgement as to where to
problem is coming from. Sometimes it may be better to display the
numbers in hex, rather than decimal. This may help you to see an
overflow condition. (Rolling over from 0xFFFF to 0x0000, and losing
resolution, which causes a strange output). In other words, be a
detective. Investigate the problem. |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Thu Mar 12, 2009 4:05 pm |
|
|
Do you get the odd bad sample with the code fvm posted, you removed the part that drives cs high to signify the end of the data frame, but the datasheet is a little unclear if this is necessary or not.(and I cant see as it would make the reading more accurate as you describe)
Also dont rule out a hardware problem, spi wire/trace length, and proper decoupling. |
|
|
Sydney
Joined: 13 Feb 2009 Posts: 71
|
|
Posted: Thu Mar 12, 2009 4:07 pm |
|
|
You could also try a slower spi speed, to rule that out. |
|
|
Armer175
Joined: 13 Jan 2009 Posts: 12
|
|
Posted: Fri Mar 13, 2009 7:39 am |
|
|
So I started back up this morning and I can't dulplicate the problem. Putty has been running for an hour and no false readings. I even removed the delays with no problems. The one strange thing is that my msb and lsb dont match extactly what I am getting from my logic analyzer.
Saleae Logic:
Time [s] , MOSI, MISO
0.0000043, 0x03, 0x00
0.0000205, 0x00, 0x05
0.0000368, 0x00, 0xC5
0.0000550, 0x00, 0x3F
At approx same time debug terminalgiving :
highbyte=8a
lowbyte=9f
I cant remeber if I reset the system yesterday so maybe trying to read incorrectly put a lil "garbage" in the system. I did have to change my clock from 8mhz to 4mhz. If I put it on 8 the values are not read correctly even with a clock divide of 64. This should work since even with that since that is only 125khz. I am using 4mhz now with a clock divide of 16 which is 250khz. Maybe I am better off using external timer for spi bus.
I dont know if i can really rule out that I may not be reading registers correctly. I think I may contact Analog Devices about the specifics for reading and writing.
Im gonna try reading in acceleration now that I know spi seems to be working correctly. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|