Forum: Projekte & Code [STM32] DOGM204-A / SSD1803A Library


von Markus M. (adrock)


Angehängte Dateien:

Lesenswert?

Hi,

hier mal meine kleine Bibliothek zur Ansteuerung eines DOGM204-A LCDs 
(SSD1803A Controller) über SPI an einem STM32 Controller.

Da die Beschreibung und auch Implementierung der Funktionen im 
Controller teilweise sehr kreativ sind, ist es vlt. nützlich für den 
einen oder anderen.

Der Code ist für STM32CubeMX gedacht und verwendet folglich die 
HAL_SPI_... Funktionen. Im main.c gibt es kleine Demo-Funktionen für so 
ziemlich alles was der Display-Controller her gibt.

Ich habe den Code auf einem STM32F0 getestet. Der Demo-Code geht davon 
aus, dass am PA0 die Reset-Leitung des Displays angeschlossen ist um das 
Display am Anfang einmal zurückzusetzen.

Für HAL-Hasser sollte es auch keine große Hürde sein den Code zu ändern.

Grüße
Markus

: Bearbeitet durch User
von Walter (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Markus,
Danke dir erstmalfür dein Code, das Hat mir sehr zum Verständnis 
geholfen.
ich bin gerade an einem Projekt und ich kann nicht vorankommen.
Muss der LCD Modul "EA DIP203G-4NLED" basiert auf ssd1803 Controller. 
Die Ansteuerung passiert über die SPI Schnittstelle des STM32F103 Cortex 
M3 Microcontrollers.
Ich weiß es nicht woran der Fehler liegt, da ich nichts auf dem Display 
bekomme. Ich habe der NSS Pin als Output Konfiguriert und dann folgende 
Funktion für das Ziehen auf LOW bzw. High Level der CS pin meines LCD:



void SPIx_DisableLCD(void)
{
  HAL_GPIO_WritePin(SPIx_NSS_GPIO_PORT ,SPIx_NSS_PIN , GPIO_PIN_SET);
}
void SPIx_EnableLCD(void)
{
  HAL_GPIO_WritePin(SPIx_NSS_GPIO_PORT ,SPIx_NSS_PIN , GPIO_PIN_RESET);
}


Hier die SPI_FINI89 Funktion:

void spi_init(SPI_HandleTypeDef* spi_modul)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  // SPI_HandleTypeDef spiHandle;
   SPIx_CLK_ENABLE();
   SPIx_GPIO_CLK_ENABLE();

   // SPI MOSI GPIO and SPI NSS GPIO Pin configuration!!!

   GPIO_InitStruct.Pin = SPIx_MOSI_PIN| SPIx_MISO_PIN|SPIx_SCK_PIN ;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pull = GPIO_NOPULL;

   HAL_GPIO_Init(SPIx_MOSI_GPIO_PORT , &GPIO_InitStruct);

   // SPI MISO GPIO Pin configuration!!!

   GPIO_InitStruct.Pin  = SPIx_MISO_PIN ;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Speed= GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pull = GPIO_NOPULL;

   HAL_GPIO_Init(SPIx_MISO_GPIO_PORT , &GPIO_InitStruct);

   // SPI SCK GPIO Pin configuration !!

   GPIO_InitStruct.Pin =SPIx_SCK_PIN;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pull = GPIO_NOPULL;


   HAL_GPIO_Init(SPIx_SCK_GPIO_PORT , &GPIO_InitStruct);

 // NSS Pin configuration
   GPIO_InitStruct.Pin =SPIx_SCK_PIN;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pull = GPIO_NOPULL;

   HAL_GPIO_Init(SPIx_NSS_GPIO_PORT , &GPIO_InitStruct);


   /* NVIC configuration for SPI2 Transmit complete interrupt */

   //HAL_NVIC_SetPriority ( SPI2_IRQn  , 15, 0);
   //HAL_NVIC_EnableIRQ (SPI2_IRQn);

   // SPI Interface Configuration  !!

   spi_modul->Instance=SPIx;
   spi_modul->Init.Mode=SPI_MODE_MASTER;
   spi_modul->Init.Direction=SPI_DIRECTION_2LINES;
   spi_modul->Init.DataSize=SPI_DATASIZE_8BIT;
   spi_modul->Init.CLKPolarity=SPI_POLARITY_HIGH;
   spi_modul->Init.CLKPhase = SPI_PHASE_1EDGE;
   spi_modul->Init.NSS =SPI_NSS_HARD_OUTPUT;     // SPI_NSS_SOFT
   spi_modul->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
   spi_modul->Init.FirstBit = SPI_FIRSTBIT_LSB;
   spi_modul->Init.TIMode = SPI_TIMODE_DISABLE;
   spi_modul->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
   //spi_modul.Init.CRCPolynomial = 10;
    if (HAL_SPI_Init(spi_modul) != HAL_OK)
    {
      Error_Handler();

    }


}

von Walter (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang die Pin Belegung des Displays

von Markus M. (adrock)


Lesenswert?

Hi,

die Initialisierung in meinem Code sieht etwas anders aus bzgl. der 
SPI-Parameter:
1
  hspi1.Instance = SPI1;
2
  hspi1.Init.Mode = SPI_MODE_MASTER;
3
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
4
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
5
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
6
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
7
  hspi1.Init.NSS = SPI_NSS_SOFT;
8
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
9
  hspi1.Init.FirstBit = SPI_FIRSTBIT_LSB;
10
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
11
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
12
  hspi1.Init.CRCPolynomial = 7;
13
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
14
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

Insbesondere ClkPhase und FirstBit sind anders als bei Dir. NSS habe ich 
gänzlich deaktiviert.

Vlt. magst Du das mal testen?

Gruß
Markus

von Walter (Gast)


Lesenswert?

Hi,

ich habe nochmal das Datenblatt angeschaut  und ja bei  der Clock-Phase 
soll eher eingestellt werden. Ein großes bei mir ist auch das NSS 
Signal.
- In der HAL DRIVER habe ich die Option  hspi1.Init.NSSPMode = 
SPI_NSS_PULSE_DISABLE; nicht finden Können.

Ich noch ein Paar Fragen oder Unklarheiten, kann man anstatt deine LCD 
read function:
static uint8_t LCD1803_ReadB(SPI_HandleTypeDef *spi) {
    uint8_t b = LCD1803_STARTBYTE|LCD1803_FLAG_RS|LCD1803_FLAG_RW;
    uint8_t zero = 0;

    HAL_SPI_Transmit(spi, &b, 1, HAL_MAX_DELAY);
    HAL_SPIEx_FlushRxFifo(spi);
    HAL_SPI_TransmitReceive(spi, &zero, &b, 1, HAL_MAX_DELAY);

    return b;
}

,  ein Hal_delay benutzen, wo diese Funktion zum Abwarten aufgerufen 
wird ?

- Braucht man unbedingt den Contrast  zu benutzen. kriegt man nichts am 
Display angezeigt wenn das nicht eingestellt  ist?

von Markus M. (adrock)


Lesenswert?

Was möchtest Du mit HAL_delay denn machen? Das ist doch ein statisches 
Delay?

Tatsache ist, man sollte bei vielen Operationen immer auch das BUSY Flag 
des Displays abfragen ob es denn bereit für den nächsten Befehl ist.

Mein Code war ja für einen STM32F0.

Das zeigt leider genau was auch der Kritikpunkt vieler Leute an der HAL 
ist. Es ist eben keine echte Abstraktion, sondern man muss sich doch 
wieder mit Controllerspezifischen Flags rumschlagen, in diesem Fall das 
für den NSS Modus.

SPI_NSS_SOFT ist in Deinem Fall korrekt, das heißt die Software kümmert 
sich selbst darum.

Vlt. ist auch dieser Thread fürt Dich interessant, dort geht es auch um 
die Displays:

Beitrag "DOGM-204 Problem mit Steuercodes"

Was passiert denn, wenn Du meinen Code mal auf STM32F103 anpasst und 
ausprobierst? Sollte nach kleinen Anpassungen ja eigentlich 
funktionieren.

Was die Kontrasteinstellung angeht bin ich mir nicht mehr sicher (ist 
schon zu lange her und ich habe seitdem nichts mehr mit dem Display 
gemacht), aber ich hatte mich für die Initialisierung an der Sequenz aus 
dem Datenblatt orientiert. Das ganze ist auf jeden Fall ein bisschen 
fragil und man sollte sich da größtenteils an das Datenblatt halten.

Die Beschaltung des Displays mit den Kondensatoren etc. hast Du gemacht? 
Für die Erzeugung der Spannungen und so?

: Bearbeitet durch User
von Walter (Gast)


Lesenswert?

Hi,

Ja ehrlich gesagt habe ich mich an deinem Code orientiert weil ich 
anfangs nicht wusste wie ich anfangen konnte. Aber jetzt verstehe ich 
vieles.

Was die Beschaltung angeht, glaube ich nicht das ich mit Kondensatoren 
was zu tun haben soll. Ich habe eine 3V3 PIN auf dem Microcontroller 
STM32F103, ich habe kein 5V Betriebsspannung. Also habe die MOSI MiSo 
und SCK Pins vom Mikrokontroller mit denen vom Display verbunden.


Leider kann ich immer noch nicht Das Display in Betrieb bringen. Kriege 
immer nichts drauf.


Eine Frage: Weißt du wie ich ein Schematic Diagramm für mein Projekt 
machen kann? Gibt es Software dafür?

vielen Dank schonmal?

von Markus M. (adrock)


Lesenswert?

OK, das mit den Kondensatoren war nur für das DOGM204-A notwendig, bei 
Deinem Display werden sie wohl nicht benötigt.

Hast Du denn mal meinen Code komplett übernommen? Also Code von CubeMX 
generieren lassen, die Teile aus den "USER CODE" Sektionen aus meinem 
main.c in Dein main.c übernommen, lcd1803.c mit in das Projekt 
aufgenommen, und einfach mal compiliert?

Die Lötbrücke für SPI hast Du geschlossen wie in der Anleitung 
beschrieben?

von ondraN (Gast)


Lesenswert?

Hi Marcus,
thanks a lot for your code. I port it for F401 CPU and it works 
perfectly. There are some slightly diferencies in HAL library (F401 
doesnt have SPI Ex part). I only remove this parts ( 
HAL_SPIEx_FlushRxFifo(spi)) without change of functionality. Next, I set 
baud rate divider at value 32 (80MHz) for 2,5MHz SPI clock, works 
without problem.

von Markus M. (adrock)


Lesenswert?

ondraN schrieb:

> thanks a lot for your code. I port it for F401 CPU and it works
> perfectly. There are some slightly diferencies in HAL library (F401

Thanks for your feedback and mentioning the differences to make it 
working on STM32F4xx. Glad to hear that you can make use of it!

Regards
Markus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.