- LiFePO4 Speicher Test         
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
    32
    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

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    14.04.2005
    Ort
    Freiberg
    Alter
    42
    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, 14: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, 12: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, 07:10
  4. Verstärker geht nach wenigen Sekunden aus
    Von Cysign im Forum Elektronik
    Antworten: 3
    Letzter Beitrag: 27.12.2014, 04:24
  5. LCD Display steigt nach einiger Zeit aus
    Von surfer007 im Forum AVR Hardwarethemen
    Antworten: 10
    Letzter Beitrag: 04.12.2007, 14:07

Berechtigungen

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

Labornetzteil AliExpress