- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 21

Thema: EA DOMG-163 an SPI - Ich krieg die Krise

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.473
    Hallo botty

    Mensch, vielen Dank für deine Hilfe. Das werd ich so bald wie möglich mal ausprobieren.

    Ja...daß das LCD die Daten nicht schneller verarbeitet nur weil es diese über SPI reinbekommt ist mir schon klar. Dummerweise bietet das LCD über SPI keinen Rückkanal um festzustellen, ob es fertig ist oder nicht. Daher auch die lahme SPI.

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.473
    @botty:
    Ich habe deine Vorschläge ausprobiert...das Oszi zeigt immer noch keinen Mucks. Ich hab es zwischendurch mal mit dem Programm getestet, daß ich mit der HAL-Bibliothek gemacht habe. Das funktioniert.

    Mir ist aber was aufgefallen: Ich habe mal die Funktionen angeschaut, wo die Cube die Initialisierung der GPIOs und der SPI gemacht hat. Die Pins sind dieselben. Allerdings wird kein Pin als "Alternate Function" initialisiert.

    Cube-Code:
    Code:
     /*Configure GPIO pins : PC2 PC3 */
      GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
      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);
    Code:
    /* SPI2 init function */
    static void MX_SPI2_Init(void)
    {
    
      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_1EDGE;
      hspi2.Init.NSS = SPI_NSS_SOFT;
      hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
      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();
      }
    
    }
    Auch unter den Suchwort "AFR" oder "function" findet meine IDE im cubegenerierten Projekt nichts relevantes. Hat jemand eine Ahnung, was die HAL/Cube da eigentlich macht? Immerhin läuft die SPI da.

    Noch eine andere Auffälligkeit: Im Datenblatt ist das Alternate-Function-Register in zwei 16-Bit-Register je Port aufgeteilt. Meine IDE kennt aber nur ein AFR (mit AFR[0] oder AFR[1] kann der Compiler aber was anfangen), ich hätte aber eher sowas wie AFRL und AFRH erwartet. Das AFR als Array hab ich aus irgendeinem Inernet-Beispiel, aber kann das überhaupt stimmen?

    - - - Aktualisiert - - -

    Ich hab meinen Code mal im Debugger durchlaufen lassen. Beim Warten auf das Tx-Empty--Flag kommt er nicht mehr aus der zweiten While-Schleife raus...anscheinend läuft das SPI-Modul überhaupt nicht. Nur...warum? Takt ist drin.

    Code:
    //Sendet ein Befehlbyte ans LCD
    void SndBfhlLCD(char byte){
      GPIOC->BSRR |= GPIO_BSRR_BR_2;                //RS-Pin zurücksetzen
      SPI2->CR1 |= SPI_CR1_SPE;                     //SPI aktivieren
      while (SPI2->SR & SPI_SR_TXE){                //Warten bis Transmit-Register frei ist
      }
      SPI2->DR = byte;                              //Byte senden
      while (SPI2->SR & SPI_SR_TXE){                //Warten bis Transmit-Register frei ist
      }
      while (!(SPI2->SR & SPI_SR_BSY)){             //Warten bis laufende Übertragung abgeschlossen ist
      }
      //SPI2->CR1 &= ~SPI_CR1_SPE;                  //SPI deaktivieren
      //RS NICHT toggeln
    }

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    19.05.2015
    Beiträge
    69
    Hi,
    also zur HAL kann ich nicht viel sagen. Wenn ich hier einen stm32f446er mit SPI2 in CubeMX auswähle und den Transfer-Master-Mode mit Soft Nss eingebe, dann werden MOSI und CLK mit Alternate Function generiert?!? -> Keine Ahnung warum das bei mir anders ist als bei dir?!?

    Zu deinem Code:
    TXE und BSY verhalten sich genau umgekehrt wie du es benutzt und die ziehst die CS Leitung nicht runter bevor du schreibst:
    Code:
    void SndBfhlLCD(char byte){
      SPI2->CR1 |= SPI_CR1_SPE;                     //SPI aktivieren
      GPIOC->BSRR |= GPIO_BSRR_BR_2;                //RS-Pin zurücksetzen
      GPIOC->BSRR |= GPIO_BSRR_BR_3;            // CS runterziehen
    
      while ( ! (SPI2->SR & SPI_SR_TXE)){                //Warten bis Transmit-Register frei ist
      }
      SPI2->DR = byte;                              //Byte senden
      while ( ! (SPI2->SR & SPI_SR_TXE)){                //Warten bis Transmit-Register frei ist
      }
      while (SPI2->SR & SPI_SR_BSY){             //Warten bis laufende Übertragung abgeschlossen ist
      }
    
      GPIOC->BSRR |= GPIO_BSRR_BS_3;            // CS high
      GPIOC->BSRR |= GPIO_BSRR_BS_2;                //RS-Pin high
      SPI2->CR1 &= ~SPI_CR1_SPE;                     //SPI deaktivieren
    }
    Hoffe das das jetzt klappt.
    Hab heute auch zwei Stunden nach genau einem Bit gefahndet und kann deinen Ärger verstehen.

    Gruss botty

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.473
    Autsch...da werd ich TXE und BSY mal noch fix drehen. Und CS natürlich einbauen. Das Oszi hab ich erst am Mo wieder zur Verfügung, falls das LCD die Arbeit noch verweigert (wovon ich sicherheitshalber mal ausgehe).

    - - - Aktualisiert - - -

    Nachtrag:
    Der STM32 kommt im Debug-Mode immer noch nicht aus der zweiten While-Schleife. Wenn ich einen Haltepunkt am Ende der Funktion setze, wird dieser nie erreicht -> Endlosschleife.

    Was muß denn gemacht werden, um ein Peripherie-Element wie die SPI zu nutzen? Meines Wissens ist dies:
    -Takt für Pins aktivieren
    -Takt für Peripherie aktivieren
    -Pins konfigurieren
    -Peripherie konfigurieren
    -> Ferig

    Hab ich was übersehen in dieser Liste?

    Noch was...was macht eigentlich die SystemInit() ? (Hab die grad mal am Anfang des Programms aufgerufen, ändert aber auch nichts.)

    Code:
    void SndBfhlLCD(char byte){
      SPI2->CR1 |= SPI_CR1_SPE;                     //SPI aktivieren
      GPIOC->BSRR |= GPIO_BSRR_BR_2;                //RS-Pin zurücksetzen
      GPIOC->BSRR |= GPIO_BSRR_BR_3;                //CS runterziehen
    
      while (!(SPI2->SR & SPI_SR_TXE)){             //Warten bis Transmit-Register frei ist
      }
      SPI2->DR = byte;                              //Byte senden
      while (!(SPI2->SR & SPI_SR_TXE)){             //Warten bis Transmit-Register frei ist
      }
      while (SPI2->SR & SPI_SR_BSY){                //Warten bis laufende Übertragung abgeschlossen ist
      }
      GPIOC->BSRR |= GPIO_BSRR_BS_3;                //CS high
      GPIOC->BSRR |= GPIO_BSRR_BS_2;                //RS-Pin high
      SPI2->CR1 &= ~SPI_CR1_SPE;                    //SPI deaktivieren
      //RS NICHT toggeln
    }

    Ich wünsche an dieser Stelle mal ein schönes Wochenende

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo,
    ich habe das Display auch schon in Gang gebracht, aber im 4 Bit Modus.
    Das lief auch SEHR schwer anfangs....
    Hast Du den Kontrast richtig eingestellt und die Kondensatoren dran.
    Bei der 3,3 Volt Versorgung gibt es wohl eine Follower, der auch eingestellt werden muss.
    Hab auch schonmal ewig gesucht und dann stellte sich heraus, dass ich nur nix gesehen hatte, weil der Kontrast falsch eingestellt war.
    Der CSB und PSB Pin auch richtig ? und nicht vergessen die Datenleitungen, obwohl nicht benutzt festzulegen..

    Ich weiss nicht wie schnell deine Pins toggeln, aber mein Prozessor war zu schnell und ich musste delays einbauen.
    2-3 Mikrosekunden.

    Ganz wichtig war die Initialisierung, da hat jedes "ähnliche" Display seinen Eigenheiten.
    Wobei die DOGM Serie sich doch von anderen Displays unterscheidet
    Zudem gibt es ja auch 2 Instruction Tables, die richtig hin und hergeschaltet werden müssen.

    Am Anfang darf man ja auch nicht das Busy Flag abfrage, weil es noch nicht funktioniert.
    Wie das genau beim SPI Modus läuft, hab ich aber nicht ausprobiert.

    Schau Dir mal die Zeiten an, beim Initialisieren von mir:
    Code:
    /* initialize LCD 4 Bit mode FOSC 380 KHz */
    /* Power Up need ca. 40ms internal Power on reset ST7036 */
        Wait_us(50000);   
    
        LCD_DataOut8(0x30);       /* Function set */
        Wait_us(2000);           /* wait > 1,6ms */
    
        LCD_DataOut8(0x30);       /* Function set */
        Wait_us(50);            /* wait > 26,3 us */
    
        LCD_DataOut8(0x30);       /* Function set */
        Wait_us(50);            /* wait > 26,3 us */
    
    
        LCD_DataOut8(0x20);       /* Function Set  4 BIT DL=0 */
        Wait_us(50);            /* wait > 26,3 us */
    
        /* !!!! erst ab jetzt ist der 4 Bit Modus aktiv */
    
        LCD_WaitBusy();
    
      /* DL = High= 8 Bit  DL=Low = 4 Bit */
        /* N=1=2 Zeilen   N=0=1Zeile */
        LCD_DataOut4(0x29);         /* Function Set 4 Bit N=1 DH=0 IS2=0 IS1=1   DH=1=Double Height*/
        LCD_WaitBusy();
    
        LCD_DataOut4(0x14);    /* BIAS  Intern OSC frequency BS=  1  0    FX=1   */
        LCD_WaitBusy();
    
        LCD_DataOut4(0x78);  /* Contrast set  C3 C2 C1 C0 */
        LCD_WaitBusy();
    
        LCD_DataOut4(0x55);  /* 0x5E Power  Ion=1 Bon=1 C5=1 C4=1 */
        LCD_WaitBusy();
    
        LCD_DataOut4(0x6D); /* Follower control Fon Rab2 Rab1 Rab0  */
        LCD_WaitBusy();
    
    /*    LCD_DataOut4(0x28); */ /* switch back to instruction table 0 */
    /*    LCD_WaitBusy();   */
    
         LCD_DataOut4(0x0F);  /* Display On/off  D=  C=  B=  */
        LCD_WaitBusy();
    
      LCD_DataOut4(0x01);  /* Clear Display, Cursor home  */
        LCD_WaitBusy();
    
        LCD_DataOut4(0x06);  /* Cursor auto increment  Entry Mode set ID=   S=   cursor move dir */
        LCD_WaitBusy();
    Geändert von Siro (11.11.2016 um 22:05 Uhr)

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von White_Fox
    Registriert seit
    04.10.2011
    Beiträge
    1.473
    Hallo Siro

    Erstmal danke...aber momentan läuft die SPI noch nichtmal. Ich komm dann aber gern auf deinen Code zurück (in V2 werd ich definitiv die Ansteuerung im 4- oder 8-Bitmodus nutzen, nie wieder LCD über SPI, grmpf).

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.08.2008
    Ort
    DE
    Beiträge
    523
    SPI1 mit SPL für einen 411RE, sollte aber Pin-Kompatibel mit dem 446 sein. Für CS muss noch ein Pin konfiguriert werden.
    Code:
    #include "SPI.h"
    
    
    void Spi_Init(SPI_TypeDef *SPIx)
    {
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef  SPI_InitStructure;
    
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    
        // Periph clock enable
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
    
        // Configure SPI pins: SCK, MOSI
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        // Configure pins: MISO
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
        // Reset SPI Interface
        SPI_I2S_DeInit(SPIx);
    
        // SPI configuration
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_CRCPolynomial = 7;
        SPI_Init(SPIx, &SPI_InitStructure);
    
        SPI_CalculateCRC(SPIx, DISABLE);
    
        // Enable the SPI
        SPI_Cmd(SPIx, ENABLE);
    }
    
    uint8_t Spi_ReadByte(SPI_TypeDef *SPIx)
    {
        return Spi_WriteByte(SPIx, 0xFF);
    }
    
    uint8_t Spi_WriteByte(SPI_TypeDef *SPIx, uint8_t _data)
    {
        // Loop while DR register is not empty
        while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
    
        // Send byte through the SPIx peripheral
        SPI_I2S_SendData(SPIx, _data);
    
        while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET);
    
        // Return the byte read from the SPI bus
        return (uint8_t)SPI_I2S_ReceiveData(SPIx); }
    mfg

Ähnliche Themen

  1. noch ne seltsame Rechenfunktion - ich krieg die Krise!
    Von dl1akp im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 17.08.2008, 20:44
  2. wie, krieg ich die hex auf dem board
    Von Sp666dy im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 25.02.2008, 07:34
  3. Menü - ich krieg die Krise!!!
    Von dl1akp im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 18.11.2007, 14:41
  4. Wo krieg ich BASCOM Basic her?
    Von zwerg1 im Forum AVR Hardwarethemen
    Antworten: 23
    Letzter Beitrag: 13.02.2007, 22:34
  5. [ERLEDIGT] Wo krieg ich Baupläne her
    Von Aramis im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 05.09.2004, 10:16

Berechtigungen

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

12V Akku bauen