- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 9 von 9

Thema: IMU über SPI steigt nach wenigen Sekunden aus

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Einen vollständigen Code hätte ich schon ganz gerne, sonst bin ich raus, ohne Grundlage kann man nur schwer etwas vermuten....
    Der ganze Code muss nicht sein, aber alle Routinen die du aufrufst (v.a. MX_GPIO_Init() und alle anderen Peripherie-Initialisierungen) sollten schon vorhanden sein.
    Auch wenn ich sehe, dass du das wohl mit Cube erstellst hast und somit SW-Fehler unwahrscheinlich sind, würde ein Blick darauf wohl dennoch nicht schaden.

    Beim Schaltplan ist es ähnlich, das ist kein Schaltplan, sondern lediglich ein kleiner Ausschnitt davon. Was soll man da erkennen?

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    14.04.2005
    Ort
    Freiberg
    Alter
    41
    Beiträge
    311
    Hallo Chris,

    dann also hier die fehlenden Funktionen im Code und der Schaltplan des Nucleo-Shields. Sollte dir noch etwas fehlen, gib Bescheid!

    Grüß, NRicola

    Code:
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "stdbool.h"
    #include "math.h"
    #include "../Peripherals/LSM6DS3.h"        // Funktionen sind hier angehangen (siehe unten)
    #include "../Peripherals/OLED_128x32.h"
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
        
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    I2C_HandleTypeDef hi2c3;
    
    SPI_HandleTypeDef hspi2;
    
    UART_HandleTypeDef huart2;
    DMA_HandleTypeDef hdma_usart2_rx;
    
    /* USER CODE BEGIN PV */
        const uint8_t IMU_datlength = 8;        // die letzten x Messwerte werden mitgespeichert
        struct IMU_Struct IMU1;                // besteht aus IMU1.status, sowie 6 Arrays [0:IMU_datlength-1] für acc und gyr in x,y,z
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_DMA_Init(void);
    static void MX_USART2_UART_Init(void);
    static void MX_SPI2_Init(void);
    static void MX_I2C3_Init(void);
    /* USER CODE BEGIN PFP */
            
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
    
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
    
      /* USER CODE END 1 */
    
      /* MCU Configuration--------------------------------------------------------*/
    
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
    
      /* USER CODE BEGIN Init */
    
      /* USER CODE END Init */
    
      /* Configure the system clock */
      SystemClock_Config();
    
      /* USER CODE BEGIN SysInit */
    
      /* USER CODE END SysInit */
    
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_DMA_Init();
      MX_USART2_UART_Init();
      MX_SPI2_Init();
      MX_I2C3_Init();
      /* USER CODE BEGIN 2 */
    
    
        IMU1.status=0;
        for(uint8_t i=0;i<IMU_datlength-1;i++){
                IMU1.acc_x[i] = 0;
                IMU1.acc_y[i] = 0;
                IMU1.acc_z[i] = 0;
                IMU1.gyr_x[i] = 0;
                IMU1.gyr_y[i] = 0;
                IMU1.gyr_z[i] = 0;
        }
    
        //--------------------------------
    
        Mot001_SS_Disable();    // SS auf high
        IMU1_SS_Disable();    // SS auf high
        HAL_Delay(20);        // 20ms start-up time für IMUs
        
        //        OLED-Display
        uint16_t OLED_refresh_cntr=0;
        uint16_t OLED_refresh_max=5;
        OLED_Init();
        OLED_Clear_Screen();
        OLED_IMU1_vars();
        
        
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    
            IMU1 = IMU1_Read_Values();
            if(OLED_refresh_cntr>=OLED_refresh_max){    OLED_refresh_cntr=0; OLED_IMU1_vars();    // Messwerte des IMU1 anzeigen
            }else{                        OLED_refresh_cntr++;
            }
            
      }
      /* USER CODE END 3 */
    }
    
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
      /** Configure the main internal regulator output voltage
      */
      __HAL_RCC_PWR_CLK_ENABLE();
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
      /** Initializes the RCC Oscillators according to the specified parameters
      * in the RCC_OscInitTypeDef structure.
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /** Initializes the CPU, AHB and APB buses clocks
      */
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /**
      * @brief I2C3 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_I2C3_Init(void)
    {
    
      /* USER CODE BEGIN I2C3_Init 0 */
    
      /* USER CODE END I2C3_Init 0 */
    
      /* USER CODE BEGIN I2C3_Init 1 */
    
      /* USER CODE END I2C3_Init 1 */
      hi2c3.Instance = I2C3;
      hi2c3.Init.ClockSpeed = 400000;
      hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
      hi2c3.Init.OwnAddress1 = 0;
      hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
      hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
      hi2c3.Init.OwnAddress2 = 0;
      hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
      hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
      if (HAL_I2C_Init(&hi2c3) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN I2C3_Init 2 */
    
      /* USER CODE END I2C3_Init 2 */
    
    }
    
    /**
      * @brief SPI2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_SPI2_Init(void)
    {
    
      /* USER CODE BEGIN SPI2_Init 0 */
    
      /* USER CODE END SPI2_Init 0 */
    
      /* USER CODE BEGIN SPI2_Init 1 */
    
      /* USER CODE END SPI2_Init 1 */
      /* SPI2 parameter configuration*/
      hspi2.Instance = SPI2;
      hspi2.Init.Mode = SPI_MODE_MASTER;
      hspi2.Init.Direction = SPI_DIRECTION_2LINES;
      hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
      hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
      hspi2.Init.NSS = SPI_NSS_SOFT;
      hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
      hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi2.Init.CRCPolynomial = 10;
      if (HAL_SPI_Init(&hspi2) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN SPI2_Init 2 */
    
      /* USER CODE END SPI2_Init 2 */
    
    }
    
    /**
      * @brief USART2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_USART2_UART_Init(void)
    {
    
      /* USER CODE BEGIN USART2_Init 0 */
    
      /* USER CODE END USART2_Init 0 */
    
      /* USER CODE BEGIN USART2_Init 1 */
    
      /* USER CODE END USART2_Init 1 */
      huart2.Instance = USART2;
      huart2.Init.BaudRate = 115200;
      huart2.Init.WordLength = UART_WORDLENGTH_8B;
      huart2.Init.StopBits = UART_STOPBITS_1;
      huart2.Init.Parity = UART_PARITY_NONE;
      huart2.Init.Mode = UART_MODE_TX_RX;
      huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart2.Init.OverSampling = UART_OVERSAMPLING_16;
      if (HAL_UART_Init(&huart2) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN USART2_Init 2 */
    
      /* USER CODE END USART2_Init 2 */
    
    }
    
    /**
      * Enable DMA controller clock
      */
    static void MX_DMA_Init(void)
    {
    
      /* DMA controller clock enable */
      __HAL_RCC_DMA1_CLK_ENABLE();
    
      /* DMA interrupt init */
      /* DMA1_Stream5_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
    
    }
    
    /**
      * @brief GPIO Initialization Function
      * @param None
      * @retval None
      */
    static void MX_GPIO_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOA, LED_GN_Pin|LED_RD_Pin|Mot003_Status_Pin|Mot002_Status_Pin
                              |IMU2_SS_Pin|IMU3_SS_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOC, IMU1_Status_Pin|IMU2_Status_Pin|Mot001_Status_Pin|Mot003_SS_Pin
                              |IMU3_Status_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|IMU1_SS_Pin|Mot001_SS_Pin|HDMode_LED_Pin
                              |Mot002_SS_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pins : Reset_SW_Pin Hall_Detection_Button_PC14_Pin */
      GPIO_InitStruct.Pin = Reset_SW_Pin|Hall_Detection_Button_PC14_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
      /*Configure GPIO pins : LED_GN_Pin LED_RD_Pin Mot003_Status_Pin Mot002_Status_Pin
                               IMU2_SS_Pin IMU3_SS_Pin */
      GPIO_InitStruct.Pin = LED_GN_Pin|LED_RD_Pin|Mot003_Status_Pin|Mot002_Status_Pin
                              |IMU2_SS_Pin|IMU3_SS_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /*Configure GPIO pins : IMU1_Status_Pin IMU2_Status_Pin Mot001_Status_Pin Mot003_SS_Pin
                               IMU3_Status_Pin */
      GPIO_InitStruct.Pin = IMU1_Status_Pin|IMU2_Status_Pin|Mot001_Status_Pin|Mot003_SS_Pin
                              |IMU3_Status_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
      /*Configure GPIO pins : PB0 IMU1_SS_Pin Mot001_SS_Pin HDMode_LED_Pin
                               Mot002_SS_Pin */
      GPIO_InitStruct.Pin = GPIO_PIN_0|IMU1_SS_Pin|Mot001_SS_Pin|HDMode_LED_Pin
                              |Mot002_SS_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
      /*Configure GPIO pins : Mot002_Error_Pin_Pin Mot003_Error_Pin_Pin Mot001_Error_Pin_Pin HDMode_SW_Pin */
      GPIO_InitStruct.Pin = Mot002_Error_Pin_Pin|Mot003_Error_Pin_Pin|Mot001_Error_Pin_Pin|HDMode_SW_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    }
    
    /* USER CODE BEGIN 4 */
    
    /* USER CODE END 4 */
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
    
      /* USER CODE END Error_Handler_Debug */
    }
    
    #ifdef  USE_FULL_ASSERT
    /**
      * @brief  Reports the name of the source file and the source line number
      *         where the assert_param error has occurred.
      * @param  file: pointer to the source file name
      * @param  line: assert_param error line source number
      * @retval None
      */
    void assert_failed(uint8_t *file, uint32_t line)
    {
      /* USER CODE BEGIN 6 */
      /* User can add his own implementation to report the file name and line number,
         tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    
    
    
    //-------------------------------------------------------------------------------
    //---------- Inhalt LSM6DS3.c ---------------------------------------------------
    //-------------------------------------------------------------------------------
    
    void IMU1_config(void){
        
        const uint8_t CTRL1_XL_addr    = 0x10;
        const uint8_t CTRL1_XL_write    = 0x3B;        // 0011_10_11
        const uint8_t CTRL2_G_addr    = 0x11;
        const uint8_t CTRL2_G_write      = 0x34;    // 0011_01_0_0
    
        Send_2Bytes_IMU1(CTRL1_XL_addr,CTRL1_XL_write);
        Send_2Bytes_IMU1(CTRL2_G_addr,CTRL2_G_write);
    }
    
    struct IMU_Struct IMU1_Read_Values(void){
        const uint8_t WHO_AM_I = 0x69;            // ist die korrekte Antwort, falls der Sensor da ist
        const uint8_t addr_WHO_AM_I_read = 0x8F;
        const uint8_t addr_CTRL1_XL_read = 0x90;
        const uint8_t addr_acc_x_l_read  = 0xA8;
        const uint8_t addr_acc_x_h_read  = 0xA9;
        //------------------------------        
        //--------------------------------------------------
        if (Read_1Byte_IMU1(addr_WHO_AM_I_read) == WHO_AM_I){    // Wenn IMU1 auf WHO_AM_I reagiert,
            IMU1.status=1;                    // 
            if (Read_1Byte_IMU1(addr_CTRL1_XL_read) == 0){        IMU1_config();        // Falls der Accelerometer im Sensor nicht korrekt konfiguriert ist, konfiguriere nochmal neu
                                        HAL_GPIO_TogglePin(LED_GN_GPIO_Port, LED_GN_Pin);
            }
        }else{
            IMU1.status=0;                    // Status: Sensor ist nicht angeschlossen
        }
        if(IMU1.status==1){                    // Wenn IMU1 erkannt, 
            IMU1_Status_SET();                // dann Status-LED anschalten
        }else{
            IMU1_Status_RESET();                // ansonsten Status-LED ausschalten
        }
        
        IMU1.acc_x[IMU_datlength-1]=Read_1Byte_IMU1(addr_acc_x_l_read);    // einen Messwert lesen
        return IMU1;
    }
    
    void Send_2Bytes_IMU1(uint8_t Byte1,uint8_t Byte2){
            const uint8_t timeout = 10;
            uint8_t TxBuffer[2];
                TxBuffer[0]=Byte1;
                TxBuffer[1]=Byte2;
            IMU1_SS_Enable();                // SS auf low
            HAL_SPI_Transmit(&hspi2, TxBuffer, 2, timeout); 
            IMU1_SS_Disable();                // SS auf high
    }
    
    uint8_t Read_1Byte_IMU1(uint8_t Byte){
            const uint8_t timeout = 10;
            uint8_t TxBuffer[2];
                TxBuffer[0]=Byte;            // Adresse des Read-Bytes
                TxBuffer[1]=0;
            uint8_t RxBuffer[2];
            IMU1_SS_Enable();                // SS auf low
            HAL_SPI_TransmitReceive(&hspi2, TxBuffer, RxBuffer, 2, timeout);
            IMU1_SS_Disable();                // SS auf high
            return RxBuffer[1];
    }
    Angehängte Dateien Angehängte Dateien
    Gurken schmecken mir nicht, wenn sie Pelz haben!

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    So ist das schon viel besser
    Also ich kann in deinem Code keine Pin-Definitionen für die SPI-Pins, und auch für die anderen Peripherie-Pins erkennen (bis auf SS und deine Status-Pins).
    Leider fehlen aber wieder ein paar Infos, die Defines, die du verwendest, kennen wir alle nicht...
    Auch finde ich den Code im allgemeinen sehr "unschön", hab mich nie mit Cube anfreunden können.
    Ich programmiere die STM32 nach wie vor mit der SPL, auch wenns veraltet ist, damit bin ich "groß" geworden.
    Auf die schnelle hab ich dir mal was zusammengebastelt, kanns leider nicht testen, sollte aber tun:
    Code:
    #include "stm32f4xx_conf.h"
    #include "arm_math.h"
    
    
    
    #define IMU1_SS_LOW         GPIOB->ODR &= ~GPIO_Pin_12
    #define IMU1_SS_HIGH        GPIOB->ODR |= GPIO_Pin_12
    
    #define LSM6DS3WRITEREG     0x00
    #define LSM6DS3READREG      0x80
    
    #define WHOAMIREG           0x0F
    #define WHOAMIVALUE         0x69
    
    
    
    int main(void);
    void InitSpi2(uint16_t Prescaler);
    uint8_t Spi2Transfer(uint8_t Data);
    void Delay(uint32_t t);
    
    
    
    volatile uint8_t WhoAmI;
    
    
    int main(void){
    
        SystemInit();
        
        InitSpi2(2);
        
        while(1)
        {
            Delay(1000); //! just a 'random' Delay
            IMU1_SS_LOW;
            WhoAmI = Spi2Transfer(WHOAMIREG | LSM6DS3READREG); //! read out
            IMU1_SS_HIGH;
            if(WhoAmI==WHOAMIVALUE)
            {
                //! Correct answer
            }else
            {
                //! False or no answer
            }
        }
    }
    
    
    
    void Delay(uint32_t t){
        for(uint32_t i=0;i<t;i+=1) ;
    }
    
    
    
    
    void InitSpi2(uint16_t Prescaler){
        GPIO_InitTypeDef GPIO_InitTypeDefStruct;
        SPI_InitTypeDef SPI_InitTypeDefStruct;
    
    
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
        
    
        SPI_Cmd(SPI2, DISABLE);
        if(Prescaler==2)
        {
            SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
        }else if(Prescaler==4)
        {
            SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
        }
        else if(Prescaler==128)
        {
            SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
        }else
        {
            SPI_InitTypeDefStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
        }
        SPI_InitTypeDefStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitTypeDefStruct.SPI_Mode = SPI_Mode_Master;
        SPI_InitTypeDefStruct.SPI_DataSize = SPI_DataSize_8b;
        SPI_InitTypeDefStruct.SPI_NSS = SPI_NSS_Soft;
        SPI_InitTypeDefStruct.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitTypeDefStruct.SPI_CPOL = SPI_CPOL_Low;
        SPI_InitTypeDefStruct.SPI_CPHA = SPI_CPHA_1Edge;
        SPI_Init(SPI2, &SPI_InitTypeDefStruct);
    
    
        
        //! SCK, MISO, MOSI
        GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitTypeDefStruct);
    
    
        //! SS
        GPIO_InitTypeDefStruct.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitTypeDefStruct.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitTypeDefStruct.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitTypeDefStruct.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitTypeDefStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_Init(GPIOB, &GPIO_InitTypeDefStruct);
    
        //! Connect Pins to Peripheral
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
    
        //! ENABLE SPI2
        SPI_Cmd(SPI2, ENABLE);
    
        //! PULL SS HIGH
        IMU1_SS_HIGH;
    }
    
    uint8_t Spi2Transfer(uint8_t Data){
        uint8_t dump = 0;
    
        while(!(SPI2->SR&SPI_SR_TXE));
        SPI2->DR = Data;
        while(!(SPI2->SR&SPI_SR_RXNE));
        dump = SPI2->DR;
        return (dump);
    }
    Wenn du ein Nucleo-Board nutzt, kannst du wahrscheinlich über SWD debuggen? Das ist schonmal eine sehr große Hilfe.
    Für den Anfang würde ich alles unnütze (LED, LCD, etc...) weglassen und nurmal die Kommunikation zum laufen bringen.
    Welche IDE benutzt du?

    Gruß
    Chris

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    14.04.2005
    Ort
    Freiberg
    Alter
    41
    Beiträge
    311
    Hallo zusammen, Hallo Chris,

    ich bitte um Entschuldigung für die späte Rückmeldung. Ich war in der Zeit nicht untätig. Chris, vielen Dank für deine Hilfe. Tatsächlich gab es ein Init-Problem: zwar war das angesprochene IMU korrekt initialisiert. Allerdings haben die SS-Initialisierungen der anderen IMUs gefehlt. Immer wenn ich einen der anderen IMUs angeschlossen habe, haben die sich natürlich auch angesprochen gefühlt (SS noch low/aktiv gewesen). Das hat dann auf MISO ein großes Chaos verursacht.

    Da ich mehr in der Hardware das Problem vermutet habe, habe ich da mal etwas beleuchten können. Und ich behaupte mal den Übeltäter gefunden zu haben:
    Die Spannung! Welche Spannung? Alle!
    Der LSM6DS3 möchte eine Versorgungsspannung von 1,7...3,6V haben.
    "Absolute maximum Ratings": -0,3...4,8V
    An den Signalleitungen: 0,3...Vcc+0,3V

    Klingt an sich erstmal im Limit, wenn ich eine Versorgungs- und SPI-Nennspannung von 3,3V anlege. Die langen Leitungen sind hier aber nicht gut. Lang bezieht sich schon auf 0,2-0,4m pro Sensor (Summiert sich über alle Sensoren des gleichen Busses). Wie oben schon geschrieben, nutze ich in Reihe geschaltete Widerstände, um Überschwinger an den Flanken abzumildern. Mein bisheriger Aufbau:

    MCU ____________________________________ IMU
    MOSI -|100Ohm|-------------------------- MISO
    SCLK -|100Ohm|-------------------------- SCLK
    MISO --------------------------|100Ohm|- MISO
    SS ------------------------------------- SS


    Das reicht allerdings nicht. Ich habe mal die Spannung (Vcc für IMU und Signale) ein bisschen zurückgenommen: bei ca. 2V funktioniert alles.
    Als es funktionierte, konnte ich endlich auch mal mit dem Oszi ran - siehe Bild unten.
    Durch die Leitungen kam es teilweise zu erheblichen Über- und Unterschwingern. Vor allem die negativen Spannungen mögen die IMUs nicht. Ab ca. -1V auf irgendeiner der Signalleitungen steigen sie aus.

    Ich habe dazu mal eine kleine Variation durchgeführt. Siehe zweites Bild im Anhang. Aufgelistet ist der Spannungsbereich, bis zu dem der IMU noch sauber im Betrieb war (gefühlt ca. 95% aller Signale vom Sensor i.O.). Im Durchschnitt ist er 0,02V unter dem min-Wert bzw. 0,15V über dem max-Wert permanent ausgestiegen. Auf den Wegen dorthin hat der Anteil der fehlerhaften Übertragungen zugenommen.
    Beim Eintrag "Diode" wird eine Diode von GND ----|>|---- SCLK gespannt. Beim blau Geschriebenen war es eine 1N4148, beim schwarz geschriebenen eine 1N4005. Wie man sieht, funktionierte die 1N4005 besser.

    Man sieht, dass es einen großen Unterschied machen kann, wo man diese Widerstände platziert - auf der IMU-Seite oder auf der µC-Seite. Wenn man auf die 3,3V kommen möchte, ist wohl wichtig, dass auf beiden Seiten Widerstände vorhanden sind.

    Fazit für mich:
    Ich werde jetzt nur noch mit 2-2,2V unterwegs sein und damit hoffentlich auch mit meinen Ziel-Leitungslängen von 1m klarkommen.

    Ich hoffe, dass jemand anderes von dieser Erkenntnis hier auch profitieren kann!

    Grüß, NRicola
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken Variation_Widerstände.jpg   Oszi_SS_SCLK_komm.jpg  
    Gurken schmecken mir nicht, wenn sie Pelz haben!

Ähnliche Themen

  1. nodeMCU zu nodeMCU: keine Kommunikations-Verbindung mehr nach wenigen Minuten
    Von HaWe im Forum NodeMCU-Board und ESP8266, ESP32-Serie
    Antworten: 0
    Letzter Beitrag: 02.10.2017, 15:01
  2. Elektromobilität: Die Nachfrage nach Elektroautos steigt - aber bei uns nicht
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 1
    Letzter Beitrag: 13.06.2017, 13:57
  3. Weltrekord: Kleiner Quadrocopter steigt in knapp 4 Sekunden um 100 Meter
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 25.02.2016, 08:10
  4. Verstärker geht nach wenigen Sekunden aus
    Von Cysign im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 27.12.2014, 05:24
  5. LCD Display steigt nach einiger Zeit aus
    Von surfer007 im Forum AVR Hardwarethemen
    Antworten: 10
    Letzter Beitrag: 04.12.2007, 15:07

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress