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"
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.
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 "); }
Wolfgang schrieb: > Habe dementsprechend den Code angepasst, leider ohne Erfolg. >> 11 D4 PD12 >> 12 D5 PD13 >> 13 D6 PD14 >> 14 D7 PD15 versus
1 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; |
???
Wolfgang schrieb: > Habe dementsprechend den Code angepasst, leider ohne Erfolg. > Hat dieser Code bei dir funktioniert? Ja, aber mit PortD. Irgendwann hatte ich ihn noch geändert. Er steht weiter unten unter dem Schaltbild: http://mino-elektronik.de/FM_407/fmeter_407.htm#a5 Für den Kontrast wird DAC1 verwendet. Was funktioniert denn und was nicht?
m.n. schrieb: > Was funktioniert denn und was nicht? Vielleicht sollte man das Timing etwas päpstlicher ausfallen lassen?
Mitlesa schrieb: > Vielleicht sollte man das Timing etwas päpstlicher ausfallen lassen? Ich denke 65 ms (bzw. 10 ms) pro Ausgabe sind langsam genug.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.