Enteresan Bir Problem (Kayan Yazı)

Başlatan eyetouch, 24 Mayıs 2009, 14:27:39

eyetouch

Merhabalar

16 satır ve 80 sütunlu, satır taramalı bir kayan yazı projesi yapmaktayım. Kayan yazılarla ilgilenenler mutlaka görmüştür, 152 sütun-16 satırlı bir proje var internette birçok sitede. "bilgeyazilim" kullanıcı adı ile koyulmuş. Onun 80 sütunlu versiyonunu yapayım dedim, ayrıca yaparken programın gereksiz yere çok uzatıldığını gördüm ve hem görsellik açısından, hem bellek tasarrufu açısından programı kısaltmaya karar verdim.

Bilenler bilir, programın yazarı 16 adet 19 elemanlı dizi tanımlamış.

18 - 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0

Böylece 19x8=152 sütunu oluşturmuş.

Ben de satırları ayrı ayrı array olarak tanımlamaktansa, bütün sistemi tek array'da toplamak istedim. 19x16=304 elemanlı bir dizi tanımladım.

303 - 302 - 301 - 300 - 299 - 298 - 297 - 296 - 295 - 294 - 293 - 292 - 291 - 290 - 289 - 288 - 287 - 286 - 285   (1. satır)
284 - 283 - 282 - 281 - 280 - 279 - 278 - 277 - 276 - 275 - 274 - 273 - 272 - 271 - 270 - 269 - 268 - 267 - 266   (2. satır)
. . . .
. . . .
18 - 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 0  (16. satır)

Bu şekilde.

Böylece programın karakter tablosu hariç kısımları yaklaşık 400 satır azalmış oldu. Fakat Proteus simülasyonunda ekranda sadece 14 ve 15. satırlarda led yanıyor. Problemin nerden kaynaklandığı bulmak için çok uğraştım, LCD ekleyip istediğim kısımlarda değişkenlerin değerlerini LCD'ye yazdırarak problemi sonunda buldum. "alinan" değeri ne olursa olsun, karakter tablosunun en üstündeki harfi işliyor sadece.  Benim programda en üstte "nokta" karakteri vardı, 14 ve 15. satırlarda led'lerin yanmasının sebebi de böylece anlaşılmış oldu. En üste "A" harfini getirdim, bu sefer de A harfini aldı. Ama "alinan" değerine bağlı olarak gerekli harfin alt programına gidiyor. alinan=75 (K harfi) dedim, ve K harfi alt programının içine ufak bir Lcd mesajı yazdım ve simülasyonda Lcd'ye yazıyı yazdı.

Özetlemek gerekirse alinan değişkeninin aldığı değere göre gitmesi gereken harfin alt programına gidiyor, fakat satır bilgisini ordan almıyor da en üstte yazılı olan harfe ait alt programdan alıyor. Sorun bununla da bitmiyor, A harfinin ilk sütununda yanması gereken ledler kayarak ilerlerken, geride kalan ledler de olduğu gibi kalıyor:



Tekrar "nokta" karakterini en üste alıyorum programda ve sonuç:



Bugüne kadar birçok yazılım projesiyle uğraştım (Pic, PLC, c++, php), böyle birşey görmedim. Programlama mantığına tamamen aykırı birşey.

Yazdığım programı da hemen vereyim. Bu arada uğraşmak daha kolay olsun diye 16 sütunluymuş gibi değiştirmiştim programı. Normalde matris var byte [32] olan yer matris var byte [304] Karakter tablosunu çıkarıyorum çok uzun olmasın diye..

not: aşağıdaki program 16f877 için ama asıl kullanacağım pic 18f452 (877 96 elemandan fazla array kabul etmiyor)

DEFINE osc 20
ADCON1=7
DATAPIN1 VAR PORTB.0          
CLOCKPIN1 VAR PORTB.1 
LATCH VAR PORTB.2 

TRISB=%00000000 
TRISC=%00000000
TRISD=%00000000
kc var byte           'okunacak adres
kb var byte
k1 var byte 	      'kayma hızı
ks var byte         'kaydırma sayısı (sütun sayısı kadar kaydırmak için)
TEMP VAR BYTE
TEMP2 VAR BYTE
DON VAR BYTE
satir var byte

MATRIS VAR BYTE[32]
satirlar var byte[16]

alinan var byte
clear

DATA@0," ABC",5
PORTD=0 
PORTC=0

start:
kc=0
for kc=0 to 255
    alinan=75  'READ KC,ALINAN 
    IF alinan=5 THEN START
    gosub karakter
    for kb=0 to ks    'harf genişliği kadar kaydır
        for k1=0 to 5
            satir=0   'tarama sayısı , KAYMA HIZI
            gosub tarama
        next k1 
    gosub kaydir  
    next kb
next kc

goto start

karakter: 
   
if alinan=32 then gosub bosluk
if alinan=46 then gosub NOKTA
if alinan=65 then gosub A
if alinan=66 then gosub B
if alinan=67 then gosub C
IF ALINAN=199 THEN GOSUB _C
if alinan=68 then gosub D
if alinan=69 then gosub E
if alinan=70 then gosub F
if alinan=71 then gosub G
IF ALINAN=208 THEN GOSUB _G
if alinan=72 then gosub H
if alinan=73 then gosub I
IF ALINAN=221 THEN GOSUB _I
if alinan=74 then gosub J
if alinan=75 then gosub K
if alinan=76 then gosub L
if alinan=77 then gosub M
if alinan=78 then gosub N
if alinan=79 then gosub O
IF ALINAN=214 THEN GOSUB _O
if alinan=80 then gosub P
if alinan=81 then gosub Q
if alinan=82 then gosub R
if alinan=83 then gosub S
IF ALINAN=222 THEN GOSUB _S
if alinan=84 then gosub T
if alinan=85 then gosub U
IF ALINAN=220 THEN GOSUB _U
if alinan=86 then gosub V
if alinan=87 then gosub W
if alinan=88 then gosub X
if alinan=89 then gosub Y
if alinan=90 then gosub Z
if alinan=48 then gosub _0
if alinan=49 then gosub _1
if alinan=50 then gosub _2
if alinan=51 then gosub _3
if alinan=52 then gosub _4
if alinan=53 then gosub _5
if alinan=54 then gosub _6
if alinan=55 then gosub _7
if alinan=56 then gosub _8
if alinan=57 then gosub _9
return

kaydir:

'Matrisi kaydırma işlemi

FOR DON=31 to 1 STEP -1

  IF DON//2!=0 THEN 'yeni satıra geçilirse
  	TEMP=MATRIS[DON]
  	TEMP=TEMP<<1
  	TEMP2=MATRIS[DON-1]
  	TEMP.0=TEMP2.7
  	MATRIS[DON]=TEMP
  	MATRIS[DON-1]=TEMP2
  ELSE
	MATRIS[DON]=MATRIS[DON]<<1
  ENDIF
  
next
MATRIS[0]=MATRIS[0]<<1

'Karakter Tablolarından Matrise yükleme işlemi

FOR DON=15 to 0 step -1

TEMP=MATRIS[DON*2]
temp2=satirlar[15-DON] '0 dan 15 e kadar gitmesi için
TEMP.0=TEMP2.7
MATRIS[DON*2]=TEMP
satirlar[15-DON]=satirlar[15-DON]<<1

NEXT

return

tarama:

FOR DON=31 to 0 STEP -1
 
  Shiftout DATAPIN1,CLOCKPIN1,1,[MATRIS[DON]]     
 
  if DON//2=0 THEN 'yeni satıra geçince
    satir=satir+1 
    high latch 
    PAUSEUS 10
    low latch
    'satır numarasına göre satırlar açılıyor
    if satir=1 then PORTC=%00000001
    IF satir=2 then PORTC=%00000010  
    IF satir=3 THEN PORTC=%00000100
    IF satir=4 then PORTC=%00001000   
    IF satir=5 THEN PORTD=%00000001
    IF satir=6 then PORTD=%00000010
    IF satir=7 THEN PORTD=%00010000     
    IF satir=8 then PORTC=%10000000
    IF satir=9 THEN PORTC=%01000000  
    IF satir=10 then PORTC=%00100000
    IF satir=11 THEN PORTC=%00010000
    IF satir=12 then PORTD=%00001000
    IF satir=13 THEN PORTD=%00000100
    IF satir=14 THEN PORTD=%00100000   
    IF satir=15 THEN PORTD=%01000000
    IF satir=16 THEN PORTD=%10000000
    
    Pause 1 
    PORTC=0 
    PORTD=0
    
  ENDIF

next 

'karakter tablosu

NOKTA:
ks=1
satirlar[0]=%00000000
satirlar[1]=%00000000
satirlar[2]=%00000000
satirlar[3]=%00000000
satirlar[4]=%00000000
satirlar[5]=%00000000
satirlar[6]=%00000000
satirlar[7]=%00000000
satirlar[8]=%00000000
satirlar[9]=%00000000
satirlar[10]=%00000000
satirlar[11]=%00000000
satirlar[12]=%00000000
satirlar[13]=%11000000
satirlar[14]=%11000000
satirlar[15]=%00000000
return

...
..
böyle gidiyor..


Gördüğünüz gibi "Read kc" olayını da iptal edip direk alinan'a değer vermişim 75 diye. Yorumu olan var mı? Ben mi birşeyi gözden kaçırıyorum yoksa PBP'nin patladığı yer bana mı denk geldi  :)

eyetouch

Evet, programlamanın mantığına aykırı olan şeyi ben yapmışım.

O kadar yazıyorsun yazıyorsun ama,

next

'karakter tablosu

satırları arasında "Return" unutunca yazdıkların da işe yaramıyor :oops:

O halde yukarıdaki kod çalışan programdır. Kayan yazı projeleriyle ilgilenen arkadaşlara yardımcı olur umarım..