2020-05-22 01:46 PM
#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);
}
}
2020-05-22 02:41 PM
Did you observe the SPI bus using oscilloscope/logic analyzer?
JW
2020-05-22 05:01 PM
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;
}