STM32F107 ile GLCD kullanımı Kütüphane sorunu

Başlatan Mucit23, 23 Ekim 2012, 12:04:52

demket

S.A. stm32f1 veya stm32f4 ile kullanabileceğim, ssd1963 için kütüphene paylaşabilcek olan var mıdır? Yalnız denenmiş olması şart.

Kolay gelsin,


demket

Elimdeki tft  bu WF43BTIBED0# ve datasheet te 15 nolu pin CS diyor fakat paylaştığınız linkteki 15. pin RD. Elimdeki datasheet mi yanlış?

camby

datasheet'e göre kullanın siz. Modeller farklı olabilir.

demket

DAtasheet teki LCD bağlantı pinleri aşağıdaki gibidir. Peki burda ki    "B/L Enable (3 nolu pin)"  ve "Display On(19 Nolu pin)" pinlerini nereye bağlamamız gerekmektedir.

1 GND Ground
2 VDD Power supply for Logic
3 B\L Enable Backlight control
4 RS Command/Data select
5 WR 8080 family MPU interface : Write signal
6 RD 8080 family MPU interface: Read signal
7 DB0
8 DB1
9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
Data bus
15 CS Chip select
16 RES REST
17 NC No connection
18 NC No connection
19 DISP ON Display on
20 NC No connection

pisayisi

Eğer işlemci çıkışlarını bu pinler için kullanmayacaksan, Display On(19 Nolu pin)" pinini10k lık bir direnç üzerinden Vdd ye bağlayabilirsin. Böylece display devamlı on konumunda. Arka plan led ışığının beslemek için ya da enable yapmak için B/L Enable (3 nolu pin)"  kullanılmakta. Sadece enable yapmaya yarıyorsa bu pin yapacağın yine 10k lık direnç üzerinden Vdd ye bağlayacaksın. Bazı lcd lerde backlight pinine 330 ohm luk bir direnç üzerinden 5 volta bağlayarak besleme yapmak gerekebiliyor sanırım seninkinde sadece 10k üzerinden vdd yaparak led aydınlanması kontrol edilmekte...
Murat

demket

S.A., stm32 ile denerken bir hatamı yapıyorum şeklinde bir düşünce ile msp430 a döndüm. Olaki giriş çıkış pinlerinde bir hata yapıyorumdur diye.

Çizgi Tagem den aldığım geliştirme kitiyle hemen bağlantıları yaptım. Yine karşımda bembeyaz bir ekran. Data ve Command portlarına bağlı ledler vasıtasıyla Debug step over yaparak işlemleri takip ettim. Bir problem görünmüyordu.

Derken, LCD nin 1. ve 2. pinine bağlamam gereken GND ve VDD yi söktüm. Ekranı  araya bekleme koyarak değişik renklere boyamayı istiyordum.  Ekranda silikte olsa bir şeyler görünmeye başladı. Ama renk yerine beyazın tonları görünüyor. GND veya VDD den birini bağlayınca da daha parlak yanıyor.

Tahmin ettiğim kadarıyla RGB ye aynı değeri basıyorum. Bu sebeple beyaz tonları görünüyor. LCD yi 8bit pixel data ve 18 bit modda çalıştırıyorum. Fonksiyonum void " FULL_ON(unsigned long dat)" şeklinde ve kullanımı da "FULL_ON(0x0000ff);       // blue" gibi.

Hatayı nerede yapmaktayım?
Kandiliniz Mübarek olsun.

fryrmnd

#112
Selamün Aleyküm arkadaşlar.

Elimde S6B0108 kontrolcüsüne sahip PGM12864B isimli bir glcd var.  ks0108 uyumlu diyedir diye başladım. Fxdev arkadaşın kodlarını kullandım.

ks0108_pixel(unsigned char x, unsigned char y, unsigned char renk);


fonksiyonu ile tek pixeli yakmak istedim. mesela (25,50,1)

Ancak sanırım bu fonksiyon düşündüğüm gibi çalışmıyor.


bu 4. sayfada açıklanan y ekseninin 8 satır tarzı olmasından mı kaynaklanıyor.?
Alt alta 8 adet pixel değilde tek pixeli aktif edebilmemin imkanı var mıdır?

Burak B

