LCD-Modul 2x16 am STM32F4Discovery-Board

Gast #2895060
Lesenswert?
• ▲
▼
Mit dem angefügten Programm 'STM32F4_lcd.c' läßt sich ein LCD-Modul 2x16 
am STM32F4-Discovery-Board betreiben. Verwendet werden dazu die Pins 
PortD9 - PortD15 gemäß gezeigtem Schaltbild.
Alle Anschlüsse lassen sich über einen 10-poligen Steckverbinder kompakt 
verdrahten, wenn der freie Pin 'NC' mit dem Anschluß '5V' verbunden wird 
(diagonal verlegtes Kabel). Die Anzeige wird dann aus dem USB-Anschluß 
mit versorgt. Falls diese Spannung merklich unter +5V liegt 
(Hintergrundbeleuchtung schwach, geringer Kontrast), ist es ratsam, für 
Board und LCD eine externe 5V-Stromversorgung anzuschließen.

Beim Programm ist zu kontrollieren, ob die Funktion 'warte_1us()' auch 
etwa die gewünschte Verzögerung bringt. Falls die bestehenden 
Einstellungen des SysTick-Timers nicht passen oder dieser garnicht 
aktiviert ist, muß man u. U. diese Funktion anpassen/ergänzen.

Das Programm kann für einfache Ausgaben verwendet werden. Entwickelt 
wurde es für die  Anzeige von Messwerten eines reziproken 
Frequenzzählers.
Beitrag "reziproker Frequenzzähler mit STM32F4Discovery"
Angehängte Dateien:
Gast #2911928
Lesenswert?
• ▲
▼
Schon länger wollte ich mit einem Foto zeigen, wie kompakt und einfach 
der Anschluß eines LCD-Moduls ist. Hier ist es.
Es können auch größere Module bis 2x40 oder auch 4x20 angesteuert 
werden, wenn man beachtet, wo die jeweiligen Zeilen im Display-Speicher 
abgelegt sind.
Angehängte Dateien:
Gast #4410861
Lesenswert?
• ▲
▼
Hallo m.n.

Ich hage gerade deinen Quellcode an einem STM32F10x ausprobiert, an Port 
C.
Habe dementsprechend den Code angepasst, leider ohne Erfolg.
Hat dieser Code bei dir funktioniert?

MfG Wolfgang

/*
  LCD-Pin   Funktion    Discovery-Board

    1         GND            GND-Pin
    2         +5V        +5V über NC-Pin
    3       Kontrast    Diode->GND (ca.0,7V Vorsp.)
    4         RS              PC1
    5         R/W             PC2
    6         E               PC3
    7       D0(GND)
    8       D1(GND)
    9       D2(GND)
    10      D3(GND)
    11        D4              PC4
    12        D5              PC5
    13        D6              PC6
    14        D7              PC7

*/


#include "stm32f10x.h"

#define LCD_CMD     GPIO_Pin_1        // 0 = CMD, 1 = Zeichenausgabe
#define LCD_READ    GPIO_Pin_2       // 0 = Schreiben, 1 = Status lesen
#define LCD_STROBE  GPIO_Pin_3       // Schreibimpuls E fuers LCD
#define ZEILE1      0x7f              // jeweils 1 addieren fuer 1. 
Spalte
#define ZEILE2      0xbf              // dto.
#define BUSY_FLAG   0x80              // Bit7 vom LCD-Status


void warte_1us(void)
{

volatile uint32_t t2;
  while(SysTick->VAL <1000);
  t2 = SysTick->VAL - 140;
  while(SysTick->VAL > t2);
}


// Routinen zur Ausgabe auf LCD 2x16

uint8_t lcd_status(void)    // oberstes Bit ist busy-flag, Rest: Adresse
{
  uint8_t temp = 0;
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | 
GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    // auf 
Eingang schalten
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIOC->ODR |= LCD_READ;             // PortC lesen
  GPIOC->ODR &= ~LCD_CMD;             // PortC lesen
  warte_1us();
  GPIOC->ODR |= LCD_STROBE;
  warte_1us();
  temp = (GPIOC->IDR >> 8) & 0xf0;    // oberes nibble zuerst
  GPIOC->ODR &= ~LCD_STROBE;
  warte_1us();
  GPIOC->ODR |= LCD_STROBE;
  warte_1us();
  temp |= (GPIOC->IDR >> 12) & 0x0f;  // unteres nibble zuletzt
  GPIOC->ODR &= ~LCD_STROBE;
  GPIOC->ODR &= ~LCD_READ;
  warte_1us();
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // wieder als 
Ausgang verwenden
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  warte_1us();

  return(temp);                       // busy-flag + Adresse
}


void lcd_impuls(void)       // Schreibimpuls mit Mindestlaenge
{
  warte_1us();
  GPIOC->ODR |= LCD_STROBE;
  warte_1us();
  GPIOC->ODR &= ~LCD_STROBE;
  warte_1us();
}

void lcd_nibble(char c)     // 4-bit-Wert an PC4-PC7 ausgeben
{
uint16_t temp;
  temp = GPIOC->ODR & ~(GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | 
GPIO_Pin_7);
  temp |= ((c<<8) & (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | 
GPIO_Pin_7));
  GPIOC->ODR = temp;
  lcd_impuls();
}

void lcd_out(char z,char mode)      // Ausgabe von Daten (mode==1) oder 
CMDs (mode==0)
{
  while(lcd_status() & BUSY_FLAG);  // vor neuer Ausgabe busy-flag 
abwarten
  if(mode) GPIOC->ODR |= LCD_CMD;
  else GPIOC->ODR &= ~LCD_CMD;
  lcd_nibble(z);
  z <<= 4;
  lcd_nibble(z);
}

void lcd_cmd(char z)        // einen LCD-Befehl ausgeben
{
  lcd_out(z,0);
}

void lcd_zeichen(char z)    // ein Zeichen ausgeben
{
  lcd_out(z,1);
}

void lcd_string(char *s)    // Zeichenkette auf LCD
{
signed char temp;
  while((temp=*s++) != 0) {
     lcd_zeichen(temp);
  }
}

void lcd_init_nibble(char c)  // 4-bit-Wert ausgeben LCD_INIT
{
uint16_t temp = 65000;
  lcd_nibble(c);
  while(temp--) warte_1us();  // bei Init genug Zeit lassen
}

void lcd_zeile1(char *s)    // komplette Zeile ausgeben
{
  lcd_cmd(ZEILE1+1);        // 1.Zeile, 1.Spalte
  lcd_string(s);
}
void lcd_zeile2(char *s)    // komplette Zeile ausgeben
{
  lcd_cmd(ZEILE2+1);        // 2.Zeile, 1.Spalte
  lcd_string(s);
}

void lcd_init(void)         // Port D9 - PortD 15 werden gebraucht
{
uint16_t temp;
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

  // Ausgänge von PortC Pins 1, 2, 3, 4, 5, 6, 7 push-pull output*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 
|GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  temp = 3000;
  while(temp--) warte_1us();    // nach Reset genug Zeit lassen

  lcd_init_nibble(0x30);
  lcd_init_nibble(0x30);
  lcd_init_nibble(0x30);
  lcd_init_nibble(0x20);
  lcd_cmd(0x28);                // im 4-bit mode
  lcd_cmd(0x0f);
  lcd_cmd(0x01);

  temp = 3000;
  while(temp--) warte_1us();    // nach init genug Zeit lassen

  lcd_cmd(ZEILE1+1);            // 1.Zeile, 1.Spalte
            //1234567890123456
  lcd_string("    1.Zeile     ");
  lcd_cmd(ZEILE2+1);            // 2.Zeile, 1.Spalte
  lcd_string("    2.Zeile     ");
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren