|
楼主 |
发表于 2012-5-18 08:44:25
|
显示全部楼层
哇,楼上的!
这个程序你写的?请指点一下以下语句:
1,#define ADDR 0xD0;这个D0是怎么得来的?L3G4200工厂代码是1101,后面的四位中前三位是要根据电路联接来定的,是不是?
2,整个程序里面,我没有看到你对控制寄存器和数据寄存器的读写?请指明一下,相关的是那几句?
下面贴上我抄来的:
// Gyroscope Example
// by dimu
#define DI_ADDR_GYRO 0xD2 /*!< Gyro I2C address */
#define DIGYRO_REG_CTRL1 0x20 /*!< Gyro control register 1 */
#define DIGYRO_REG_CTRL2 0x21 /*!< Gyro control register 2 */
#define DIGYRO_REG_CTRL3 0x22 /*!< Gyro control register 3 */
#define DIGYRO_REG_CTRL4 0x23 /*!< Gyro control register 4 */
#define DIGYRO_REG_CTRL5 0x24 /*!< Gyro control register 5 */
#define DIGYRO_CTRL4_BLOCKDATA 0x80 /*!< Gyro block data update - output registers are not updated until MSB and LSB reading */
#define DIGYRO_CTRL4_BIGENDIAN 0x40 /*!< Gyro use big endian - MSB/LSB rather than LSB/MSB in output registers */
#define DIGYRO_CTRL4_SCALE_250 0x00 /*!< Gyro 250 degrees per second scale */
#define DIGYRO_CTRL4_SCALE_500 0x10 /*!< Gyro 500 degrees per second scale */
#define DIGYRO_CTRL4_SCALE_1000 0x20 /*!< Gyro 1000 degrees per second scale */
#define DIGYRO_CTRL4_SCALE_2000 0x30 /*!< Gyro 2000 degrees per second scale */
// These bytes set the full scale range of the gyroscope.
// it is important to define full_scale_range. Values are below.
//0x00 - 250 dps. Full scale range.
//0x10 - 500 dps. Full scale range.
//0x30 - 2000 dps. Full scale range.
#define full_scale_range DIGYRO_CTRL4_SCALE_2000
int divisor = 128; // This will be the divisor we divide the raw value of the gryscope by
// to get a scaled value on output. Default will be for 250 dps,
// but we'll define it again in start_gyro.
void start_gyro(byte port, byte range){
byte I2Csnd[];
//Write CTRL_REG1
// Enable all axes. Disable power down.
ArrayBuild(I2Csnd, DI_ADDR_GYRO, DIGYRO_REG_CTRL1, 0x0F);
if (I2CWrite(port, 0, I2Csnd) != NO_ERR)
PlayTone(TONE_A3, 500);
Wait(MS_10);
//Write CTRL_REG2
// No High Pass Filter
ArrayBuild(I2Csnd, DI_ADDR_GYRO, DIGYRO_REG_CTRL2, 0x00);
if (I2CWrite(port, 0, I2Csnd) != NO_ERR)
PlayTone(TONE_A3, 500);
Wait(MS_10);
//Write CTRL_REG3
// No interrupts. Data ready.
ArrayBuild(I2Csnd, DI_ADDR_GYRO, DIGYRO_REG_CTRL3, 0x08);
if (I2CWrite(port, 0, I2Csnd) != NO_ERR)
PlayTone(TONE_A3, 500);
Wait(MS_10);
//Write CTRL_REG4
ArrayBuild(I2Csnd, DI_ADDR_GYRO, DIGYRO_REG_CTRL4, range);
if (I2CWrite(port, 0, I2Csnd) != NO_ERR)
PlayTone(TONE_A3, 500);
Wait(MS_10);
//Write CTRL_REG5
ArrayBuild(I2Csnd, DI_ADDR_GYRO, DIGYRO_REG_CTRL5, 0x00);
if (I2CWrite(port, 0, I2Csnd) != NO_ERR)
PlayTone(TONE_A3, 500);
Wait(MS_10);
// Set divisor so that the output of our gyro axis readings can be turned
// into scaled values.
///////////////////////////////////////////////////////////////////////////
if (range == DIGYRO_CTRL4_SCALE_250)
divisor = 128; // Full scale range is 250 dps.
else if (range == DIGYRO_CTRL4_SCALE_500)
divisor = 64; // Full scale range is 500 dps.
else if (range == DIGYRO_CTRL4_SCALE_1000)
divisor = 32; // Full scale range is 1000 dps.
else if (range == DIGYRO_CTRL4_SCALE_2000)
divisor = 16; // Full scale range is 2000 dps.
}
// Gyro: axis_reading gets a byte of axis reading data
//
byte gyro_axis_reading_byte(byte port, byte reg){
byte I2Csnd[];
ArrayBuild(I2Csnd, DI_ADDR_GYRO, reg);
byte I2Crec[]; // We are looking for a single byte returned.
int count = 1;
byte result = 0x00;
if (I2CBytes(port, I2Csnd, count, I2Crec))
result = I2Crec[0];
else
PlayTone(TONE_A4, 500);
return result;
}
#define DIGYRO_REG_XLOW 0x28 /*!< Gyro x-axis low byte register (read only) */
#define DIGYRO_REG_XHIGH 0x29 /*!< Gyro x-axis high byte register (read only) */
#define DIGYRO_REG_YLOW 0x2A /*!< Gyro y-axis low byte register (read only) */
#define DIGYRO_REG_YHIGH 0x2B /*!< Gyro y-axis high byte register (read only) */
#define DIGYRO_REG_ZLOW 0x2C /*!< Gyro z-axis low byte register (read only) */
#define DIGYRO_REG_ZHIGH 0x2D /*!< Gyro z-axis high byte register (read only) */
// Gyro: gets a full axis reading, scaled to the full scale reading. Returns
// float in degrees per second.
float gyro_axis_reading(byte port, byte axis){
// byte axis definitions
// 0x00 - x-axis
// 0x01 - y-axis
// 0x02 - z-axis
if (axis > 0x02)
return 0.0;
byte reg_low[] = {DIGYRO_REG_XLOW, DIGYRO_REG_YLOW, DIGYRO_REG_ZLOW};
byte reg_high[] = {DIGYRO_REG_XHIGH, DIGYRO_REG_YHIGH, DIGYRO_REG_ZHIGH};
byte lb = gyro_axis_reading_byte(port, reg_low[axis]);
byte hb = gyro_axis_reading_byte(port, reg_high[axis]);
// NumOut( 0, LCD_LINE1-(axis*8), lb);
// NumOut(40, LCD_LINE1-(axis*8), hb);
// Assemble the final number by assembling the two bytes,
// and dividing it by the divisor (defined in the gyro startup,
// to get a properly scaled float.
int ival = lb + (hb<<8);
float val = ival/divisor;
return val;
}
#define DIGYRO_REG_WHOAMI 0x0F /*!< Gyro device identification register (read only) */
#define DIGYRO_REG_REFERENCE 0x25 /*!< Gyro reference register - stores the reference value used for interrupt generation */
#define DIGYRO_REG_OUTTEMP 0x26 /*!< Gyro temperature register (read only) - stores temperature data */
#define DIGYRO_REG_STATUS 0x27 /*!< Gyro status register (read only) */
#define DIGYRO_REG_FIFOCTRL 0x2E /*!< Gyro FIFO control register */
#define DIGYRO_REG_FIFOSRC 0x2F /*!< Gyro FIFO source register (read only) */
#define DIGYRO_REG_INT1_CFG 0x30 /*!< Gyro interrupt 1 config register */
task main(){
SetSensorLowspeed(S1);
start_gyro(S1, full_scale_range); // Fire up the gyro. Initialize it. Only needs to be done once.
float x_val, y_val, z_val; // Our assembled values.
while (true){
ClearScreen();
// Read the GYROSCOPE
x_val = gyro_axis_reading(S1, 0x00); // Get x-axis in dps.
y_val = gyro_axis_reading(S1, 0x01); // Get y-axis in dps.
z_val = gyro_axis_reading(S1, 0x02); // Get z-axis in dps.
byte who, ref, status, temp;
ReadI2CRegister(S1, DI_ADDR_GYRO, DIGYRO_REG_WHOAMI, who);
ReadI2CRegister(S1, DI_ADDR_GYRO, DIGYRO_REG_REFERENCE, ref);
ReadI2CRegister(S1, DI_ADDR_GYRO, DIGYRO_REG_STATUS, status);
ReadI2CRegister(S1, DI_ADDR_GYRO, DIGYRO_REG_OUTTEMP, temp);
NumOut(0, LCD_LINE1, x_val);
NumOut(0, LCD_LINE2, y_val);
NumOut(0, LCD_LINE3, z_val);
NumOut(0, LCD_LINE4, who);
NumOut(0, LCD_LINE5, ref);
NumOut(0, LCD_LINE6, status);
NumOut(0, LCD_LINE7, temp);
Wait(MS_500);
}
}
|
|