#113
Tek pixel için ordaki 8 bitlik(1byte) veriyi okumalı ve sonra pixel koymak istediğin bit ile OR etmeli daha sonrada gerisin geri lcd ye yazmalısın.
Ancak şunu söylemeliyim ki bu kod olarak çok ağır çalışır. Bunun yerine bir MCU RAM bölgesini buffer tayin edip onun üzerinde işlem yaptıktan sonra bu bilgiyi LCD' ye boca etmen çok daha hızlı bir tepkime süresi verir. Zaten bu tür grafik lcdler 1 bit renk bilgisi sakladığından ve Y ekseninde byte olarak işlediklerinden 128x64 pixel bir grafik modül için 128*(64/8) bytelık bir buffer yeterlidir. Buda 1K buffer demek. Seçim senin. Hızmı bellek mi ?
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

fryrmnd

#114
Hocam açıkçası kullanımını yeteri kadar anlayamadım. Önce yavaş yolla basıp buffer kısmına daha sonra geçsem iyi olucak Şimdi şu fonksiyonda zaten dediklerinizi yapmıyor mu? Yanlış mı anlıyorum?

void ks0108_pixel(unsigned char x, unsigned char y, unsigned char renk)
{
unsigned char veri, kay=1;
unsigned char chip=sol;
if(x>63)      // 63'ten büyükse ikinci chipe geç
{
x=x-64;
chip=sag;
}
DI=0;         // Komut verilecek
x=x&0x7F;        // X için komutlar haz?rlan?yor
x=x|0x40;
ks0108_write(chip,x);    // X için komut veriliyor
ks0108_write(chip,(y/8 & 0xBF) | 0xB8);  // Y için komut veriliyor
DI=1;             // Veri okunup, yaz?lacak
ks0108_read(chip);        // Yeni adres bilgisi için
veri=ks0108_read(chip);        // GLCD iki kez okunuyor
if(renk)            // Pixel aç?k m? kapal? m?
veri=veri | kay<<y%8;
else
veri=veri & (~(kay<<y%8));
DI=0;             // Komut veriliyor
ks0108_write(chip,x);
DI=1;             // Yaz?m yap?l?yor
ks0108_write(chip,veri);
}


fonksiyon sanırım nette ençok kullanılan kütüphanin

aşağıdaki parçasında x adres ve y page belirleniyor.

DI=0;         // Komut verilecek
x=x&0x7F;        // X için komutlar haz?rlan?yor
x=x|0x40;
ks0108_write(chip,x);    // X için komut veriliyor
ks0108_write(chip,(y/8 & 0xBF) | 0xB8);  // Y için komut veriliyor
DI=1;


bu kısımda da okunan page deki yazılacak pixel OR lan mıyor mu?
gerçi yukarda ki yazmalarla sanırım adres belirleniyor ama her yazmada x adresi otomatik olarak 1 artmıyor mu? Okunan adres yazılacak x adresten bir sonraki olmuyor mu? Çok karıştırdım  ???

ks0108_read(chip);        // Yeni adres bilgisi için
veri=ks0108_read(chip);        // GLCD iki kez okunuyor
if(renk)            // Pixel aç?k m? kapal? m?
veri=veri | kay<<y%8;
else
veri=veri & (~(kay<<y%8));
DI=0;             // Komut veriliyor
ks0108_write(chip,x);
DI=1;             // Yaz?m yap?l?yor
ks0108_write(chip,veri);





muhittin_kaplan


fryrmnd

Hocam ordakini de port etmeye çalıştım ama başaramadım. Ex33ds xfi arkadaşın ve Fxdev in kileri port ettim zaten birbirinin aynısı gibi. Çalıştırdığınız bir demo var mı bu kütüphane ile biraz incelesem. Aslında ks0108 in çalışmasını çözsem daha iyi olcak ama.

muhittin_kaplan

hocam kolay gelsin.

main.c inport ettiğim
#include "KS0108.h" //GLCD
#include "graphic.h" //GLCD
#include "KS0108-STM32.c"   //DOSYANIN ��ER�S�NDE INITIALE DE PORT AYARLAMASI YAPILACAK


ile

ilk etapta

GLCD_Initialize();
GLCD_ClearScreen();


yapıyorum.

//-------------------------------------------------------------------------------------------------
// Universal KS0108 driver library
// STM32 MCU low-level driver
// (c) Rados�aw Kwiecie�, radek@dxp.pl
//-------------------------------------------------------------------------------------------------
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"


#define KS0108_PORT  GPIOA

#define KS0108_RS    GPIO_Pin_8
#define KS0108_RW    GPIO_Pin_9
#define KS0108_EN    GPIO_Pin_10


#define KS0108_CS1   GPIO_Pin_11
#define KS0108_CS2   GPIO_Pin_12
#define KS0108_CS3   GPIO_Pin_13

#define KS0108_D0    0	 //-------------�nemli

#define DISPLAY_STATUS_BUSY	0x80

extern unsigned char screen_x;
extern unsigned char screen_y;

GPIO_InitTypeDef GPIO_InitStructure;

//-------------------------------------------------------------------------------------------------
// Delay function /for 8MHz/
//-------------------------------------------------------------------------------------------------
void GLCD_Delay(void)
{
 asm("nop");asm("nop");asm("nop");asm("nop");
}
//-------------------------------------------------------------------------------------------------
// Enalbe Controller (0-2)
//-------------------------------------------------------------------------------------------------
void GLCD_EnableController(unsigned char controller)
{
switch(controller){
case 0 : GPIO_ResetBits(KS0108_PORT, KS0108_CS1); break;
case 1 : GPIO_ResetBits(KS0108_PORT, KS0108_CS2); break;
case 2 : GPIO_ResetBits(KS0108_PORT, KS0108_CS3); break;
}
}
//-------------------------------------------------------------------------------------------------
// Disable Controller (0-2)
//-------------------------------------------------------------------------------------------------
void GLCD_DisableController(unsigned char controller)
{
switch(controller){
case 0 : GPIO_SetBits(KS0108_PORT, KS0108_CS1); break;
case 1 : GPIO_SetBits(KS0108_PORT, KS0108_CS2); break;
case 2 : GPIO_SetBits(KS0108_PORT, KS0108_CS3); break;
}
}
//-------------------------------------------------------------------------------------------------
// Read Status byte from specified controller (0-2)
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadStatus(unsigned char controller)
{
unsigned char status;

GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xFF << KS0108_D0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KS0108_PORT, &GPIO_InitStructure);

GPIO_SetBits(KS0108_PORT, KS0108_RW);
GPIO_ResetBits(KS0108_PORT, KS0108_RS);
GLCD_EnableController(controller);
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, KS0108_EN);
GLCD_Delay();
status = ((GPIO_ReadInputData(KS0108_PORT) >> KS0108_D0) & 0xFF);
GPIO_ResetBits(KS0108_PORT, KS0108_EN);
GLCD_DisableController(controller);
return status;
}
//-------------------------------------------------------------------------------------------------
// Write command to specified controller
//-------------------------------------------------------------------------------------------------
void GLCD_WriteCommand(unsigned char commandToWrite, unsigned char controller)
{
while(GLCD_ReadStatus(controller)&DISPLAY_STATUS_BUSY);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin  = (0xFF << KS0108_D0);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(KS0108_PORT, &GPIO_InitStructure);

GPIO_ResetBits(KS0108_PORT, KS0108_RS | KS0108_RW);
GLCD_Delay();
GLCD_EnableController(controller);
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, (commandToWrite << KS0108_D0));
commandToWrite ^= 0xFF;
GPIO_ResetBits(KS0108_PORT, (commandToWrite << KS0108_D0));
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, KS0108_EN);
GLCD_Delay();
GPIO_ResetBits(KS0108_PORT, KS0108_EN);
GLCD_Delay();
GLCD_DisableController(controller);
}

//-------------------------------------------------------------------------------------------------
// Read data from current position
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadData(void)
{
unsigned char tmp;
while(GLCD_ReadStatus(screen_x / 64)&DISPLAY_STATUS_BUSY);
GPIO_StructInit(&GPIO_InitStructure);  
GPIO_InitStructure.GPIO_Pin = 0xFF << KS0108_D0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KS0108_PORT, &GPIO_InitStructure);

GPIO_SetBits(KS0108_PORT, KS0108_RS | KS0108_RW);

