Here's part of some code for ST's LSM330DLC that looks like it has all the same registers for your gyroscope. Be sure to correct the address for your device.
Since it's a lengthy program, I'll just list the basic functions.
I used the MSSP module of the PIC18F14K50 so it can run in the background.
The read routine was called using the DRDY interrupt output of the device.
MSSP config:
Code:
SSPSTAT.7 = 0 ' Slew rate control set to 400KHz
SSPSTAT.6 = 0 ' SMBus compliance disabled
SSPCON1 = %00101000 ' Enbles I2C module and Master mode
SSPADD = $1A ' Baud rate clock divider bits set for 400KHz
' Adjusted from $1D = 368KHz
CLEAR ' Set all registers to 0
XYZ_RAM VAR BYTE[12] ' Array for 16 bit data, 2 bytes each. First 6 for accelerometer, last 6 for gyro
Gyro register configs:
Code:
'=========================================================================
' Gyroscope configuration
' Load time for all 13 Registers is 1029us at 400KHz setting
' Registers loaded in order specified by data sheet:
' 1. Write CTRL_REG2
' 2. Write CTRL_REG3
' 3. Write CTRL_REG4
' 4. Write CTRL_REG5
' 5. Write Reference
' 6. Write INT1_THS
' 7. Write INT1_DUR
' 8. Write INT1_CFG
' 9. Write CTRL_REG5
' 10. Write CTRL_REG1
'=========================================================================
Config_Gyr:
' Load CTRL_REG2: 10100111, Edge sensitive trigger, HP filter = Normal,
' HP cutoff = 0.09Hz
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $21 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %10100111 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load CTRL_REG3: 10000000, INT1_G enabled, no Boot Status, Active High,
' Push-pull output. INT2_G disabled
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $22 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00000000 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load CTRL_REG4: 01110000, cont. update, MSB @ lower address, 2000dps
' non SPI
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $23 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %01110000 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
'////////////////// XYZ Interrupt threshold settings ////////////////////
' Threshold level = THS / 0.061dps, where THS = 540dps (1.5 turns/sec)
' Maximum threshold level is 1/2 of Full Scale
' 14bit result is loaded into HI/LO registers of each axis
'////////////////////////////////////////////////////////////////////////
' Load INT1_THS_XH: 00100010, Interrupt MSB threshold bits 14:8
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $32 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00100010 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load INT1_THS_XL: 10010100, Interrupt LSB threshold bits 7:0
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $33 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %10010100 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load INT1_THS_YH: 00100010, Interrupt MSB threshold bits 14:8
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $34 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00100010 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load INT1_THS_YL: 10010100, Interrupt LSB threshold bits 7:0
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $35 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %10010100 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load INT1_THS_ZH: 00100010, Interrupt MSB threshold bits 14:8
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $36 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00100010 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load INT1_THS_ZL: 10010100, Interrupt LSB threshold bits 7:0
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $37 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %10010100 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
'|||||||||||||||| end XYZ Interrupt threshold settings ||||||||||||||||||
'////////////////// Duration set value //////////////////////////////////
' The ODR sets the LSB; 1/190Hz = 5.26ms
' The maximum Duration time is 6 bit or 128, Max = 128 * 5.26ms = 673ms
' The bit value = Duration/5.26ms
'///////////////////////////////////////////////////////////////////////
' Load INT1_Duration: 10000001, Wait enabled, Duration set to 1.3ms
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $38 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %10000000 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load INT1_CFG: 00101010, OR combo of INT, not Latched, interrupt request
' on measured value HIGHER than preset threshold
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $30 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00101010 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load CTRL_REG5: 00011010, Reboot mem Norm, FIFO disabled, HPen enabled,
' Out_SEL = HPF+LPF2, INT1 = HPF+LPF2
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $24 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00011010 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
' Load CTRL_REG1: 00111111, ODR=95Hz, LPF1=12.5Hz, LPF2=50Hz, Norm PWR,
' ZYX axes enabled
GOSUB Start_Gyr ' Adresss the device
SSPBUF = $20 ' Transmit register address
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
SSPBUF = %00001111 ' Transmit the 8bit data to register
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
GOSUB Stop_I2C ' Complete TX data
RETURN
'||||||||||||||||||| end Gyroscope configuration ||||||||||||||||||||||||
Gyro register reading routine:
Code:
'//////////////////// Gyroscope XYZ data reading ////////////////////////
' Recommended way of reading sequential registers
'
' Master Slave Note
' 1. ST Sends Start condition
' 2. SAD+W Sends Slave Address including Write bit
' 3. SAK Sends Acknowledge
' 4. SUB Sends Sub Address (1st register address to read)
' 5. SAK Sends Acknowledge
' 6. SR Sends a Repeated Start condition
' 7. SAD+R Sends Slave Address including Read bit
' 8. SAK Sends Acknowledge
' 9. Data Sends Data
' 10. MAK Sends Acknowledge
' 11. Data Sends Data
' 12. MAK Sends Acknowledge
' 13. Data Sends Data (Process repeated)
' 14. NMAK No Acknowledgement sent after last register read
' 15. SP Sends Stop condition ending Read process
'
' Reading all XYZ registers and loading the array takes 237us worst case.
'////////////////////////////////////////////////////////////////////////
Read_G_REG:
' Generate Start condition
GOSUB Start_Gyr
' Send first register to read with bit #1 set indicating READ and bit #7
' set indicating multiple reads
SSPBUF = %10101000 ' Register 28h with 7 set = $A8
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
' Wait for ACK from device
WHILE SSPCON2.6 : WEND ' Wait until device sends an ACK
' Send Repeated Start condition
SSPCON2.1 = 1 ' Send Repeated Start condition
WHILE SSPCON2.1 = 1: WEND ' Wait until MSSP module finishes task
' Send device address with Read bit set
SSPBUF = $D7 ' Transmit device address w/READ bit
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
' Wait for ACK from device
WHILE SSPCON2.6 : WEND ' Wait until device sends an ACK
'///////////////////// Read the next 6 registers ////////////////////////
' This portion loops through Read sequence 6 times. The Master sends an
' ACK after each read indicating "send another" so no ACK is sent after
' the 6th data packet, a Stop Condition is sent instead to end the READ.
'////////////////////////////////////////////////////////////////////////
FOR e = 6 TO 11
' Receive the 8 bit data from gyroscope
SSPCON2.3 = 1 ' Enable the Receiver to clock in data
WHILE !SSPSTAT.0: WEND ' Wait until Buffer Full bit is set
XYZ_RAM[e] = SSPBUF ' Load each XYZ_RAM byte in array
' Master sends ACK for first 5 data packets
IF e != 11 THEN
SSPCON2.4 = 1 ' Initiate Acknowledge sequence
WHILE SSPCON2.4 = 1: WEND ' Wait until Acknowledge sequence Idle
ENDIF
NEXT e
' Send Stop condition to end Read function
GOSUB Stop_I2C ' Complete RX data read
RETURN
'||||||||||||||||||| end Gyroscope XYZ data reading |||||||||||||||||||||
I2C Start and Stop routines:
Code:
'=========================================================================
' Generate Gyroscope Start condition
'=========================================================================
Start_Gyr:
' Start condition to the transmit device address
SSPCON2.0 = 1 ' Generate Start condition
WHILE SSPCON2.0 = 1: WEND ' Wait until MSSP module ready to TX
PIR1.3 = 0 ' Clear the Interrupt flag
SSPBUF = $D6 ' Transmit address that includes WRITE bit
WHILE SSPSTAT.2: WEND ' Wait until MSSP module finishes task
RETURN
'=========================================================================
' Stop I2C routine
'=========================================================================
Stop_I2C:
SSPCON2.2 = 1 ' Initiate Stop condition
WHILE SSPCON2.2: WEND ' Wait until MSSP module finishes task
PIR1.3 = 0 ' Clear interrupt flag
@ nop ; Had to slow it down or it didn't work!
@ Nop ; Only 1 was needed but 1 more won't hurt
RETURN
Bookmarks