Skocz do zawartości

[C] [STM32] LCD Nokia 5110 PCD8544 - problem z wyświetlaniem


BennyLava

Pomocna odpowiedź

Mam problem z poprawnym wyświetlaniem obrazu na ekranie. Na początku zaimplementowałem komunikację samemu na podstawie datasheetu, ale ekran nie wyświetlał zupełnie nic. Przerobiłem już chyba wszystkie gotowce z Internetu, poniżej wklejam kod opierający się na jednym z nich, za pomocą którego w końcu udało się zmusić wyświetlacz do współpracy:

#include "stm32f10x.h"
#include "stm32f1xx_nucleo.h"

#define LCD_PIN_ENABLE      GPIO_Pin_12
#define LCD_PIN_RESET       GPIO_Pin_11
#define LCD_PIN_COMMAND     GPIO_Pin_10
#define LCD_PIN_DATA        GPIO_Pin_9
#define LCD_PIN_CLOCK       GPIO_Pin_8

#define LCD_CMD             0
#define LCD_DATA            1

#define LCD_DISPLAY_BLANK   0x08
#define LCD_DISPLAY_FULL    0x09
#define LCD_DISPLAY_NORMAL  0x0C
#define LCD_DISPLAY_INVERT  0x0D

GPIO_InitTypeDef GPIO_InitStructure;

void delay_ms(uint16_t time);

void LcdSetXY(uint8_t x, uint8_t y);
void LcdWrite(uint8_t type, uint8_t value);

volatile uint16_t g_wait = 0;

void SysTick_Handler()
{
if( g_wait > 0 )
	g_wait--;
}

int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = LCD_PIN_ENABLE | LCD_PIN_RESET | LCD_PIN_COMMAND | LCD_PIN_DATA | LCD_PIN_CLOCK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

SysTick_Config(SystemCoreClock / 1000);

GPIO_SetBits(GPIOA, LCD_PIN_RESET);
delay_ms(10);
GPIO_ResetBits(GPIOA, LCD_PIN_RESET);
delay_ms(10);
GPIO_SetBits(GPIOA, LCD_PIN_RESET);

LcdWrite(LCD_CMD, 0x21); // extended cmd
LcdWrite(LCD_CMD, 0xB1); // Vop
LcdWrite(LCD_CMD, 0x04); // temp coeff.
LcdWrite(LCD_CMD, 0x15); // bias

LcdWrite(LCD_CMD, 0x20); // basic cmd
LcdWrite(LCD_CMD, LCD_DISPLAY_NORMAL);

int i;

for(i = 0; i < 3; i++){
	LcdWrite(LCD_CMD, LCD_DISPLAY_BLANK);
	delay_ms(500);
	LcdWrite(LCD_CMD, LCD_DISPLAY_FULL);
	delay_ms(500);
}

LcdWrite(LCD_CMD, LCD_DISPLAY_NORMAL);

uint8_t x, y, stripeType = 0;

while(1){
	LcdSetXY(0, 0);
	for(y = 0; y < 6; y++){
		for(x = 0; x < 84; x++){
			LcdWrite(LCD_DATA, (stripeType ? 0xCC : 0x00));
		}
		stripeType = !stripeType;
	}
	delay_ms(1000);
	stripeType = !stripeType;
}
}

void LcdWrite(uint8_t type, uint8_t value)
{
if( type == LCD_DATA )
	GPIO_SetBits(GPIOA, LCD_PIN_COMMAND);
else
	GPIO_ResetBits(GPIOA, LCD_PIN_COMMAND);

GPIO_ResetBits(GPIOA, LCD_PIN_ENABLE);

int i;
for (i = 0; i < 8; i++)
{
	GPIO_ResetBits(GPIOA, LCD_PIN_CLOCK);

	if (value & 0x80)
		GPIO_SetBits(GPIOA, LCD_PIN_DATA);
	else
		GPIO_ResetBits(GPIOA, LCD_PIN_DATA);

	value <<= 1;

	GPIO_SetBits(GPIOA, LCD_PIN_CLOCK);
}

GPIO_ResetBits(GPIOA, LCD_PIN_CLOCK);
GPIO_ResetBits(GPIOA, LCD_PIN_DATA);
GPIO_SetBits(GPIOA, LCD_PIN_ENABLE);
}

void LcdSetXY(uint8_t x, uint8_t y)
{
if( x > 83 ) x = 83;
if( y > 5 ) y = 5;
LcdWrite(LCD_CMD, 0x80 | x);
LcdWrite(LCD_CMD, 0x40 | y);
}

void delay_ms(uint16_t time)
{
g_wait = time;
while( g_wait );
}

W działaniu wygląda to tak jak na załączonym niżej filmiku. Wypróbowałem wiele różnych wzorów testowych (szachownica, bitmapa przesyłana z PC, paski o różnej grubości) i niektóre wyświetlają się całkiem dobrze, inne dają zupełnie losowy szum. Wygląda to tak jakby ekran gubił losowo przesyłane bajty. Z kolei całkowicie nie mogę wypełnić ekranu czarnymi pikselami wysyłając bajty 0xFF - każdy taki bajt jest zawsze ignorowany przez wyświetlacz. Próbowałem opóźnić transmisję przez wrzucanie delayów o różnym czasie i w różnych momentach w LcdWrite, nie dało to żadnego efektu. W jednym z przykładów w Internecie znalazłem schemat z wstawionym kondensatorem między Vcc i Gnd - różne kombinacje również nie pomogły. Ekran jest podłączony bezpośrednio do pinów GPIO uC, używam płytki z kursu Forbota (Nucleo F103RB). Męczę się z tym już od kilku dni i skończyły mi się pomysły. Problem programowy? Elektroniczny? Czy może ekran jest po prostu walnięty?

Link do komentarza
Share on other sites

Niestety ten sam problem.

Inicjalizacja SPI:

	SPI_InitStructure.SPI_BaudRatePrescaler = 	SPI_BaudRatePrescaler_64;
SPI_InitStructure.SPI_CPHA = 				SPI_CPHA_1Edge;
SPI_InitStructure.SPI_CPOL = 				SPI_CPOL_Low;
SPI_InitStructure.SPI_CRCPolynomial = 		7;
SPI_InitStructure.SPI_DataSize = 			SPI_DataSize_8b;
SPI_InitStructure.SPI_Direction = 			SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_FirstBit = 			SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = 				SPI_Mode_Master;
SPI_InitStructure.SPI_NSS = 				SPI_NSS_Soft;

Transmisja:

void LcdWrite(uint8_t type, uint8_t value)
{
if( type == LCD_DATA )
	GPIO_SetBits(GPIOA, LCD_PIN_COMMAND);
else
	GPIO_ResetBits(GPIOA, LCD_PIN_COMMAND);

GPIO_ResetBits(GPIOA, LCD_PIN_ENABLE);

   while( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET );
   SPI_I2S_SendData(SPI1, value);
   while( SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET );

GPIO_SetBits(GPIOA, LCD_PIN_ENABLE);
}
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.