GLCD_EnableController(screen_x / 64);
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, KS0108_EN);
GLCD_Delay();
tmp = ((GPIO_ReadInputData(KS0108_PORT) >> KS0108_D0) & 0xFF);
GPIO_ResetBits(KS0108_PORT, KS0108_EN);
GLCD_DisableController(screen_x / 64);
screen_x++;
return tmp;
}
//-------------------------------------------------------------------------------------------------
// Write data to current position
//-------------------------------------------------------------------------------------------------
void GLCD_WriteData(unsigned char dataToWrite)
{
while(GLCD_ReadStatus(screen_x / 64)&DISPLAY_STATUS_BUSY);
  
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = (0xFF << KS0108_D0);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(KS0108_PORT, &GPIO_InitStructure);

GPIO_ResetBits(KS0108_PORT, KS0108_RW);
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, KS0108_RS);
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, (dataToWrite << KS0108_D0));
dataToWrite ^= 0xFF;
GPIO_ResetBits(KS0108_PORT, (dataToWrite << KS0108_D0));
GLCD_Delay();
GLCD_EnableController(screen_x / 64);
GLCD_Delay();
GPIO_SetBits(KS0108_PORT, KS0108_EN);
GLCD_Delay();
GPIO_ResetBits(KS0108_PORT, KS0108_EN);
GLCD_Delay();
GLCD_DisableController(screen_x / 64);
screen_x++;
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_InitializePorts(void)// PORT AYARLAMASI YAPILACAK....
{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin   =  GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed =  GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode  =  GPIO_Mode_Out_PP;

GPIO_Init(KS0108_PORT, &GPIO_InitStructure);
GPIO_Write(KS0108_PORT, KS0108_CS1 | KS0108_CS2 | KS0108_CS3 | KS0108_RS | KS0108_RW | (0xFF << KS0108_D0));
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
unsigned char GLCD_ReadByteFromROMMemory(char * ptr)
{
 return *(ptr);
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------



//-------------------------------------------------------------------------------------------------
// Graphic LCD C library
// http://glcd-libc.dxp.pl
// (c) Rados�aw Kwiecie�, radek@dxp.pl
//-------------------------------------------------------------------------------------------------
#define KS0108_SCREEN_WIDTH	128
#define KS0108_SCREEN_HEIGHT	64


#define DISPLAY_SET_Y       0x40
#define DISPLAY_SET_X       0xB8
#define DISPLAY_START_LINE  0xC0
#define DISPLAY_ON_CMD	 0x3E
 #define ON	0x01
 #define OFF	0x00
#define DISPLAY_STATUS_BUSY	0x80
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_Initialize(void);
void GLCD_WriteData(unsigned char);
void GLCD_ClearScreen(void);
void GLCD_TextGoTo(unsigned char, unsigned char);
void GLCD_GoTo(unsigned char, unsigned char);
void GLCD_WriteString(char *);
unsigned char GLCD_ReadByteFromROMMemory(char *);
void GLCD_WriteChar(char charToWrite);

//-------------------------------------------------------------------------------------------------
// End of file KS0108.h
//-------------------------------------------------------------------------------------------------



//-------------------------------------------------------------------------------------------------
// (c) Rados�aw Kwiecie�, radek@dxp.pl
//-------------------------------------------------------------------------------------------------
extern void GLCD_SetPixel(unsigned char x, unsigned char y, unsigned char color);

const unsigned char color = 1;
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_Rectangle(unsigned char x, unsigned char y, unsigned char b, unsigned char a)
{
 unsigned char j; // zmienna pomocnicza
 // rysowanie linii pionowych (boki)
 for (j = 0; j < a; j++) {
GLCD_SetPixel(x, y + j, color);
GLCD_SetPixel(x + b - 1, y + j, color);
}
 // rysowanie linii poziomych (podstawy)
 for (j = 0; j < b; j++)	{
GLCD_SetPixel(x + j, y, color);
GLCD_SetPixel(x + j, y + a - 1, color);
}
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_Circle(unsigned char cx, unsigned char cy ,unsigned char radius)
{
int x, y, xchange, ychange, radiusError;
x = radius;
y = 0;
xchange = 1 - 2 * radius;
ychange = 1;
radiusError = 0;
while(x >= y)
 {
 GLCD_SetPixel(cx+x, cy+y, color); 
 GLCD_SetPixel(cx-x, cy+y, color); 
 GLCD_SetPixel(cx-x, cy-y, color);
 GLCD_SetPixel(cx+x, cy-y, color); 
 GLCD_SetPixel(cx+y, cy+x, color); 
 GLCD_SetPixel(cx-y, cy+x, color); 
 GLCD_SetPixel(cx-y, cy-x, color); 
 GLCD_SetPixel(cx+y, cy-x, color); 
 y++;
 radiusError += ychange;
 ychange += 2;
 if ( 2*radiusError + xchange > 0 )
   {
   x--;
radiusError += xchange;
xchange += 2;
}
 }
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------
void GLCD_Line(int X1, int Y1,int X2,int Y2,unsigned char lineColor)
{
int CurrentX, CurrentY, Xinc, Yinc, 
   Dx, Dy, TwoDx, TwoDy, 
TwoDxAccumulatedError, TwoDyAccumulatedError;

Dx = (X2-X1); // obliczenie sk�adowej poziomej
Dy = (Y2-Y1); // obliczenie sk�adowej pionowej

TwoDx = Dx + Dx; // podwojona sk�adowa pozioma
TwoDy = Dy + Dy; // podwojona sk�adowa pionowa

CurrentX = X1; // zaczynamy od X1
CurrentY = Y1; // oraz Y1

Xinc = 1; // ustalamy krok zwi�kszania pozycji w poziomie 
Yinc = 1; // ustalamy krok zwi�kszania pozycji w pionie

if(Dx < 0) // jesli sk�adowa pozioma jest ujemna 
 {
 Xinc = -1; // to b�dziemy si� "cofa�" (krok ujemny)
 Dx = -Dx;  // zmieniamy znak sk�adowej na dodatni
 TwoDx = -TwoDx; // jak r�wnie� podwojonej sk�adowej
 }

if (Dy < 0) // je�li sk�adowa pionowa jest ujemna
 {
 Yinc = -1; // to b�dziemy si� "cofa�" (krok ujemny)
 Dy = -Dy; // zmieniamy znak sk�adowej na dodatki
 TwoDy = -TwoDy; // jak r�wniez podwojonej sk�adowej
 }

GLCD_SetPixel(X1,Y1, lineColor); // stawiamy pierwszy krok (zapalamy pierwszy piksel)

if ((Dx != 0) || (Dy != 0)) // sprawdzamy czy linia sk�ada si� z wi�cej ni� jednego punktu ;)
 {
 // sprawdzamy czy sk�adowa pionowa jest mniejsza lub r�wna sk�adowej poziomej
 if (Dy <= Dx) // je�li tak, to idziemy "po iksach"
   { 
   TwoDxAccumulatedError = 0; // zerujemy zmienn� 
   do // ruszamy w drog�
 {
     CurrentX += Xinc; // do aktualnej pozycji dodajemy krok 
     TwoDxAccumulatedError += TwoDy; // a tu dodajemy podwojon� sk�adow� pionow�
     if(TwoDxAccumulatedError > Dx)  // je�li TwoDxAccumulatedError jest wi�kszy od Dx
       {
       CurrentY += Yinc; // zwi�kszamy aktualn� pozycj� w pionie
       TwoDxAccumulatedError -= TwoDx; // i odejmujemy TwoDx
       }
      GLCD_SetPixel(CurrentX,CurrentY, lineColor);// stawiamy nast�pny krok (zapalamy piksel)
      }while (CurrentX != X2); // idziemy tak d�ugo, a� osi�gniemy punkt docelowy
    }
  else // w przeciwnym razie idziemy "po igrekach" 
     {
     TwoDyAccumulatedError = 0; 
     do 
   {
       CurrentY += Yinc; 
       TwoDyAccumulatedError += TwoDx;
       if(TwoDyAccumulatedError>Dy) 
         {
         CurrentX += Xinc;
         TwoDyAccumulatedError -= TwoDy;
         }
        GLCD_SetPixel(CurrentX,CurrentY, lineColor);
        }while (CurrentY != Y2);
   }
 }
}
//-------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------


herhalde hepsini verdim.

fryrmnd

Eyvallah hocam. Esasında ben pic ile sürmeye çalışıyordum. Daha öncesinde tam dikkat etmemişim fazla eklemeler yapmışım. Şimdi derleyebildim yalnız bu sefer de string yazımında sıkıntı var  :(.


Şekil çizimi ve pixel basımı normal. Ama ByteMaster hocamında dediği gibi  tek tek pixel basmak çok yavaş olucakmış gibi gözüküyor. 


Burak B

Bahsettiğim gibi bir 1K buffer ile çok hızlı bir şekilde işlem yaptırabilirsin. Bu tip işler için özel algoritmalar mevcut. Ayrıca pixel basma işini yaparken bölme ve çarpma işlemlerinden mümkün oldukça kaçının. Bunun yerine hazır veriler kullanabilirsiniz. Yada shift ile çarpma bölme yapabilirsiniz. Unutmayın çarpma ve bölme çok yorucu işlemlerdir. Ayrıca uzun döngülerde bu şekilde zaman alıcı ve MCU yu yoran işlemlerdir. Bunu bir buffer ve DMA kanalıyla gerçekleştirirseniz işlemleriniz çok çok hızlanacaktır. Ayrıca söylediğim gibi çarpma ve bölmeden kaçının.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle