简体   繁体   English

STM32F429-DISC1上的陀螺仪表现异常

[英]Gyroscope on STM32F429-DISC1 is behaving strangely

I'm quite new in STM32 world, and I have a problem with the on-board L3GD20 gyroscope on teh STM32F429-DISC1 board. 我在STM32世界中是一个新手,我在STM32F429-DISC1板上的板载L3GD20陀螺仪上遇到问题。

I had troubles in getting it running (the gyroscope was constantly sending the same data, even after reset or power down) and after I finally managed to get it working (by sending instructions a couple of times), I saw strange results (both on x-axis, y and z) (see graph below). 我在使其运行时遇到了麻烦(即使在重置或掉电之后,陀螺仪仍在不断发送相同的数据),并且在最终设法使其工作(通过多次发送指令)后,我看到了奇怪的结果(两者都x轴,y和z)(请参见下图)。

Am I missing something, or should I do something with the raw data, that will smooth it? 我会丢失某些东西,还是应该对原始数据进行某些处理以使数据平滑? Is there a possibility, that the IC is defective? IC是否可能有缺陷?

I am using Atollic TrueStudio v9.0 for STM32 with STM32F429-DISC1. 我正在将STM32的Atollic TrueStudio v9.0与STM32F429-DISC1一起使用。

Here is my code: 这是我的代码:

#include "stm32f4xx.h"
#include "stm32f429i_discovery.h"
#include "stdio.h"
volatile uint32_t elapsed = 0;

#define CS_gyro_start   GPIO_ResetBits( GPIOC, GPIO_Pin_1 )
#define CS_gyro_stop    GPIO_SetBits( GPIOC, GPIO_Pin_1 )

void DelayMS( int time ){
    elapsed = time;
    while( elapsed > 0 );
}

void SysTick_Handler(){
    if( elapsed > 0 ) --elapsed;
}

void SendChar( char ch ){
    while( USART_GetFlagStatus( USART1, USART_FLAG_TXE ) == RESET ){}
    USART_SendData( USART1, ch );
}
void sendString( const char *s ){
    while( *s ){
        SendChar( *s++ );
    }
}
int _write( int file, char *ptr, int len ){
    sendString( ptr );
return len;
}  //sadly this doesn't work with float variables


void initialize( void ){
    RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA |
                            RCC_AHB1Periph_GPIOC |
                            RCC_AHB1Periph_GPIOF, ENABLE );

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI5 |
                            RCC_APB2Periph_SYSCFG |
                            RCC_APB2Periph_USART1, ENABLE );

    GPIO_InitTypeDef        gpio;
    USART_InitTypeDef       usart;
    SPI_InitTypeDef         spi;

    GPIO_StructInit(    &gpio );
    USART_StructInit(   &usart );
    SPI_StructInit(     &spi );

//usart
    GPIO_PinAFConfig( GPIOA, GPIO_PinSource10, GPIO_AF_USART1 );
    GPIO_PinAFConfig( GPIOA, GPIO_PinSource9, GPIO_AF_USART1 );

    gpio.GPIO_Mode =        GPIO_Mode_AF;
    gpio.GPIO_OType =       GPIO_OType_PP;
    gpio.GPIO_PuPd =        GPIO_PuPd_NOPULL;
    gpio.GPIO_Pin =         GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_Init( GPIOA, &gpio );

    usart.USART_BaudRate =  115200;
    USART_Init( USART1, &usart );

    USART_Cmd( USART1, ENABLE );

//spi
    GPIO_PinAFConfig( GPIOF, GPIO_PinSource7, GPIO_AF_SPI5 );
    GPIO_PinAFConfig( GPIOF, GPIO_PinSource9, GPIO_AF_SPI5 );
    GPIO_PinAFConfig( GPIOF, GPIO_PinSource8, GPIO_AF_SPI5 );

    //SS
    gpio.GPIO_Pin =     GPIO_Pin_1;
    gpio.GPIO_Mode =    GPIO_Mode_OUT;
    gpio.GPIO_OType =   GPIO_OType_PP;
    gpio.GPIO_PuPd =    GPIO_PuPd_NOPULL;
    GPIO_Init( GPIOC, &gpio );
    GPIO_SetBits( GPIOC, GPIO_Pin_1 );

    //SCK, MOSI
    gpio.GPIO_Pin =     GPIO_Pin_9 | GPIO_Pin_7;
    gpio.GPIO_OType =   GPIO_OType_PP;
    gpio.GPIO_Mode =    GPIO_Mode_AF;
    gpio.GPIO_Speed =   GPIO_Speed_50MHz;
    gpio.GPIO_PuPd =    GPIO_PuPd_NOPULL;
    GPIO_Init( GPIOF, &gpio );

    //MISO
    gpio.GPIO_Pin =     GPIO_Pin_8;
    gpio.GPIO_OType =   GPIO_OType_PP;
    gpio.GPIO_Mode =    GPIO_Mode_AF;
    gpio.GPIO_Speed =   GPIO_Speed_50MHz;
    gpio.GPIO_PuPd =    GPIO_PuPd_NOPULL;
    GPIO_Init( GPIOF, &gpio );

    spi.SPI_Mode =                  SPI_Mode_Master;
    spi.SPI_NSS =                   SPI_NSS_Soft;
    spi.SPI_BaudRatePrescaler =     SPI_BaudRatePrescaler_256;
    SPI_Init( SPI5, &spi );
    SPI_Cmd( SPI5, ENABLE );

}


uint8_t SPI_sendByte( uint8_t byte_ ){
    while( SPI_I2S_GetFlagStatus( SPI5, SPI_I2S_FLAG_TXE ) == RESET ){}
    SPI_I2S_SendData( SPI5, byte_ );

    while( SPI_I2S_GetFlagStatus( SPI5, SPI_I2S_FLAG_RXNE ) == RESET ){}
return SPI_I2S_ReceiveData( SPI5 );
}

void SPI_writeData( uint8_t address, uint8_t byteToWrite ){
    CS_gyro_start;
        SPI_sendByte( address );
        SPI_sendByte( byteToWrite );
    CS_gyro_stop;
}

void GetGyroValues( uint16_t *x, uint16_t *y, uint16_t *z ){
    CS_gyro_start;
        SPI_sendByte( 0x29 | 0x80 );
        *x = SPI_sendByte( 0xff );
    CS_gyro_stop;
    CS_gyro_start;
        SPI_sendByte( 0x28 | 0x80 );
        *x |= (SPI_sendByte( 0xff ) << 8);
    CS_gyro_stop;

    CS_gyro_start;
        SPI_sendByte( 0x2B | 0x80 );
        *y = SPI_sendByte( 0xff );
    CS_gyro_stop;
    CS_gyro_start;
        SPI_sendByte( 0x2A | 0x80 );
        *y |= (SPI_sendByte( 0xff ) << 8);
    CS_gyro_stop;

    CS_gyro_start;
        SPI_sendByte( 0x2D | 0x80 );
        *z = SPI_sendByte( 0xff );
    CS_gyro_stop;
    CS_gyro_start;
        SPI_sendByte( 0x2C | 0x80 );
        *z |= (SPI_sendByte( 0xff ) << 8);
    CS_gyro_stop;
}

int main( void ){
    SysTick_Config( SystemCoreClock / 1000 );
    initialize();

    SPI_writeData(0x20, 0xff);  //power on, settings from TM-library & datasheet
    SPI_writeData(0x21, 0x00);  //high-pass filter settings
    SPI_writeData(0x24, 0x10);  //high-pass filter en
    SPI_writeData(0x23, 0x20);  //scale 2000

    uint16_t x, y, z;
    while( 1 ){
        GetGyroValues( &x, &y, &z );
        printf( "x: %d\r\n", x );

        DelayMS( 100 );

    }
}


uint32_t sEE_TIMEOUT_UserCallback(void)
{
  /* TODO, implement your code here */
  while (1)
  {
  }
}//   This is required by Atollic

Here is a sample graph showing the changes on x-axis. 这是显示x轴变化的示例图。 (the discovery board was more or less at 45 degrees, when it's at 0 degrees - laying down, then the output is a stable 65000) (发现板大致处于45度,当处于0度时-放下,则输出是稳定的65000) COM端口视图

From the L3GD20 app note : L3GD20应用笔记中

在此处输入图片说明

Note the last part "expressed as a two's complement number" ; 注意最后一部分“表示为二进制补码” you are incorrectly interpreting the data as unsigned . 您错误地将数据解释为unsigned It looks like the value is hovering around zero; 值似乎在零附近徘徊; or actually it looks like you are holding it rather unsteadily in a position, but certainly not rotating it continuously as a steady rate. 或实际上看起来好像您将它不稳定地保持在某个位置,但是肯定不会以稳定的速度连续旋转它。 The device is a gyroscope not an accelerometer . 该设备是陀螺仪,而不是加速度计 It measures angular velocity not acceleration (or tilt - ie acceleration due to gravity). 它测量的是角速度, 而不是加速度(或倾斜度-即由于重力引起的加速度)。 While stationary you would expect zero on all axes. 静止时,所有轴都期望为零。 What your graph shows is probably your hand shaking trying to hold it at 45 degrees. 您的图形显示的可能是您的手在试图将其保持45度时摇动。

void GetGyroValues( int16_t *x, int16_t *y, int16_t *z )

should be more sucessful, and of course: 应该会更成功,当然:

    int16_t x, y, z;

You can get an approximate measure of change of angle by integrating angular velocity, but not absolute angle. 您可以通过积分角速度而不是绝对角度来获得近似的角度变化量度。 Even then you may have to calibrate frequently for zero - a small non-zero bias in integration will manifest itself as a false slow rotation. 即使那样,您可能也必须经常校准零-积分中的一个很小的非零偏差将表现为错误的缓慢旋转。

As from the datasheet L3GD20 , table 17, the OUT_XL is at address 0x28 and OUT_XH at address 0x29. 从数据表L3GD20的表17开始,OUT_XL位于地址0x28,而OUT_XH位于地址0x29。 So you have to left shift the value with address 0x29 not 0x28 and vica versa. 因此,您必须左移地址0x29而不是0x28的值,反之亦然。 This also with Y and Z values. 这也包含Y和Z值。

void GetGyroValues( int16_t *x, int16_t *y, int16_t *z ){
    CS_gyro_start;
    SPI_sendByte( 0x28 | 0x80 );
    *x = SPI_sendByte( 0xff );
    CS_gyro_stop;
    CS_gyro_start;
    SPI_sendByte( 0x29 | 0x80 );
    *x |= (SPI_sendByte( 0xff ) << 8);
    CS_gyro_stop;

    CS_gyro_start;
    SPI_sendByte( 0x2A | 0x80 );
    *y = SPI_sendByte( 0xff );
    CS_gyro_stop;
    CS_gyro_start;
    SPI_sendByte( 0x2B | 0x80 );
    *y |= (SPI_sendByte( 0xff ) << 8);
    CS_gyro_stop;

    CS_gyro_start;
    SPI_sendByte( 0x2C | 0x80 );
    *z = SPI_sendByte( 0xff );
    CS_gyro_stop;
    CS_gyro_start;
    SPI_sendByte( 0x2D | 0x80 );
    *z |= (SPI_sendByte( 0xff ) << 8);
    CS_gyro_stop;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM