avatar_Mucit23

CCS C P10 Led Panel Kütüphanesi

Başlatan Mucit23, 20 Ağustos 2013, 15:08:41

Mucit23

Merhaba Arkadaşlar.

P10 Paneller üzerine ufak bir çalışma yaptım.

P10 Paneller son birkaç yıldır moda oldu ve piyasada oldukça sağlam bir yer sahibi oldu. Gerçekten nerdeyse heryerde bu paneller kullanılarak yapılmış irili ufaklı grafik ekranlara rastlayabilirsiniz.

Normalde Bu paneller için çeşitli özelliklere sahip sürücü kartları bulabilirsiniz. Amacımız bu kartların yapamıyacağı kendi özel projelerinizde bu panelleri kullanmak. Bende bu noktadan yola çıktım.

Herneyse işin ayrıntılarına girmeden önce bazı  teknik detayları belirtmek isterim. Bu panelleri kontrol etmek işlem yoğunluğu olan bir iş, Bu yüzden paneli sürecek olan mikrodenetleyici oldukça yüksek frekanslarda çalışması gerekiyor. Bu yüzden bende 18F serisi ve 40Mhz çalışma frekansını seçtim. 2-3 veya 4 paneli bu hızlarda idare edebilirsiniz fakat fazlası için hızın artması gerekir.

Panel Spi ile Haberleşiyor. üzerinde 16 adet 74595 Shift Register bulunmakta. Bu Shift Registerler dizilişi icabı her biri ayrı bir bölümdeki ledleri kontrol etmektedir.

74595 lerin Panel içerisindeki yapısı resimdeki gibidir.



Panel Yukarıdaki Resime bakarsanız alt alta 4 adet 74595 koyulduğunu görürsünüz. Bu alt alta dizilmiş olan 74595 lerin herbiri 4 adet satırı kontrol etmektedir. (4x4=16Satır) Fakat Aynı anda 4 adet satırı kontrol edemez. Bu seçim işlemide Taramayla yapılır.

Tarama işleminde A ve B ucları kullanılır. Bu pinlere 0-3 arası değer verilerek satır seçimi yapılır.

Aşağıdaki tabloda A ve B pinlerine verilecek değerlere göre aktif olan satırlar gösterilmiştir.



Displayi Sürmek için 74595 lere datalar gönderildikten sonra A ve B ucları konumlandırılıp OE pini 1 Konumuna çekilerek Display Aktif hale getirilir. Ardından belirli bir süre kadar beklenip OE pini 0 konumuna çekilerek yeniden data gönderilir. Sonra Tekrar A ve B pinleri konumlandırılıp Tekrardan OE pini 1 konumuna çekilip display aktif edilir. Panelin sürülüş tarzı bu şekildedir.

Örneğin Yukarıdaki Tablodan örnek vermek gerekirse, A=0, B=0 ike Sadece Kırmızı ile renklendirdiğim satırlar aktif olur.

A=1  B=0 iken Mavi,  A=0 B=1 iken Yeşil, A=1  B=1 iken Sarı Satırlar Aktif olur. Tarama ve Data gönderme işlemi buna göre yapılmaktadır.

Panel'de bir önceki data gönderimi ile bir sonraki data gönderimi arasındaki bekleme biraz önemlidir. Çok Fazla beklemek Display parlaklığını çok arttırıyor. Fakat panelde tümü yanıyorken 5Ampere yakın akım çekiyor. Çok fazla bir değer. Normalde Panelin 4 Amperden fazla akım çekmesine engel olmak gerekiyor. Aksi halde Arkadaki sürücü  enteğreler biraz ısınıyorlar. Bu dediğim süreler 500uS ile 2000uS arasındadır.

Normalde 1000uS en ideali ama ben 800uS bekledim.

Şimdi Panel Hakkında biraz bilgimiz olduğuna göre artık donanıma ve yazılıma bakabiliriz.

Burada ben 18F4620 kullandım. 4xPLL ile 40Mhz de çalıştırdım. Ayrıca donanımsal spi modülünü kullanarak Data gönderiminde max. hıza ulaşmaya çalıştım. Donanımsal spi ile yazılımsal spi arasında oladukça fazla bir hız farkı var.

Panel ile Pic arasındaki bağlantılar aşağıda verdiğim şemadaki gibidir.


Paneli ilk başta elime aldığımda açıkçası nasıl süreceğim hakkında hiçbir fikrim yoktu. Nasıl çalıştığını öğrendikten sonra kendim ekran için bir ram bölgesi ayırıp bu ram bölgesini Timer Kesmesi ile sürekli Ekrana yansıttım. Bu iş için iki boyutlu bir dizi kullandım.

Ekranın ram yapısını aşağıdaki tablodan görebilirsiniz.



Bu ram bölgesini ekrana yansıtmak için Timer kesmesini kullandım. Timer kesmesini 800uS de bir oluşacak şekilde ayarladıktan sonra her kesme oluştuğunda displaya_ram isimli dizinin ilgili bölgesini ekrana gönderip, bilginin gözükecegi satır aktif edilir. Bu işlem sürekli devam etmesi gerekir.

Aşağıdaki kodda timer kesme fonksiyonu ve ram alanını displaye göndermek için hazırladığım Spi data gönderme fonksiyonu var.

Timer Kesme fonksiyonu

#int_timer0 //Timer0 Kesmesi
void Timer0_int(){
set_timer0(133); //800us Gecikme için Timer kuruluyor..
output_toggle(pin_d1);
switch (int_syc) //Her 800us de Bir bir sonraki satıra Geç
{
case 0:
output_low(PinOE);write_data(int_syc);
output_low(PinA);output_low(PinB);output_high(PinOE);
break;
case 1:
output_low(PinOE);write_data(int_syc);
output_high(PinA);output_low(PinB);output_high(PinOE);
break;
case 2:
output_low(PinOE);write_data(int_syc);
output_low(PinA);output_high(PinB);output_high(PinOE);
break;
case 3:
output_low(PinOE);write_data(int_syc);
output_high(PinA);output_high(PinB);output_high(PinOE);
break;
}
int_syc++;if(int_syc>3)int_syc=0;
}


Spi Data gönderme Fonksiyonu

void write_data(unsigned int8 row_adr)
{
int8 i=0,j=0;
int8 k=3;
while(k!=255) // Bu Döngü ileriye doğru sayarsa panel sağdan
{j=15-k; // Sola Doğru yüklenir.
for (i=0;i<4;i++) // Satırlar dolduruluyor..
{
spi_write(display_ram[j][row_adr]);
j-=4;
}
k--;
}
output_high(LATCH);
delay_cycles(2);
output_low(LATCH);
}


Bu Fonksiyonlar ile Yukarıdaki tablodaki ram alanı sürekli ekrana yansıtılır. Çalışması biraz karmaşık görünüyor ama öyle değil biraz inceleyip kodları adım adım takip ederseniz kolayca mantığını kavrarsınız.

Şimdi Yazıdığım Kütüphaneye bakalım. Kütüphanede Tüm Fonksiyonları ben yazmadım açıkçası. Temel olarak Daire çizme, Çizgi çizme, ve dikdörgen çizme fonksiyonlarını keilde ili9325 kütüphanemden aldım. Bunların yanı sıra PutPixel, GetPixel, Bargraph, clear_display, invert_display ve Text Basma Yazı Kaydırma gibi fonksiyonları ben hazırladım.

P10 Panel Kütüphanesi

/*******************************************************************************
* File Name : P10_Panel_Driver.c
* Author : Ferhat YOL
* Version : V1.0
* Date : 13/07/2013
* Description : P10 Panel kütüphanesidir.
* :
*******************************************************************************/

#include "font1 .h"
#include "font2 .h"
#include "font3 .h"
#include "font4 .h"

#define PinA pin_c0
#define PinB pin_c1
#define PinOE pin_c4 //OE=0 Display OFF, OE=1 Display ON
#define LATCH pin_c6

#define Font1H 8
#define Font2H 12
#define Font3H 14
#define Font4H 16
#define Panel 1 //P10 Panel Sayısı
#define RIGHT 0 //
#define LEFT 1 //
#define UP 2 //
#define DOWN 3 //
#define WIDTH 31
#define HEIGHT 15

unsigned int8 display_ram[16][4]; //Bu Bölge Display Ram Alanını belirtir
unsigned char Text[50]="";

void clear_display (int1 fill);
void invert_screen (void);
void Set_Brightness (int8 value);
void PutPixel (unsigned int Xpos, unsigned int Ypos, int1 fill);
int1 GetPixel (unsigned int Xpos, unsigned int Ypos);
void Line (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int1 fill);
void Rectangle (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int1 fill);
void Circle (unsigned int x, unsigned int y, unsigned int size, int1 fill);
void Bargraph (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int1 hor, unsigned int value);
void ShowString (unsigned int x, unsigned int y, unsigned int size, int1 fill);
void TextToLeftScroll (unsigned int Line, unsigned int Size, unsigned int speed, int1 fill);

/*******************************************************************************
* Satır Kaydırma Fonksiyonu *
* Parameter: Line, ZeroBit *
* Return: OwerFlow *
*******************************************************************************/
int1 LineScroll(unsigned int Line, int1 ZeroBit){
unsigned int32 Tam=0;
unsigned int y1=Line%4;
unsigned int y2=Line/4;
int1 OwerFlow;
ZeroBit=1-Zerobit;

OwerFlow=(display_ram[(y2*4)][y1]/128)&0x01;
Tam=display_ram[(y2*4)][y1];
Tam=Tam< <8;
Tam=Tam+display_ram[(y2*4)+1][y1];
Tam=Tam<<8;
Tam=Tam+display_ram[(y2*4)+2][y1];
Tam=Tam<<8;
Tam=Tam+display_ram[(y2*4)+3][y1];

Tam=Tam<<1; Tam=Tam+ZeroBit; display_ram[(y2*4) ][y1]=(int32)(Tam>>24)&0xFF;
display_ram[(y2*4)+1][y1]=(int32)(Tam>>16)&0xFF;
display_ram[(y2*4)+2][y1]=(int32)(Tam>>8)&0xFF;
display_ram[(y2*4)+3][y1]=(int32)(Tam&0xFF);

Return OwerFlow;
}
/*******************************************************************************
* Text Basma Fonksiyonu Font1 *
* Parameter: x, y, Fill *
* Return: *
*******************************************************************************/
void DrawCharFont1(unsigned x, unsigned y, int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int clm=x,row=y;

While (Text[i]!='\0')
{
if(clm+5>WIDTH) //Satır sonuna gelindimi Bir Alt Satıra Geç
{
clm=0;
row=row+8;
if(row+8>HEIGHT+1) break;
}

for(b=0;b<5;b++)
{
cdata=Font_5x7[Text[i]-32][b];
for(a=0;a<8;a++)
{
PutPixel(clm+b,row+a,(fill-(cdata>>a) & 0x01));
}
}

i++;
clm=clm+6;
}
}
/*******************************************************************************
* Text Basma Fonksiyonu Font2 *
* Parameter: x, y, Fill *
* Return: *
*******************************************************************************/
void DrawCharFont2(unsigned int x, unsigned int y, int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int clm=x,row=y;

while(Text[i]!='\0')
{
if(clm+8>WIDTH) //Satır sonuna gelindimi Bir Alt Satıra Geç
{
clm=0;
row=row+12;
if(row+12>HEIGHT+1) break;
}

for(b=0;b<16;b=b+2)
{
cdata=Font_8x12[Text[i]-32][b];
for(a=0;a<8;a++)
{
PutPixel(clm+(b/2),row+a,(fill-(cdata>>a) & 0x01));
}
cdata=Font_8x12[Text[i]-32][b+1];
for(a=0;a<4;a++)
{
PutPixel(clm+(b/2),row+8+a,(fill-(cdata>>a) & 0x01));
}
}
clm=clm+8;
i++;
}
}
/*******************************************************************************
* Text Basma Fonksiyonu Font3 *
* Parameter: x, y, Fill *
* Return: *
*******************************************************************************/
void DrawCharFont3(unsigned int x, unsigned int y, int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int clm=x,row=y;

while(Text[i]!='\0')
{
if(clm+12>WIDTH) //Satır sonuna gelindimi Bir Alt Satıra Geç
{
clm=0;
row=row+14;
if(row+14>HEIGHT+1) break;
}

for(b=0;b<24;b=b+2)
{
cdata=Font_12x14[Text[i]-32][b];
for(a=0;a<8;a++)
{
PutPixel(clm+(b/2),row+a,(fill-(cdata>>a) & 0x01));
}
cdata=Font_12x14[Text[i]-32][b+1];
for(a=0;a<6;a++)
{
PutPixel(clm+(b/2),row+8+a,(fill-(cdata>>a) & 0x01));
}
}
clm=clm+12;
i++;
}
}
/*******************************************************************************
* Text Basma Fonksiyonu Font4 *
* Parameter: x, y, Fill *
* Return: *
*******************************************************************************/
void DrawCharFont4(unsigned int x, unsigned int y, int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int clm=x,row=y;

while(Text[i]!='\0')
{
if(clm+12>WIDTH) //Satır sonuna gelindimi Bir Alt Satıra Geç
{
clm=0;
row=row+16;
if(row+16>HEIGHT+1) break;
}

for(b=0;b<24;b=b+2)
{
cdata=Font_12x16[Text[i]-32][b];
for(a=0;a<8;a++)
{
PutPixel(clm+(b/2),row+a,(fill-(cdata>>a) & 0x01));
}
cdata=Font_12x16[Text[i]-32][b+1];
for(a=0;a<8;a++)
{
PutPixel(clm+(b/2),row+8+a,(fill-(cdata>>a) & 0x01));
}
}
clm=clm+12;
i++;
}
}
/*******************************************************************************
* Text Kaydırma Fonksiyonu Font1 *
* Parameter: Line, Speed, Fill *
* Return: *
*******************************************************************************/
void ScrollTextFont1 (unsigned int Line, unsigned int speed,int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int16 delay=speed*20;
int1 ZeroBit=0;

While(Text[i]!='\0')
{
if(Line+Font1H-1>HEIGHT)Break;
for(b=0;b<5;b++)
{
cdata=Font_5x7[Text[i]-32][b];
for (a=0;a<8;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(Line+a,ZeroBit);
}
delay_Ms(210-delay);
}
for (a=0;a<8;a++)
{
LineScroll(Line+a,0);
}
delay_Ms(210-delay);
i++;
}
}
/*******************************************************************************
* Text Kaydırma Fonksiyonu Font2 *
* Parameter: Line, Speed, Fill *
* Return: *
*******************************************************************************/
void ScrollTextFont2(unsigned int Line, unsigned int Speed,int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int16 delay=speed*20;
int1 ZeroBit=0;

while(Text[i]!='\0')
{
if(Line+Font2H-1>HEIGHT)Break;
for(b=0;b<16;b=b+2)
{
cdata=Font_8x12[Text[i]-32][b];
for(a=0;a<8;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(Line+a,ZeroBit);
}
cdata=Font_8x12[Text[i]-32][b+1];
for(a=0;a<4;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(Line+8+a,ZeroBit);
}
delay_Ms(210-delay);
}
i++;
}
}
/*******************************************************************************
* Text Kaydırma Fonksiyonu Font3 *
* Parameter: Line, Speed, Fill *
* Return: *
*******************************************************************************/
void ScrollTextFont3(unsigned int Line, unsigned int Speed,int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int16 delay=speed*20;

int1 ZeroBit=0;

while(Text[i]!='\0')
{
if(Line+Font3H-1>HEIGHT)Break;
for(b=0;b<24;b=b+2)
{
cdata=Font_12x14[Text[i]-32][b];
for(a=0;a<8;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(Line+a,ZeroBit);
}
cdata=Font_12x14[Text[i]-32][b+1];
for(a=0;a<6;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(Line+8+a,ZeroBit);
}
delay_Ms(210-delay);
}
i++;
}
}
/*******************************************************************************
* Text Kaydırma Fonksiyonu Font4 *
* Parameter: Line, Speed, Fill *
* Return: *
*******************************************************************************/
void ScrollTextFont4(unsigned int Line, unsigned int Speed,int1 fill){
unsigned int a=0,b=0,i=0;
unsigned int cdata=0;
unsigned int16 delay=speed*20;
int1 ZeroBit=0;

while(Text[i]!='\0')
{
if(Line+Font4H-1>HEIGHT)Break;
for(b=0;b<24;b=b+2)
{
cdata=Font_12x16[Text[i]-32][b];
for(a=0;a<8;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(a,ZeroBit);
}
cdata=Font_12x16[Text[i]-32][b+1];
for(a=0;a<8;a++)
{
ZeroBit=fill-(cdata>>a) & 0x01;
LineScroll(8+a,ZeroBit);
}
delay_Ms(210-delay);
}
i++;
}
}
/*******************************************************************************
* Ekran Temizleme Fonksiyonu *
* Parameter: fill *
* Return: *
*******************************************************************************/
void clear_display(int1 fill){
int8 i=0,j=0,fdata=0;
if (fill){
fdata=0x00;
}else{
fdata=0xFF;
}
for (i=0;i<4;i++)
{
for (j=0;j<16;j++)
{
display_ram[j][i]=fdata;
}
}
}
/*******************************************************************************
* Ekran Tersleme Fonksiyonu *
* Parameter: *
* Return: *
*******************************************************************************/
void invert_screen(void){
int8 i=0,j=0;

for(i=0;i<4;i++)
{
for(j=0;j<16;j++)
{
display_ram[j][i] =~ display_ram[j][i]; //Önbellekteki değer değillenip geri yazılıyor
}
}
}
/*******************************************************************************
* Parlaklık Ayar Fonksiyonu *
* Parameter: value (0-100) *
* Return: *
*******************************************************************************/
void Set_Brightness(int8 value){
set_pwm1_duty((int16)value*10);
}
/*******************************************************************************
* Pixel Fonksiyonu *
* Parameter: Xpos, Ypos, fill *
* Return: *
*******************************************************************************/
void PutPixel(unsigned int Xpos,unsigned int Ypos, int1 fill)
{
int8 y1=0,x1=0;
int8 y2=0,x2=0;
int8 temp=0;

y1 = Ypos%4;
y2 = Ypos/4;
x1 = Xpos%8;
x2 = Xpos/8;

if(fill) //Nokta Koy
{
temp=display_ram[(y2*4)+x2][y1]; //Ram'deki değer ön belleğe alınıyor.
display_ram[(y2*4)+x2][y1] = (temp & (255-(128>>x1))); //x'inci bit 0 yapılır
}
else //Noktayı Sil
{
temp=display_ram[(y2*4)+x2][y1]; //Ram'deki değer ön belleğe alınıyor.
display_ram[(y2*4)+x2][y1] = (temp | (128>>x1)); //x'inci Bit 1 yapılır
}

}
/*******************************************************************************
* Pixel Okuma Fonksiyonu *
* Parameter: Xpos, Ypos *
* Return: value *
*******************************************************************************/
int1 GetPixel(unsigned int Xpos,unsigned int Ypos){
int8 y1=0,x1=0;
int8 y2=0,x2=0;
int8 temp=0;
int1 value=0;

y1 = Ypos%4;
y2 = Ypos/4;
x1 = Xpos%8;
x2 = Xpos/8;

temp=display_ram[(y2*4)+x2][y1]; //Ram'deki değer ön belleğe alınıyor.
value=1-(0x80 & temp< <x1) 128;="" ram="" adresindeki="" bit="" geri="" gönderiliyor="" return="" value;="" }="" *******************************************************************************="" *="" Çizgi="" Çizme="" fonksiyonu="" parameter:="" x1,="" x2,="" y1,="" y2,="" fill="" return:="" void="" line(unsigned="" int="" unsigned="" int1="" fill)="" {="" signed="" int16="" addx="1," addy="1," p;="" i,="" dy,="" dx,="" diff;="" if(x2="">x1)
{
dx = x2 - x1;
}else{
dx = x1 - x2;
addx = -1;
}
if(y2>y1)
{
dy = y2 - y1;
}else{
dy = y1 - y2;
addy = -1;
}

if(dx >= dy)
{
dy *= 2;
P = dy - dx;
diff = P - dx;

for(i=0; i< =dx; i++)
{
PutPixel(x1, y1, fill);

if(P < 0)
{
P += dy;
x1 += addx;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
else
{
dx *= 2;
P = dx - dy;
diff = P - dy;

for(i=0; i<=dy; ++i)
{
PutPixel(x1, y1, fill);

if(P < 0)
{
P += dx;
y1 += addy;
}
else
{
P += diff;
x1 += addx;
y1 += addy;
}
}
}
}
/*******************************************************************************
* Dikdörtgen Çizme Fonksiyonu *
* Parameter: x1, x2, y1, y2, fill *
* Return: *
*******************************************************************************/
void Rectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int1 fill)
{
unsigned int16 i, xmin, xmax, ymin, ymax;

if(fill)
{
if(x1 < x2)
{
xmin = x1;
xmax = x2;
}
else
{
xmin = x2;
xmax = x1;
}

if(y1 < y2)
{
ymin = y1;
ymax = y2;
}
else
{
ymin = y2;
ymax = y1;
}

for(; xmin <= xmax; ++xmin)
{
for(i=ymin; i<=ymax; ++i)
{
PutPixel(xmin, i, 1);
}
}
}
else
{
Line(x1, y1, x2, y1, 1);
Line(x2, y1, x2, y2, 1);
Line(x2, y2, x1, y2, 1);
Line(x1, y2, x1, y1, 1);
}
}
/*******************************************************************************
* Çember Cizme Fonksiyonu *
* Parameter: x, y, Size, fill *
* Return: *
*******************************************************************************/
void Circle(unsigned int x, unsigned int y, unsigned int size, int1 fill)
{
signed int a,b,P;
a=0;
b=size;
P=1-size;

do
{
if(fill)
{
Line(x-a, y+b, x+a, y+b,1);
Line(x-a, y-b, x+a, y-b,1);
Line(x-b, y+a, x+b, y+a,1);
Line(x-b, y-a, x+b, y-a,1);
}
else
{
PutPixel(a+x, b+y,1);
PutPixel(b+x, a+y,1);
PutPixel(x-a, b+y,1);
PutPixel(x-b, a+y,1);
PutPixel(b+x, y-a,1);
PutPixel(a+x, y-b,1);
PutPixel(x-a, y-b,1);
PutPixel(x-b, y-a,1);
}

if(P < 0)
P+= 3 + 2*a++;
else
P+= 5 + 2*(a++ - b--);

}while(a<=b); } /******************************************************************************* * Bargraph Çizme Fonksiyonu * * Parameter: x1, y1, x2, y2, Mode, Value * * Return: * *******************************************************************************/ void Bargraph (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, int1 hor, unsigned int value,) { unsigned int w=0; unsigned int h=0; unsigned int a=0,b=0; unsigned int16 barval=0; if(x1>x2) w=x1-x2;
if(x1y2) h=y1-y2;
if(y1

if(hor) //Bar Yatay Olarak Oluşturulacak
{
barval=((int16)value*h)/100;

for (a=0;a<h+1;a++)
{
for(b=0;b<w+1;b++) {="" if(barval=""&gt;=a){
PutPixel(x1+b,15-a+y1,1);
}else{
PutPixel(x1+b,15-a+y1,0);
}
}
}

}else{ //Bar Dikey olarak Oluşturulacak

barval=((int16)value*w)/100;

for (a=0;a {
for(b=0;b<h+1;b++) {="" if(barval=""&gt;=a)
{
PutPixel(x1+a,y1+b,1);
}else{
PutPixel(x1+a,y1+b,0);
}
}
}
}
}
/*******************************************************************************
* Text Basma Fonksiyonu *
* Parameter: x, y, size, fill *
* Return: *
*******************************************************************************/
void ShowString(unsigned int x, unsigned int y, unsigned int size, int1 fill){
switch(size)
{
case 1: DrawCharFont1(x,y,fill);break;
case 2: DrawCharFont2(x,y,fill);break;
case 3: DrawCharFont3(x,y,fill);break;
case 4: DrawCharFont4(x,y,fill);break;
default: break;
}
}
/*******************************************************************************
* Text Kaydırma Fonksiyonu *
* Parameter: Line, Size, Speed, Fill *
* Return: *
*******************************************************************************/
void TextToLeftScroll(unsigned int Line, unsigned int Size, unsigned int Speed,int1 fill){
switch (size)
{
case 1: ScrollTextFont1(Line,Speed,fill);Break;
case 2: ScrollTextFont2(Line,Speed,fill);Break;
case 3: ScrollTextFont3(Line,Speed,fill);Break;
case 4: ScrollTextFont4(Line,Speed,fill);Break;
default: Break;
}
}


Kütüphanenin kullanımı çok basit. PutPixel, GetPixel, Line, Rectangle, Circle, Gibi fonksiyonları TFT ekranlarda olduğu gibi kullanabilirsiniz. Sadece Text Basma ve Yazı kaydırma gibi kendi hazırladığım fonksiyonlarına değinmek istiyorum.

Bu fonksiyonları hazırlarken Basılacak veya kaydırılacak olan Text'i fonksiyonun içeriğine göndermeye çalıştım. Bunun için ccs c de göstericilerden faydalanmak gerekiyor. Epeyce bir uğraşmama rağmen gösterici kullanarak yapamadım.

Bende TEXT için ayrı bir ram alanı ayırdım. Yazılacak veya kaydırılacak stringi bu ram alanına yazmak gerekiyor. Ardından yazı basılacaksa text basma fonksiyonunu, kaydırma işlemi yapılacaksa yazı kaydırma fonksiyonunu çağırmak gerekiyor.

Örnek vermek gerekirse,

Text="ABCDEFGH";

ShowString(Xpos,Ypos,Size, Fill);

Bu fonksiyon verilen kordinatlara Text Basar. Xpos ve Ypos Parametreleri Kordinat bilgisidir.

Size Parametresi ise Font Seçim Parametresidir. Benim Programa gömdüğüm 4 dahili font var. Bu yüzden Size Parametresine 1 ile 4 arası bir değer vermeniz gerekir.
Font demişken 2. Ve 3. Fontlarla fazla ilgilenemedim. Biraz düzenlenmesi gerekebilir.

Fill Parametresi Yazının invert olarak basılıp basılmayacağının ayarlandığı parametredir. 1 gönderirseniz yazıyı tersleyip basar. 0 gönderirseniz normal olarak basar.

TextToLeftScroll(Line, Size, Speed, fill);

Bu fonksiyon verilen satırdan itibaren Text Kaydırmaya başlar. Yazının tamamı kayıp bitene kadar fonksiyondan çıkamaz işlemci. Bu fonksiyonun en kötü tarafıda bu oldu.

Neyse Parametrelere gelince

Line; Satır seçim parametresidir. Kaçıncı satırdan itibaren yazı kaydırılacağını belirtir.

Size; Text Basma Fonksiyonunda olduğu gibi font seçim parametresidir.

Speed; Yazı Hızı Parametresi, 1 ile 10 arası değer alır.

Fill; Text Basma Fonksiyonundaki ile aynı işi görür.

Text Basma iyi çalışıyor fakat yazı kaydırma benim pek aklıma yatmadı. Sistemde Rtos benzeri bir yapı olmadığı için Kaydırılacak yazının tümü bitene kadar program yazı kaydırma fonksiyonundan çıkamıyor. Kesme kullanarak bu halledilebilir fakat program esnek olmazdı.

Birde Bargraph üzerine Değineyim.

Bargraph oluşturma fonksiyonunuda ben yazdım. Kullanımı şu şekilde

Bargraph (x1, y1, x2, y2, hor, value);

x1, y1, x2 ve y2 parametreleri ile bargraph boyutu belirlenir.

hor; Bu parametre Bar'ın yatay mı yoksa dikey mi çalışacağını belirtir

Value: Değeri ise Barın değeridir. Bargraph'ın Boyutu ne olursa olsun 0-100 arası bir değer alır. Ölçeklendirme Fonksiyon içerisinde yapılır.

Bargraph üzerine örnek demo programda bulunmaktadır.

Son olarak Parlaklık ayarı üzerine değinmek istiyorum.

Displayin parlaklığını ayarlamak için Donanımsal pwm modülünü kullandım. Pwm Frekansını 10Khz ye ayarladıktan sonra işlemciden çıkan OE sinyaliyle üst üste bindirmek gerekiyor. Bunun için ben bir adet 7408 enteğresini kullandım. 7408 ve kapısının girişlerinin birine pwm sinyali diğerine de OE sinyalini verdikten sonra 7408 in çıkışını Panelin OE kontrol pinine bağladım. Sonra PWM sinyalinin duty cycle değeriyle oynayarak parlaklığı Ayarladım. Ben bu şekilde yaptım. Diğer sürücü kartları nasıl yapıyor açıkçası hiç bilmiyorum.

Örnek bir Test programı hazırladım. Bu test programında kütüphanenin bütün özelliklerini göstermeye çalıştım


#include <18F4620.h>;

#device adc=10

#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES H4 //High speed osc with HW enabled 4X PLL
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=40000000)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#include <math.h>;
/*******************************P10 Panel kütüphanesi**************************/
#include <P10_Panel_Driver.c>;
/********************************Global Değişkenler****************************/
unsigned int8 int_syc=0;
int i=0,w=0;
/**********************************Fonksiyonlar********************************/
void write_data (unsigned int8 row_adr);

void FontTest (void);
void NumberTest (void);
void ScrollTest (void);
void BrightTest (void);
void GeoShapes (void);
void SineWawe (void);
void BarTest (void);
/********************************Kesme Alt Programı****************************/
#int_timer0 //Timer0 Kesmesi
void Timer0_int(){
set_timer0(133); //800us Gecikme için Timer kuruluyor..
switch (int_syc) //Her 800us de Bir bir sonraki satıra Geç
{
case 0:
output_low(PinOE);write_data(int_syc);
output_low(PinA);output_low(PinB);output_high(PinOE);
break;
case 1:
output_low(PinOE);write_data(int_syc);
output_high(PinA);output_low(PinB);output_high(PinOE);
break;
case 2:
output_low(PinOE);write_data(int_syc);
output_low(PinA);output_high(PinB);output_high(PinOE);
break;
case 3:
output_low(PinOE);write_data(int_syc);
output_high(PinA);output_high(PinB);output_high(PinOE);
break;
}
int_syc++;if(int_syc>3)int_syc=0;
}

/**********************************Ana Program*********************************/
void main()
{
set_tris_a(0x03);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
set_tris_e(0x00);

setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_SS_DISABLED);
setup_adc(ADC_OFF);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_OFF);
setup_timer_0(T0_INTERNAl | T0_8_BIT | T0_DIV_64);
setup_timer_2(T2_DIV_BY_4,249,1);
enable_interrupts(INT_timer0);
enable_interrupts(GLOBAL);
set_timer0(133);

output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);
output_e(0x00);

Set_Brightness(10); //Parlaklık veriliyor.
clear_display(0); //Ekranı Temizle

Text="P10";
ShowString(7,0,1,0);
Text="Test";
ShowString(4,8,1,0);
delay_ms(1500);
for (i=0;i<32;i++)
{
for (w=0;w<16;w++)
{
LineScroll(w,0);
}
delay_ms(30);
}

while(TRUE)
{
FontTest();
delay_ms(1000);
NumberTest();
delay_ms(1000);
ScrollTest();
delay_ms(1000);
BrightTest();
delay_ms(1000);
GeoShapes();
delay_ms(1000);
SineWawe();
delay_ms(1000);
BarTest();
delay_ms(2000);

Text="www.arectron.com ";
TextToLeftScroll(4,1,9,0);

delay_ms(2000);
}
}

void write_data(unsigned int8 row_adr)
{
int8 i=0,j=0;
int8 k=3;
while(k!=255) // Bu Döngü ileriye doğru sayarsa panel sağdan
{j=15-k; // Sola Doğru yüklenir.
for (i=0;i<4;i++) // Satırlar dolduruluyor..
{
spi_write(display_ram[j][row_adr]);
j-=4;
}
k--;
}
output_high(LATCH);
delay_cycles(2);
output_low(LATCH);
}

void FontTest(void){
Text="Font";
ShowString(3,0,1,0);
Text="Test";
ShowString(3,8,1,0);
delay_ms(1500);
clear_display(0);
delay_ms(100);

Text="A";
for (i=1;i&lt;5;i++)
{
ShowString(0,0,i,0);
delay_ms(400);
clear_display(0);
}
Text="B";
for (i=1;i<5;i++)
{
ShowString(0,0,i,0);
delay_ms(400);
clear_display(0);
}
Text="C";
for (i=1;i<5;i++)
{
ShowString(0,0,i,0);
delay_ms(400);
clear_display(0);
}
Text="D";
for (i=1;i<5;i++)
{
ShowString(0,0,i,0);
delay_ms(400);
clear_display(0);
}
}

void NumberTest(void){
Text="Numbr";
ShowString(0,0,1,0);
Text="Test";
ShowString(0,8,1,0);
delay_ms(1000);
clear_display(0);
delay_ms(100);
for (i=0;i<100;i++)
{
sprintf(Text,"%02d",i);
ShowString(4,0,4,0);
delay_ms(100);
}
for (i=0;i<3;i++)
{
Text="--";//
ShowString(4,0,4,0);
delay_ms(700);
clear_display(0);
delay_ms(500);
}
clear_display(0);
Text="iNVRT";
ShowString(0,4,1,0);
delay_ms(1000);
clear_display(1);
delay_ms(100);
for (i=0;i<100;i++)
{
sprintf(Text,"%02d",i);
ShowString(4,0,4,1);
delay_ms(100);
}
for (i=0;i<3;i++)
{
Text="--";//
ShowString(4,0,4,1);
delay_ms(700);
clear_display(1);
delay_ms(500);
}
delay_ms(500);
for (i=0;i<32;i++)
{
for (w=0;w<16;w++)
{
LineScroll(w,0);
}
delay_ms(15);
}

}

void ScrollTest(void){
Text="Scrol";
ShowString(0,0,1,0);
Text="Test";
ShowString(0,8,1,0);
delay_ms(1000);
clear_display(0);
delay_ms(100);

Text="FONT 1 ";
TextToLeftScroll(0,1,9,0);
delay_ms(800);
Text="FONT 2 ";
TextToLeftScroll(0,2,9,0);
delay_ms(700);
Text="FONT 3 ";
TextToLeftScroll(0,3,9,0);
delay_ms(600);
Text="FONT 4 ";
TextToLeftScroll(0,4,9,0);
delay_ms(500);
clear_display(1);
Text="Hardware Pic18F4620 & 40Mhz, 64Kb Flash, 3968Byte Ram vs.. ";
TextToLeftScroll(0,4,9,1);
clear_display(0);
}

void BrightTest(void)
{
for(i=1;i<100;i++)
{
Text="Brigt";
ShowString(0,0,1,0);
sprintf(Text,"%02d",i);
ShowString(10,8,1,0);
Set_Brightness(i);
delay_ms(150);
}
Set_Brightness(100);
clear_display(0);
Text="MAX";
for(i=0;i<4;i++)
{
ShowString(4,3,2,0);
delay_ms(800);
clear_display(0);
delay_ms(500);
}
Set_Brightness(10);

}

void GeoShapes(void){
Rectangle(14,6,17,9,0);
delay_ms(600);
clear_display(0);
Rectangle(11,3,20,12,0);
delay_ms(600);
clear_display(0);
Rectangle(8,0,23,15,0);
delay_ms(600);
clear_display(0);
Rectangle(14,6,17,9,1);
delay_ms(600);
clear_display(0);
Rectangle(11,3,20,12,1);
delay_ms(600);
clear_display(0);
Rectangle(8,0,23,15,1);
delay_ms(1000);
clear_display(0);
Circle(16,8,2,0);
delay_ms(600);
clear_display(0);
Circle(16,8,4,0);
delay_ms(600);
clear_display(0);
Circle(16,8,7,0);
delay_ms(600);
clear_display(0);
Circle(16,8,2,1);
delay_ms(600);
clear_display(0);
Circle(16,8,4,1);
delay_ms(600);
clear_display(0);
Circle(16,8,7,1);
delay_ms(1000);
clear_display(0);
delay_ms(100);
Line(0,0,31,15,1);
delay_ms(600);
Line(0,15,31,0,1);
delay_ms(600);
Line(5,0,8,15,1);
delay_ms(600);
Line(31,8,0,4,1);
delay_ms(600);
Line(29,0,10,15,1);
delay_ms(600);
Line(31,13,0,8,1);
delay_ms(1000);

clear_display(0);
}

void SineWawe(void){
float ax=0;
int16 xpos=0;
int8 ypos=0,sayac=0;
Text="Sine";
ShowString(0,0,1,0);
Text="Wave";
ShowString(0,8,1,0);
delay_ms(1000);
clear_display(0);
delay_ms(100);
while(True)
{
for(xpos=0;xpos<19;xpos++)
{
for (i=0;i<16;i++){
LineScroll(i,0);
}
ax=(pi*xpos)/180;
ypos=8+(7*sin(19*ax));
PutPixel(31,ypos,1);
delay_ms(30);
}
sayac++;if(sayac==10)break;
}
clear_display(0);
}

void BarTest(void){
int xstart=0,xend=3;

Text="Bar";
ShowString(0,0,1,0);
Text="Test";
ShowString(0,8,1,0);
delay_ms(1000);
clear_display(0);
delay_ms(100);

for(w=0;w&lt;8;w++)
{
for(i=0;i&lt;101;i++)
{
Bargraph(xstart,0,xend-1,15,1,i);
delay_ms(2);
}
xstart=xstart+4;xend=xend+4;
}
xstart=0;xend=3;
for(w=0;w<8;w++)
{
for(i=0;i<101;i++)
{
Bargraph(xstart,0,xend-1,15,1,100-i);
delay_ms(2);
}
xstart=xstart+4;xend=xend+4;
}
clear_display(0);
xstart=0;xend=3;
for (w=0;w<4;w++)
{
for (i=0;i&lt;101;i++)
{
Bargraph(0,xstart,31,xend-1,0,i);
delay_ms(2);
}
xstart=xstart+4;xend=xend+4;
}
xstart=0;xend=3;
for (w=0;w<4;w++)
{
for (i=0;i<101;i++)
{
Bargraph(0,xstart,31,xend-1,0,100-i);
delay_ms(2);
}
xstart=xstart+4;xend=xend+4;
}
clear_display(0);
for(w=0;w<2;w++)
{
for(i=0;i<101;i++)
{
Bargraph(0,0,31,15,1,i);
delay_ms(1);
}
for(i=0;i<101;i++)
{
Bargraph(0,0,31,15,1,100-i);
delay_ms(1);
}
}
clear_display(0);
for(w=0;w<2;w++)
{
for(i=0;i<101;i++)
{
Bargraph(0,0,31,15,0,i);
delay_ms(1);
}
for(i=0;i<101;i++)
{
Bargraph(0,0,31,15,0,100-i);
delay_ms(1);
}
clear_display(0);
}

}


Bu hazırladığım kütüphane 1 panele göre ayarlanmış durumda. Panel sayısını arttırırsanız fonksiyonları da yeniden ayarlamanız gerekecektir. En önemlisi Ram alanını arttırmanız gerekir. Örneğin iki panel için  32x4 lük bir dizi kullanmanız gerekecektir. Buna benzer ayarları diğer fonksiyonlar içinde yapmanız gerekir.

Yukarıdaki Test Programının çalışma videosunu çektim.

P10 Panel Test

Diyeceklerim bu kadar.

Bu Uygulamaya ait dosyaları buradan indirebilirsiniz.
http://yadi.sk/d/F29kaok-8A1io


İyi Çalışmalar

Edit;
Eklediğim kodlarda problem var sanırım. Kod eklentisi Bazı bölümleri bozmuş. Ek olarak kaynak kodları yakın zamanda eklerim
Edit2: Kaynak Kodlar ve Şema Eklendi
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

kotan04

#1
çok güzel bende bayadır araştırma yapmaktaydım uzun zamandır bağzı sebeplerden dolayı  denemeler yapmıyorum acaba kaynak kodları dosya halinde eklemen mümkünmü ?
ayrıca eklediğin kodlarda problem olduğunu söylemişsin bunu düzelttinmi ?
EX8B2 ExpKits kartındamı yaptın yoksa özel bir kartmı tasarladın merak ettim ?

Mucit23

Yok expkits in kartında denemeyi yaptım. 

Kodlarda sorun var derken benim sitedeki kod eklentisi <  isareti bulunan yerleri başka karakterlerle değiştirmiş.

Kaynak kodlari bugün içerisinde eklerim
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

kotan04

düzeltmeyi yptığın zaman bende deneme sonuçlarını buraya yazacağım font dosyalarını ekliyecekmisin ? onları göremedim

Mucit23

Tamam hepsini ekleyecegim

Biraz sabır lütfen :)
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Mucit23

Kaynak Kodları, Font Dosyalarını ve Devre Şemasını Ekledim.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

mitec

acaba bu çalışmayı bizim anlayacağımız şekilde (pbp veya proton gibi) nasıl düzenleyebiliriz. yoksa basic le bu iş pek olacak gibi değilmi
ben bu c kodlarından neredeyse hiç bir şey anlamadım

oguztkn

arkadaşım bende p12 panel var arka kısmınıda iki adet data konnektörü var onu nasıl sürebilirim

Mucit23

Alıntı yapılan: mitec - 24 Ağustos 2013, 21:00:06
acaba bu çalışmayı bizim anlayacağımız şekilde (pbp veya proton gibi) nasıl düzenleyebiliriz. yoksa basic le bu iş pek olacak gibi değilmi
ben bu c kodlarından neredeyse hiç bir şey anlamadım

Yok Basiclede çalışır. Fakat benim yazdığım programda çok fazla c'ye özgü yapı var. Örneğin iki boyutlu diziler, Çeşitli font dosyaları, vs vs.. Bunları çözersen gerisi kolay
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Mucit23

İki panel kullanımına dair örnek bir uygulama yaptım. Yazdığım Bargraph fonksiyona örnek olabilir.
P10 Panel Bargraph Test
İşlemci olarak STM32F103VE kullanılıyor. İşlemci 72Mhz de çalışıyor. Spi Clock frekansı yaklaşık olarak 9-10 Mhz civarında

Çalışan kodlar bunlar,

int i=0;
while(1)
  {
    for(i=1;i<62;i+=3)
    {
       raom=rand()%100;
       Bargraph(i,0,i+1,15,1,raom);
    }
    delay_ms(100);
  }
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

e135193

Merhabalar, söylediğiniz gibi aşağıdaki değişiklikleri yapıyorum ancak  1 den fazla panel eklesemde sonuç alamadım. Başka bir değişikliği ihtiyaç var mı ? Kullanmak istediğim yapı 64x16 matrix olacak şekilde yani yan yana iki panel.

yardımcı olursanız sevinirim.


unsigned int8 display_ram[32][4];

void write_data(unsigned int8 row_adr)
{
int8 i=0,j=0;
int8 k=7;
while(k!=255) // Bu Döngü ileriye doğru sayarsa panel sağdan
{j=31-k; // Sola Doğru yüklenir.
for (i=0;i<4;i++) // Satırlar dolduruluyor..
{
spi_write(display_ram[j][row_adr]);
j-=8;
}
k–;
}
output_high(LATCH);
delay_cycles(2);
output_low(LATCH);
}

Powered by EzPortal