Skip to main content
Nmo.1
Associate III
May 22, 2020
Question

Lcd EA_dogs 102 with stm32f091Rc nucleo board Hi everyone! I want to configure LCD with stm32f0 . I have the following code but it didn't work. Can you please help me.

  • May 22, 2020
  • 2 replies
  • 1083 views
#include "lcd.h"
#include "font_lcd.h"
#include "stm32f0xx.h"
#include "stm32f0xx_conf.h"
 
 
// ***********************************************************************
// Schreiben eines Zeichens an das LCD-Modul
// seriell Soft-SPI Mode, 3/4 Draht Interface
// ـbergabe: lcd_byte : Auszugebendes Zeichen/Steuerzeichen
// lcd_mode : 0 - Daten
// 1 - Steuerzeichen
// ***********************************************************************
void write_lcd(byte lcd_byte, byte lcd_mode)
{
	// Zeitangaben für 72 MHz und 2 Waitstates
	Delay(200); // Pause mind. 15us bevor nächstes Zeichen gesendet werden darf
	 //GPIO_ResetBits(LCD_CSB); // LCD_CSB = 0;
	 GPIO_ResetBits(GPIOA, GPIO_Pin_4);
	 if (lcd_mode) GPIO_ResetBits(GPIOA, GPIO_Pin_8); // LCD_RS = 0 Steuerzeichen
	 //else GPIO_SetBits(LCD_RS); // LCD_RS = 1 Daten
	 else GPIO_SetBits(GPIOA, GPIO_Pin_8);
	 // Byte senden seriell senden (D7 D6 D5 D4 D3 D2 D1 D0)
	 sendbyte_spi_lcd(lcd_byte);
	 Delay(10); // Pause (ca. 1us)
	 //GPIO_SetBits(LCD_CSB); // LCD_CSB = 1
	 GPIO_SetBits(GPIOA, GPIO_Pin_4);
}
 
// ***********************************************************************
// L�?schen des LCD-Display
// und Kursor auf Position 0,0 setzen
// ***********************************************************************
void clear_lcd(void)
{
	write_lcd(0x01,1); // Diplay löschen
	//lcd_x = lcd_y = 0; // Position für Scrollfunktion auf Anfang setzen
	Delay(50); // Pause
}
 
// ***********************************************************************
// Ausgabe eines ASCII-Zeichen positioniert auf dem LCD-Modul
// ـbergabe: lcd_x : Spalte (0...SPALTEN-1)
// lcd_y : Zeile (0...ZEILEN-1)
// lcd_ascii : ASCII-Zeichen
// ***********************************************************************
void write_byte_lcd(byte lcd_x, byte lcd_y, byte lcd_ascii, byte invertiert)
{
	unsigned char lcd_offset = 0;
	 if (lcd_x > (101 - 1)) lcd_x = 0;
	 if (lcd_y > (31 - 1)) lcd_y = 0;
	 switch (lcd_y) {
	 case 0: lcd_offset = 0x80; break; // Zeile 1
	 case 1: lcd_offset = 0xC0; break; // Zeile 2
	 default: lcd_offset = 0x80;
	 };
	 write_lcd(lcd_x+lcd_offset,1); // Kursorposition setzen
	 write_lcd(lcd_ascii,0); // Ausgabe des ASCII-Zeichen an der Kursorposition1
}
 
// ***********************************************************************
// Ausgabe einer Zeichenkette positioniert auf dem LCD-Modul
// ـbergabe: lcd_x : Spalte (0...SPALTEN-1)
// lcd_y : Zeile (0...ZEILEN-1)
// lcd_zeichen : Adresse der auszugebenden format. Zeichenkette
// clr_line : L�?schen bis Zeilenende
// 1 - L�?schen
// 0 - kein L�?schen
// ***********************************************************************
void printf_lcd(byte lcd_x, byte lcd_y, byte *lcd_zeichen, byte invertiert)
{
	unsigned char lcd_i;
	unsigned char lcd_offset = 0;
	 if (lcd_x > (101 - 1)) lcd_x = 0;
	 if (lcd_y > (31 - 1)) lcd_y = 0;
	 switch (lcd_y) {
	 case 0: lcd_offset = 0x80; break; // Zeile 1
	 case 1: lcd_offset = 0xC0; break; // Zeile 2
	 default: lcd_offset = 0x80;
	 }
	 write_lcd(lcd_x+lcd_offset,1); // Kursorposition setzen
	 // Ausgabe der Zeichenkette ab der Kursorposition
	 lcd_offset = strlen(lcd_zeichen); // Länge der Zeichenkette
	 if (lcd_offset > 101) lcd_offset = 101;
	 for(lcd_i = lcd_offset ; lcd_i ; lcd_i--) {
	 write_lcd(*lcd_zeichen,0);
	 lcd_zeichen++;
	 }
	 if (invertiert) {
	 // Löschen bis Zeilenende
	 for(lcd_i = 101 - lcd_offset - lcd_x ; lcd_i ; lcd_i--) write_lcd(' ',0);
	 }
}
 
// ***********************************************************************
// Grundinitialisierung des LCD-Moduls in SPI-Mode (seriell)
// ***********************************************************************
void init_lcd(void)
{
 
	 SPI_InitTypeDef SPI_InitStructure; // SPI Struktur
 SPI_I2S_DeInit(SPI1);
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1 Takt freigeben
	 SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; // Nur senden
	 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // SPI Master-Mode
	 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8 Datenbits
	 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // CPOL High=Ruhezustand
	 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // CPHA 2. Flanke (L/H) gibt Daten aus
	 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS Chipselect per Software
	 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; // Taktfrequenz 72MHz/32 = 2,2 MHz
	 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // MSB (höherwertiges Bit) zuerst senden
	 SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC (?)
	 SPI_Init(SPI1, &SPI_InitStructure); // SPI initialisieren
	 SPI_Cmd(SPI1, ENABLE);
 
	 GPIO_InitTypeDef LCS_CBS;
	 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	 LCS_CBS.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_9; //pa4=cs/ pa8=rst/ pa9=cmd
	 LCS_CBS.GPIO_Mode = GPIO_Mode_OUT;
	 LCS_CBS.GPIO_OType = GPIO_OType_PP;
	 LCS_CBS.GPIO_Speed = GPIO_Speed_50MHz;
	 LCS_CBS.GPIO_PuPd = GPIO_PuPd_NOPULL;
	 GPIO_Init(GPIOA, &LCS_CBS);
 
	 GPIO_InitTypeDef INSTR;
	 INSTR.GPIO_Pin= GPIO_Pin_5|GPIO_Pin_7;//pa5=clk/pa7=mosi
	 INSTR.GPIO_Mode=GPIO_Mode_AF;
	 INSTR.GPIO_OType = GPIO_OType_PP;
	 INSTR.GPIO_Speed= GPIO_Speed_50MHz;
	 GPIO_Init(GPIOA, &INSTR);
 
	 // init_spi_lcd(); // Hardware SPI Initialisierung
	 GPIO_ResetBits(GPIOA, GPIO_Pin_4);
	 Delay(500); // Wartezeit nach POWER-ON bis VCC stabil ist
	 // Grundinitialisierung (SPI, wie im 8-Bit Parallel-Mode)
	 write_lcd(0x39,1); // Function Set
	 write_lcd(0x39,1); // Function Set (gleiches Byte nochmal senden)
	 write_lcd(0x14,1); // Bias Set
	 write_lcd(0x55,1); // Power Control + Kontrast Set C5,C4
	 write_lcd(0x6D,1); // Follower Control
	 write_lcd(0x78,1); // Kontrast Set C3,C2,C1,C0
	 write_lcd(0x0C,1); // Display Set
	 write_lcd(0x06,1); // Entry Mode Set
	 clear_lcd(); // Display löschen
 
}
/*****************************************************************************/
void sendbyte_spi_lcd (unsigned char byte) {
 //SPI_I2S_SendData(SPI1, byte); // Byte per SPI senden
 SPI_I2S_SendData16(SPI1, byte);
 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); // Warten bis Byte vollständig gesendet ist
}
 
int main(int argc, char* argv[])
{
	config_pin();
	init_lcd();
 
	while (1)
	{
		printf_lcd(0,0,"Test",1);
		//write_byte_lcd(10, 10, 0x41,1);
 }
 
}

    This topic has been closed for replies.

    2 replies

    waclawek.jan
    Super User
    May 22, 2020

    Did you observe the SPI bus using oscilloscope/logic analyzer?

    JW

    Tesla DeLorean
    Guru
    May 23, 2020

    WTH are you doing using the 16-bit form?

    I'd use SPI Transmit/Receive

    uint8_t STM_SPI_WriteRead(uint8_t Data)

    {

     uint8_t tmp = 0x00;

     /* Wait until the transmit buffer is empty */

     while(SPI_I2S_GetFlagStatus(LCD_SD_SPI, SPI_I2S_FLAG_TXE) != SET)

     {

     }

     /* Send the byte */

     SPI_SendData8(LCD_SD_SPI, Data);

     /* Wait to receive a byte */

     while(SPI_I2S_GetFlagStatus(LCD_SD_SPI, SPI_I2S_FLAG_RXNE) != SET)

     {

     }

     /* Return the byte read from the SPI bus */

     tmp = SPI_ReceiveData8(LCD_SD_SPI);

     /* Return read Data */

     return tmp;

    }

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..