
KULLANIM KİTAPÇIĞI
==================
LDMicro desteklenen MicroChip PIC16 ve Atmel AVR mikrokontrolcüler için
gerekli kodu üretir. Bu iş için kullanılabilecek değişik programlar vardır.
Örneğin BASIC, C, assembler gibi. Bu programlar kendi dillerinde yazılmış
programları işlemcilerde çalışabilecek dosyalar haline getirirler.

PLC'de kullanılan dillerden biri  ladder diyagramıdır. Aşağıda LDMicro ile
yazılmış basit bir program görülmektedir.

   ||                                                                    ||
   ||    Xbutton1           Tdon           Rchatter           Yred       ||
 1 ||-------]/[---------[TON 1.000 s]-+-------]/[--------------( )-------||
   ||                                 |                                  ||
   ||    Xbutton2           Tdof      |                                  ||
   ||-------]/[---------[TOF 2.000 s]-+                                  ||
   ||                                                                    ||
   ||                                                                    ||
   ||                                                                    ||
   ||    Rchatter            Ton             Tnew           Rchatter     ||
 2 ||-------]/[---------[TON 1.000 s]----[TOF 1.000 s]---------( )-------||
   ||                                                                    ||
   ||                                                                    ||
   ||                                                                    ||
   ||------[END]---------------------------------------------------------||
   ||                                                                    ||
   ||                                                                    ||

(TON=turn-on gecikme; TOF-turn-off gecikme. --] [-- girişler, diğer bir
deyişle kontaklardır. --( )-- ise çıkışlardır. Bunlar bir rölenin bobini
gibi davranırlar. Ladder diyagramı ile ilgili bol miktarda kaynak internet
üzerinde bulunmaktadır. Burada LDMicro'ya has özelliklerden bahsedeceğiz.

LDmicro ladder diyagramını PIC16 veya AVR koduna çevirir. Aşağıda desteklenen
işlemcilerin listesi bulunmaktadır:
    * PIC16F877
    * PIC16F628
    * PIC16F876 (denenmedi)
    * PIC16F88 (denenmedi)
    * PIC16F819 (denenmedi)
    * PIC16F887 (denenmedi)
    * PIC16F886 (denenmedi)
    * ATmega128
    * ATmega64
    * ATmega162 (denenmedi)
    * ATmega32 (denenmedi)
    * ATmega16 (denenmedi)
    * ATmega8 (denenmedi)

Aslında daha fazla PIC16 ve AVR işlemci desteklenebilir. Ancak test ettiklerim
ve desteklediğini düşündüklerimi yazdım. Örneğin PIC16F648 ile PIC16F628
arasında fazla bir fark bulunmamaktadır. Eğer bir işlemcinin desteklenmesini
istiyorsanız ve bana bildirirseniz ilgilenirim.

LDMicro ile ladder diyagramını çizebilir, devrenizi denemek için gerçek zamanlı
simülasyon yapabilirsiniz. Programınızın çalıştığından eminseniz programdaki
giriş ve çıkışlara mikrokontrolörün bacaklarını atarsınız. İşlemci bacakları
belli olduktan sonra programınızı derleyebilirsiniz. Derleme sonucunda oluşan
dosya .hex dosyasıdır. Bu dosyayı PIC/AVR programlayıcı ile işlemcinize kaydedersiniz.
PIC/AVR ile uğraşanlar konuya yabancı değildir.


LDMicro ticari PLC programları gibi tasarlanmıştır. Bazı eksiklikler vardır.
Kitapçığı dikkatlice okumanızı tavsiye ederim. Kullanım esnasında PLC ve
PIC/AVR hakkında temel bilgilere sahip olduğunuz düşünülmüştür.

DİĞER AMAÇLAR
==================

ANSI C kodunu oluşturmak mümkündür. C derleyicisi olan herhangi bir
işlemci için bu özellikten faydalanabilirsiniz. Ancak çalıştırmak için
gerekli dosyaları siz sağlamalısınız. Yani, LDMicro sadece PlcCycle()
isimli fonksiyonu üretir. Her döngüde PlcCycle fonksiyonunu çağırmak, ve
PlcCycle() fonksiyonunun çağırdığı dijital girişi yazma/okuma vs gibi
G/Ç fonksiyonları sizin yapmanız gereken işlemlerdir.
Oluşturulan kodu incelerseniz faydalı olur.

KOMUT SATIRI SEÇENEKLERİ
========================

Normal şartlarda ldmicro.exe komut satırından seçenek almadan çalışır.
LDMicro'ya komut satırından dosya ismi verebilirsiniz. Örneğin;komut
satırından 'ldmicro.exe asd.ld' yazarsanız bu dosya açılmaya çalışırlır.
Dosya varsa açılır. Yoksa hata mesajı alırsınız. İsterseniz .ld uzantısını
ldmicro.exe ile ilişkilendirirseniz .ld uzantılı bir dosyayı çift tıklattığınızda
bu dosya otomatik olarak açılır. Bkz. Klasör Seçenekleri (Windows).

`ldmicro.exe /c src.ld dest.hex', şeklinde kullanılırsa  src.ld derlenir
ve hazırlanan derleme dest.hex dosyasına kaydedilir. İşlem bitince LDMicro kapanır.
Oluşabilecek tüm mesajlar konsoldan görünür.

TEMEL BİLGİLER
==============

LDMicro açıldığında boş bir program ile başlar. Varolan bir dosya ile başlatırsanız
bu program açılır. LDMicro kendi dosya biçimini kullandığından diğer dosya
biçimlerinden dosyaları açamazsınız.

Boş bir dosya ile başlarsanız ekranda bir tane boş satır görürsünüz. Bu satıra
komutları ekleyebilir, satır sayısını artırabilirsiniz. Satırlara Rung denilir.
Örneğin; Komutlar->Kontak Ekle diyerek bir kontak ekleyebilirsiniz. Bu kontağa
'Xnew' ismi verilir. 'X' bu kontağın işlemcinin bacağına denk geldiğini gösterir.
Bu kontağa derlemeden önce isim vermeli ve mikrokontrolörün bir bacağı ile
eşleştirmelisiniz. Eşleştirme işlemi içinde önce işlemciyi seçmelisiniz.
Elemanların ilk harfi o elemanın ne olduğu ile ilgilidir. Örnekler:

    * Xname -- mikrokontrolördeki bir giriş bacağı
    * Yname -- mikrokontrolördeki bir çıkış bacağı
    * Rname -- `dahili röle': hafızada bir bit.
    * Tname -- zamanlayıcı; turn-on, turn-off yada retentive
    * Cname -- sayıcı, yukarı yada aşağı sayıcı
    * Aname -- A/D çeviriciden okunan bir tamsayı değer
    * name  -- genel değişken (tamsayı)

İstediğiniz ismi seçebilirsiniz. Seçilen bir isim nerede kullanılırsa
kullanılsın aynı yere denk gelir. Örnekler; bir satırda Xasd kullandığınızda
bir başka satırda Xasd kullanırsanız aynı değere sahiptirler.
Bazen bu mecburi olarak kullanılmaktadır. Ancak bazı durumlarda hatalı olabilir.
Mesela bir (TON) Turn-On Gecikmeye Tgec ismini verdikten sonra bir (TOF)
Turn_Off gecikme devresine de Tgec ismini verirseniz hata yapmış olursunuz.
Dikkat ederseniz yaptığınız bir mantık hatasıdır. Her gecikme devresi kendi
hafızasına sahip olmalıdır. Ama Tgec (TON) turn-on gecikme  devresini sıfırlamak
için kullanılan RES komutunda Tgec ismini kullanmak gerekmektedir.

Değişken isimleri harfleri, sayıları, alt çizgileri ihtiva edebilir.
(_). Değişken isimleri sayı ile başlamamalıdır. Değişken isimleri büyük-küçük harf duyarlıdır.
Örneğin; TGec ve Tgec aynı zamanlayıcılar değildir.


Genel değişkenlerle ilgili komutlar (MOV, ADD, EQU vs) herhangi bir
isimdeki değişkenlerle çalışır. Bunun anlamı bu komutlar zamanlayıcılar
ve sayıcılarla çalışır. Zaman zaman bu faydalı olabilir. Örneğin; bir
zamanlayıcının değeri ile ilgili bir karşılaştırma yapabilirsiniz.

Değişkenler hr zaman için 16 bit tamsayıdır. -32768 ile 32767 arasında
bir değere sahip olabilirler. Her zaman için işaretlidir. (+ ve - değere
sahip olabilirler) Onluk sayı sisteminde sayı kullanabilirsiniz. Tırnak
arasına koyarak ('A', 'z' gibi) ASCII karakterler kullanabilirsiniz.

Ekranın alt tarafındaki kısımda kullanılan tüm elemanların bir listesi görünür.
Bu liste program  tarafından otomatik olarak oluşturulur ve kendiliğinden
güncelleştirilir. Sadece 'Xname', 'Yname', 'Aname' elemanları için
mikrokontrolörün bacak numaraları belirtilmelidir. Önce Ayarlar->İşlemci Seçimi
menüsünden işlemciyi seçiniz. Daha sonra G/Ç uçlarını çift tıklatarak açılan
pencereden seçiminizi yapınız.

Komut ekleyerek veya çıkararak programınızı değiştirebilirsiniz. Programdaki
kursör eleman eklenecek yeri veya hakkında işlem yapılacak elemanı göstermek
amacıyla yanıp söner. Elemanlar arasında <Tab> tuşu ile gezinebilirsiniz. Yada
elemanı fare ile tıklatarak işlem yapılacak elemanı seçebilirsiniz. Kursör elemanın
solunda, sağında, altında ve üstünde olabilir. Solunda ve sağında olduğunda
ekleme yaptığınızda eklenen eleman o tarafa eklenir. Üstünde ve altında iken
eleman eklerseniz eklenen eleman seçili elemana paralel olarak eklenir.
Bazı işlemleri yapamazsınız. Örneğin bir bobinin sağına eleman ekleyemezsiniz.
LDMicro buna izin vermeyecektir.

Program boş bir satırla başlar. Kendiniz alta ve üste satır ekleyerek dilediğiniz
gibi diyagramınızı oluşturabilirsiniz. Yukarıda bahsedildiği gibi alt devreler
oluşturabilirsiniz.

Programınız yazdığınızda simülasyon yapabilir, .hex dosyasını oluşturabilirsiniz.

SİMÜLASYON
==========

Simülasyon moduna geçmek için Simülasyon->Simülasyon modu menüsünü tıklatabilir,
yada <Ctrl+M> tuş kombinasyonuna basabilirsiniz. Simülasyon modunda program
farklı bir görüntü alır. Kursör görünmez olur. Enerji alan yerler ve elemanlar
parlak kırmızı, enerji almayan yerler ve elemanlar gri görünür. Boşluk tuşuna
basarak bir çevrim ilerleyebilir yada menüden Simülasyon->Gerçek Zamanlı Simülasyonu Başlat
diyerek (veya <Ctrl+R>) devamlı bir çevrim başlatabilirsiniz. Ladder diyagramının
çalışmasına göre gerçek zamanlı olarak elemanlar ve yollar program tarafından değiştirilir.

Giriş elemanlarının durumunu çift tıklatarak değiştirebilirsiniz. Mesela, 'Xname'
kontağını çift tıklatıranız açıktan kapalıya veya kapalıdan açığa geçiş yapar.

DERLEME
=======

Ladder diyagramının yapılmasındaki amaç işlemciye yüklenecek .hex dosyasının
oluşturulmasıdır. Buna 'derleme' denir. Derlemeden önce şu aşamalar tamamlanmalıdır:
 1- İşlemci seçilmelidir. Ayarlar->İşlemci Seçimi menüsünden yapılır.
 2- G/Ç uçlarının mikrokontrolördeki hangi bacaklara bağlanacağı seçilmelidir.
    Elemanın üzerine çift tıklanır ve çıkan listeden seçim yapılır.
 3- Çevrim süresi tanımlanmalıdır. Ayarlar->İşlemci Ayarları menüsünden yapılır.
    Bu süre işlemcinin çalıştığı frekansa bağlıdır. Çoğu uygulamalar için 10ms
    uygun bir seçimdir. Aynı yerden kristal frekansını ayarlamayı unutmayınız.

Artık kodu üretebilirsiniz. Derle->Derle yada Derle->Farklı Derle seçeneklerinden
birini kullanacaksınız. Aradaki fark Kaydet ve Farklı Kaydet ile aynıdır. Sonuçta
Intel IHEX dosyanız programınızda hata yoksa üretilecektir. Programınızda hata varsa
uyarı alırsınız.

Progamlayıcınız ile bu dosyayı işlemcinize yüklemelisiniz. Buradaki en önemli nokta
işlemcinin konfigürasyon bitlerinin ayarlanmasıdır. PIC16 işlemciler için gerekli
ayar bilgileri hex dosyasına kaydedildiğinden programlayıcınız bu ayarları algılayacaktır.
Ancak AVR işlemciler için gerekli ayarları siz yapmalısınız.

KOMUTLAR ve ELEMANLAR
=====================

> KONTAK, NORMALDE AÇIK         Xname           Rname          Yname
                             ----] [----     ----] [----    ----] [----

    Normalde açık bir anahtar gibi davranır. Komutu kontrol eden sinyal 0 ise
    çıkışındaki sinyalde 0 olur. Eğer kontrol eden sinyal 1 olursa çıkışı da 1
    olur ve çıkışa bağlı bobin aktif olur. Bu kontak işlemci bacağından alınan
    bir giriş, çıkış bacağı yada dahili bir röle olabilir.


> KONTAK, NORMALDE KAPALI       Xname           Rname          Yname
                             ----]/[----     ----]/[----    ----]/[----

    Normalde kapalı bir anahtar gibi davranır. Komutun kontrol eden sinyal 0 ise
    çıkışı 1 olur. Eğer kontrol eden sinyal 1 olursa çıkışı 0 olur ve çıkışa
    bağlı elemanlar pasif olur. Normalde çıkışa gerilim verilir, ancak bu kontağı
    kontrol eden sinyal 1 olursa kontağın çıkışında gerilim olmaz. Bu kontak
    işlemci bacağından alınan bir giriş, çıkış bacağı yada dahili bir röle olabilir


> BOBİN, NORMAL                 Rname           Yname
                             ----( )----     ----( )----

    Elemana giren sinyal 0 ise dahili röle yada çıkış bacağı 0 yapılır.
    Elemana giren sinyal 1 ise dahili röle yada çıkış bacağı 1 yapılır.
    Bobine  giriş değişkeni atamak mantıksızdır. Bu eleman bir satırda
    sağdaki en son eleman olmalıdır.


> BOBİN, TERSLENMİŞ             Rname           Yname
                             ----(/)----     ----(/)----

    Elemana giren sinyal 0 ise dahili röle yada çıkış bacağı 1 yapılır.
    Elemana giren sinyal 1 ise dahili röle yada çıkış bacağı 0 yapılır.
    Bobine  giriş değişkeni atamak mantıksızdır. Bu eleman bir satırda
    sağdaki en son eleman olmalıdır. Normal bobinin tersi çalışır.


> BOBİN, SET                   Rname           Yname
                             ----(S)----     ----(S)----

    Elemana giren sinyal 1 ise dahili röle yada çıkış bacağı 1 yapılır.
    Diğer durumlarda bu bobinin durumunda bir değişiklik olmaz. Bu komut
    bobinin durumunu sadece 0'dan 1'e çevirir. Bu nedenle çoğunlukla
    BOBİN-RESET ile beraber çalışır. Bu eleman bir satırda sağdaki en
    son eleman olmalıdır.


> BOBİN, RESET                 Rname           Yname
                             ----(R)----     ----(R)----

    Elemana giren sinyal 1 ise dahili röle yada çıkış bacağı 0 yapılır.
    Diğer durumlarda bu bobinin durumunda bir değişiklik olmaz. Bu komut
    bobinin durumunu sadece 1'dEn 0'a çevirir. Bu nedenle çoğunlukla
    BOBİN-SET ile beraber çalışır. Bu eleman bir satırda sağdaki en
    son eleman olmalıdır.


> TURN-ON GECİKME               Tdon
                           -[TON 1.000 s]-

    Bir zamanlayıcıdır. Girişindeki sinyal 0'dan 1'e geçerse ayarlanan
    süre kadar sürede çıkış 0 olarak kalır, süre bitince çıkışı 1 olur.
    Girişindeki sinyal 1'den 0'a geçerse çıkış hemen 0 olur.
    Girişi 0 olduğu zaman zamanlayıcı sıfırlanır. Ayrıca; ayarlanan süre
    boyunca giriş 1 olarak kalmalıdır.

    Zamanlayıcı 0'dan başlayarak her çevrim süresinde 1 artarak sayar.
    Sayı ayarlanan süreye eşit yada büyükse çıkış 1 olur. Zamanlayıcı
    değişkeni üzerinde işlem yapmak mümkündür. (Örneğin MOV komutu ile)


> TURN-OFF GECİKME               Tdoff
                           -[TOF 1.000 s]-

    Bir zamanlayıcıdır. Girişindeki sinyal 1'den 0'a geçerse ayarlanan
    süre kadar sürede çıkış 1 olarak kalır, süre bitince çıkışı 0 olur.
    Girişindeki sinyal 0'dan 1'e geçerse çıkış hemen 1 olur.
    Girişi 0'dan 1'e geçtiğinde zamanlayıcı sıfırlanır. Ayrıca; ayarlanan
    süre boyunca giriş 0 olarak kalmalıdır.

    Zamanlayıcı 0'dan başlayarak her çevrim süresinde 1 artarak sayar.
    Sayı ayarlanan süreye eşit yada büyükse çıkış 1 olur. Zamanlayıcı
    değişkeni üzerinde işlem yapmak mümkündür. (Örneğin MOV komutu ile)


> SÜRE SAYAN TURN-ON GECİKME        Trto
                               -[RTO 1.000 s]-

    Bu zamanlayıcı girişindeki sinyalin ne kadar süre ile 1 olduğunu
    ölçer. Ayaralanan süre boyunca giriş 1 ise çıkışı 1 olur. Aksi halde
    çıkışı 0 olur. Ayarlanan süre devamlı olması gerekmez. Örneğin; süre
    1 saniyeye ayarlanmışsa ve giriş önce 0.6 sn 1 olmuşsa, sonra 2.0 sn
    boyunca 0 olmuşsa daha sonra 0.4 sn boyunca giriş tekrar 1 olursa
    0.6 + 0.4 = 1sn olduğundan çıkış 1 olur. Çıkış 1 olduktan sonra
    giriş 0 olsa dahi çıkış 0'a dönmez. Bu nedenle zamanlayıcı RES reset
    komutu ile resetlenmelidir.

    Zamanlayıcı 0'dan başlayarak her çevrim süresinde 1 artarak sayar.
    Sayı ayarlanan süreye eşit yada büyükse çıkış 1 olur. Zamanlayıcı
    değişkeni üzerinde işlem yapmak mümkündür. (Örneğin MOV komutu ile)


> RESET (SAYICI SIFIRLAMASI)     Trto             Citems
                             ----{RES}----     ----{RES}----

    Bu komut bir zamanlayıcı veya sayıcıyı sıfırlar. TON ve TOF zamanlayıcı
    komutları kendiliğinden sıfırlandığından bu komuta ihtiyaç duymazlar.
    RTO zamanlayıcısı ve CTU/CTD sayıcıları kendiliğinden sıfırlanmadığından
    sıfırlanmaları için kullanıcı tarafından bu komutile sıfırlanması
    gerekir. Bu komutun girişi 1 olduğunda sayıcı/zamanlayıcı sıfırlanır.
    Bu komut bir satırın sağındaki son komut olmalıdır.


> YÜKSELEN KENAR                _    _
                           --[_/ OSR/ \_]--

    Bu komutun çıkışı normalde 0'dır. Bu komutun çıkışının 1 olabilmesi
    için bir önceki çevrimde girişinin 0 şimdiki çevrimde girişinin 1
    olması gerekir. Komutun çıkışı bir çevrimlik bir pals üretir.
    Bu komut bir sinyalin yükselen kenarında bir tetikleme gereken
    uygulamalarda faydalıdır.


> DÜŞEN KENAR                 _      _
                           --[ \_OSF/ \_]--

    Bu komutun çıkışı normalde 0'dır. Bu komutun çıkışının 1 olabilmesi
    için bir önceki çevrimde girişinin 1 şimdiki çevrimde girişinin 0
    olması gerekir. Komutun çıkışı bir çevrimlik bir pals üretir.
    Bu komut bir sinyalin düşen kenarında bir tetikleme gereken
    uygulamalarda faydalıdır.


> KISA DEVRE, AÇIK DEVRE
                           ----+----+----      ----+     +----

    Kısa devrenin çıkışı her zaman girişinin aynısıdır.
    Açık devrenin çıkışı her zaman 0'dır. Bildiğimiz açık/kısa devrenin
    aynısıdır. Genellikle hata aramada kullanılırlar.

> ANA KONTROL RÖLESİ
                           -{MASTER RLY}-

    Normalde her satırın ilk girişi 1'dir. Birden fazla satırın tek bir şart ile
    kontrol edilmesi gerektiğinde paralel bağlantı yapmak gerekir. Bu ise zordur.
    Bu işlemi kolayca yapabilmek için ana kontrol rölesini kullanabiliriz.
    Ana kontrol rölesi eklendiğinde kendisinden sonraki satırlar bu röleye bağlı
    hale gelir. Böylece; birden fazla satır tek bir şart ile kontrolü sağlanır.
    Bir ana kontrol rölesi kendisinden sonra gelen ikinci bir ana kontrol
    rölesine kadar devam eder. Diğer bir deyişle birinci ana kontrol rölesi
    başlangıcı ikincisi ise bitişi temsil eder. Ana kontrol rölesi kullandıktan
    sonra işlevini bitirmek için ikinci bir ana kontrol rölesi eklemelisiniz.

> MOVE                      {destvar :=  }      {Tret :=     }
                           -{ 123     MOV}-    -{ srcvar  MOV}-

    Girişi 1 olduğunda verilen sabit sayıyı (123 gibi) yada verilen değişkenin
    içeriğini (srcvar) belirtilen değişkene (destvar) atar. Giriş 0 ise herhangi
    bir işlem olmaz. Bu komut ile zamanlayıcı ve sayıcılar da dahil olmak üzere
    tüm değişkenlere değer atayabilirsiniz. Örneğin Tsay zamanlayıcısına MOVE ile
    0 atamak ile RES ile sıfırlamak aynı sonucu doğurur. Bu komut bir satırın
    sağındaki en son komut olmalıdır.

> MATEMATİK İŞLEMLER         {ADD  kay  :=}       {SUB  Ccnt :=}
                            -{ 'a' + 10   }-     -{ Ccnt - 10  }-

>                            {MUL  dest :=}       {DIV  dv :=  }
                            -{ var * -990 }-     -{ dv / -10000}-

    Bu komutun girişi doğru ise belirtilen hedef değişkenine verilen matematik
    işlemin sonucunu kaydeder. İşlenen bilgi zamanlayıcı ve sayıcılar dahil
    olmak üzere değişkenler yada sabit sayılar olabilir. İşlenen bilgi 16 bit
    işaretli sayıdır. Her çevrimde işlemin yeniden yapıldığı unutulmamalıdır.
    Örneğin artırma yada eksiltme yapıyorsanız yükselen yada düşen kenar
    kullanmanız gerekebilir. Bölme (DIV) virgülden sonrasını keser. Örneğin;
    8 / 3 = 2 olur. Bu komut bir satırın sağındaki en son komut olmalıdır.


> KARŞILAŞTIRMA         [var ==]        [var >]        [1 >=]
                       -[ var2 ]-      -[ 1   ]-      -[ Ton]-

>                       [var !=]       [-4 <   ]       [1 <=]
                       -[ var2 ]-     -[ vartwo]-     -[ Cup]-

    Değişik karşılaştırma komutları vardır. Bu komutların girişi doğru (1)
    ve verilen şart da doğru ise çıkışları 1 olur.


> SAYICI                       Cname          Cname
                           --[CTU >= 5]--  --[CTD > -5]--

    Sayıcılar girişlerinin 0'dan 1'e her geçişinde yani yükselen kenarında
    değerlerini 1 artırır (CTU) yada eksiltirler (CTD). Verilen şart doğru ise
    çıkışları aktif (1) olur. CTU ve CTD sayıcılarına aynı ismi erebilirsiniz.
    Böylece aynı sayıcıyı artırmış yada eksiltmiş olursunuz. RES komutu sayıcıları
    sıfırlar. Sayıcılar ile genel değişkenlerle kullandığınız komutları kullanabilirsiniz.


> DAİRESEL SAYICI              Cname
                           --{CTC 0:7}--

    Normal yukarı sayıcıdan farkı belirtilen limite ulaşınca sayıcı tekrar 0'dan başlar
    Örneğin sayıcı 0, 1, 2, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 2,.... şeklinde
    sayabilir. Yani bir dizi sayıcı olarak düşünülebilir. CTC sayıcılar girişlerinin
    yükselen kenarında değer değiştirirler. Bu komut bir satırın sağındaki
    en son komut olmalıdır.


> SHIFT REGISTER            {SHIFT REG   }
                           -{ reg0..3    }-

    Bir dizi değişken ile beraber çalışır. İsim olarak reg verdiğinizi ve aşama
    sayısını 3 olarak tanımladıysanız reg0, reg1, reg2 değikenleri ile çalışırsınız.
    Kaydedicinin girişi reg0 olur. Girişin her yükselen kenarında değerler kaydedicide
    bir sağa kayar. Mesela; `reg2 := reg1'. and `reg1 := reg0'. `reg0' değişmez.
    Geniş bir kaydedici hafızada çok yer kaplar.
    Bu komut bir satırın sağındaki en son komut olmalıdır.


> DEĞER TABLOSU             {dest :=     }
                           -{ LUT[i]     }-

    Değer tablosu sıralanmış n adet değer içeren bir tablodur. Girişi doğru olduğunda
    `dest' tamsayı değişkeni `i' tamsayı değişkenine karşılık gelen değeri alır. Sıra
    0'dan başlar. bu nedenle `i' 0 ile (n-1) arasında olabilir. `i' bu değerler
    arasında değilse komutun ne yapacağı tanımlı değildir.
    Bu komut bir satırın sağındaki en son komut olmalıdır.


> PIECEWISE LINEAR TABLE    {yvar :=     }
                           -{ PWL[xvar]  }-

    Bir matris tablo olarak düşünülebilir. Bir değere bağlı olarak değerin önceden
    belirlenen bir başka değer ile değiştirilmesi içi oluşturulan bir tablodur.
    Bu bir eğri oluşturmak, sensörden alınan değere göre çıkışta başka bir eğri
    oluşturmak gibi amaçlar için kullanılabilir.

    Farzedelimki x tamsayı giriş değerini y tamsayı çıkış değerine yaklaştırmak
    istiyoruz. Değerlerin belirli noktalarda olduğunu biliyoruz. Örneğin;

        f(0)   = 2
        f(5)   = 10
        f(10)  = 50
        f(100) = 100

    Bu şu noktaların eğride olduğunu gösterir:

        (x0, y0)   = (  0,   2)
        (x1, y1)   = (  5,  10)
        (x2, y2)   = ( 10,  50)
        (x3, y3)   = (100, 100)

    Dört değeri parçalı lineer tabloya gireriz. Komut, xvar'ın değerine bakarak
    yvar'a değer verir. Örneğin, yukarıdaki örneğe bakarak, xvar = 10 ise
    yvar = 50 olur.

    Tabloya kayıtlı iki değerin arasında bir değer verirseniz verilen değer de
    alınması gereken iki değerin arasında uygun gelen yerde bir değer olur.
    Mesela; xvar=55 yazarsanız yvar=75 olur. (Tablodaki değerler (10,50) ve
    (100,100) olduğuna göre). 55, 10 ve 100 değerlerinin ortasındadır. Bu
    nedenle 55 ve 75 değerlerinin ortası olan 75 değeri alınır.

    Değerler x koordinatında artan değerler olarak yazılmalıdır. 16 bit tamsayı
    kullanan bazı değerler için arama tablosu üzerinde matematik işlemler
    gerçekleşmeyebilir. Bu durumda LDMicro sizi uyaracaktır. Örneğin aşağıdaki
    tablo bir hata oluşturacaktır:

        (x0, y0)    = (  0,   0)
        (x1, y1)    = (300, 300)

    Bu tip hataları noktalar arsında ara değerler oluşturarak giderebilirsiniz.
    Örneğin aşağıdaki tablo yukarıdakinin aynısı olmasına rağmen hata
    oluşturmayacaktır.

        (x0, y0)    = (  0,   0)
        (x1, y1)    = (150, 150)
        (x2, y2)    = (300, 300)

    Genelde 5 yada 6 noktadan daha fazla değer kullanmak gerekmeyecektir.
    Daha fazla nokta demek daha fazla kod ve daha yavaş çalışma demektir.
    En fazla 10 nokta oluşturabilirsiniz. xvar değişkenine x koordinatında
    tablonun en yüksek değerinden daha büyük bir değer girmenin ve en düşük
    değerinden daha küçük bir değer girmenin sonucu tanımlı değildir.
    Bu komut bir satırın sağındaki en son komut olmalıdır.

> A/D ÇEVİRİCİDEN OKUMA        Aname
                           --{READ ADC}--

    LDmicro A/D  çeviriciden değer okumak için gerekli kodları desteklediği
    işlemciler için oluşturabilir. Komutun girişi 1 olduğunda A/D çeviriciden
    değer okunur ve okunan değer `Aname' değişkenine aktarılır. Bu değişken
    üzerinde genel değişkenlerle kullanılabilen işlemler kullanılabilir.
    (büyük, küçük, büyük yada eşit gibi). Bu değişkene işlemcinin bacaklarından
    uygun biri tanımlanmalıdır. Komutun girişi 0 ise `Aname'değişkeninde bir
    değişiklik olmaz.

    Şu an desteklenen işlemciler için; 0 Volt için ADC'den okunan değer 0,
    Vdd (besleme gerilimi) değerine eşit gerilim değeri için ADC'den okunan değer
    1023 olmaktadır. AVR kullanıyorsanız AREF ucunu Vdd besleme gerilimine
    bağlayınız.

    Aritmetik işlemler ADC değişkeni için kullanılabilir. Ayrıca bacak tanımlarken
    ADC olmayan bacakların tanımlanmasını LDMicro engelleyecektir.
    Bu komut bir satırın sağındaki en son komut olmalıdır.

    > PWM PALS GENİŞLİĞİ AYARI      duty_cycle
                             -{PWM 32.8 kHz}-

    LDmicro desteklediği mikrokontrolörler için gerekli PWM kodlarını üretebilir.
    Bu komutun girişi doğru (1) olduğunda PWM sinyalinin pals genişliği duty_cycle
    değişkeninin değerine ayarlanır. Bu değer 0 ile 100 arasında değişir. Pals
    genişliği yüzde olarak ayarlanır. Bir periyot 100 birim kabul edilirse bu
    genişliğin yüzde kaçının palsi oluşturacağı ayarlanır. 0 periyodun tümü sıfır
    100 ise periyodun tamamı 1 olsun anlamına gelir. 10 değeri palsin %10'u 1 geri
    kalan %90'ı sıfır olsun anlamına gelir.

    PWM frekansını ayarlayabilirsiniz. Verilen değer Hz olarak verilir.
    Verdiğiniz frekans kesinlikle ayarlanabilir olmalıdır. LDMicro verdiğiniz değeri
    olabilecek en yakın değerle değiştirir. Yüksek hızlarda doğruluk azalır.

    Bu komut bir satırın sağındaki en son komut olmalıdır.
    Periyodun süresinin ölçülebilmesi için işlemcinin zamanlayıcılarının bir tanesi
    kullanılır. Bu nedenle PWM en az iki tane zamanlayıcısı olan işlemcilerde kullanılır.
    PWM PIC16 işlemcilerde CCP2'yi, AVR'lerde ise OC2'yi kullanır.


> EEPROMDA SAKLA             saved_var
                           --{PERSIST}--

    Bu komut ile belirtilen değişkenin EEPROM'da saklanması gereken bir değişken olduğunu
    belirmiş olursunuz. Komutun girişi doğru ise belirtilen değişkenin içeriği EEPROM'a
    kaydedilir. Enerji kesildiğinde kaybolmaması istenen değerler için bu komut kullanılır.
    Değişkenin içeriği gerilim geldiğinde tekrar EEPROM'dan yüklenir. Ayrıca;
    değişkenin içeriği her değiştiğinde yeni değer tekrar EEPROM'a kaydedilir.
    Ayrıca bir işlem yapılması gerekmez.
    Bu komut bir satırın sağındaki en son komut olmalıdır.

                        
> UART (SERİ BİLGİ) AL          var
                           --{UART RECV}--

    LDmicro belirli işlemciler için gerekli UART kodlarını üretebilir. AVR işlemcilerde
    sadece UART1 (UART0) değil) desteklenmektedir. İletişim hızı (baudrate) ayarlarını
    Ayarlar->İşlemci Ayarları menüsünden yapmalısınız. Hız kristal frekansına bağlı olup,
    bazı hızlar desteklenmeyebilir. Bu durumda LDMicro sizi uyaracaktır.

    Bu komutun girişi yanlışsa herhangi bir işlem yapılmaz. Doğru ise UART'dan 1 karakter
    alınmaya çalışılır. Okuma yapılamaz ise komutun çıkışı yanlış (0) olur. Karakter
    okunursa okunan karakter `var' değişkeninde saklanır ve komutun çıkışı doğru (1) olur.
    Çıkışın doğru olması sadece bir PLC çevrimi sürer.


> UART (SERİ BİLGİ) GÖNDER      var
                           --{UART SEND}--

    LDmicro belirli işlemciler için gerekli UART kodlarını üretebilir. AVR işlemcilerde
    sadece UART1 (UART0) değil) desteklenmektedir. İletişim hızı (baudrate) ayarlarını
    Ayarlar->İşlemci Ayarları menüsünden yapmalısınız. Hız kristal frekansına bağlı olup,
    bazı hızlar desteklenmeyebilir. Bu durumda LDMicro sizi uyaracaktır.

    Bu komutun girişi yanlışsa herhangi bir işlem yapılmaz. Doğru ise UART'dan 1 karakter
    gönderilir. Gönderilecek karakter gönderme işleminden önce `var' değişkeninde saklı
    olmalıdır. Komutun çıkışı UART meşgulse (bir karakterin gönderildiği sürece)
    doğru (1) olur. Aksi halde yanlış olur.
    Çıkışın doğru olması sadece bir PLC çevrimi sürer.

    Karakterin gönderilmesi belirli bir zaman alır. Bu nedenle başka bir karakter
    göndermeden önce önceki karakterin gönderildiğini kontrol ediniz veya gönderme
    işlemlerinin arasına geikme ekleyiniz. Komutun girişini sadece çıkış yanlış
    (UART meşgul değilse)ise doğru yapınız.

    Bu komut yerine biçimlendirilmiş kelime komutunu (bir sonraki komut) inceleyiniz.
    Biçimlendirilmiş kelime komutunun kullanımı daha kolaydır. İstediğiniz işlemleri
    daha rahat gerçekleştirebilirsiniz.


> UART ÜZERİNDEN BİÇİMLENDİRİLMİŞ KELİME             var
                                            -{"Pressure: \3\r\n"}-

    LDmicro belirli işlemciler için gerekli UART kodlarını üretebilir. AVR işlemcilerde
    sadece UART1 (UART0) değil) desteklenmektedir. İletişim hızı (baudrate) ayarlarını
    Ayarlar->İşlemci Ayarları menüsünden yapmalısınız. Hız kristal frekansına bağlı olup,
    bazı hızlar desteklenmeyebilir. Bu durumda LDMicro sizi uyaracaktır.

    Bu komutun girişi yanlıştan doğruya geçerse (yükselen kenar) ise seri port üzerinden
    tüm kelimeyi gönderir. Eğer kelime `\3' özel kodunu içeriyorsa dizi içeriği
    `var' değişkenin içeriği otomatik olarak kelimeye (string) çevrilerek`var'
    değişkeninin içeriği ile değiştirilir. Değişkenin uzunluğu 3 karakter olacak şekilde
    değiştirilir. Mesela; `var' değişkeninin içeriği 35 ise kelime 35 rakamının başına bir
    adet boşul eklenerek `Pressure:  35\r\n' haline getirilir. Veya `var'değişkeninin
    içeriği 1453 ise yapılacak işlem belli olmaz. Bu durumda `\4' kullanmak gerekebilir.

    Değişken negatif bir sayı olabilecekse `\-3d' (veya `\-4d') gibi uygun bir değer
    kullanmalısınız. Bu durumda LDMicro negatif sayıların önüne eksi işareti, pozitif sayıların
    önüne ise bir boşluk karakteri yerleştirecektir.

    Aynı anda birkaç işlem tanımlanırsa, yada UART ile ilgili işlemler birbirine
    karışık hale getirilirse programın davranışı belirli olmayacaktır. Bu nedenle
    dikkatli olmalısınız.

    Kullanılabilecek özel karakterler (escape kodları) şunlardır:
        * \r   -- satır başına geç
        * \n   -- yeni satır
        * \f   -- kağıdı ilerlet (formfeed)
        * \b   -- bir karakter geri gel (backspace)
        * \t   -- horizontal tab
        * \v   -- vertical tab
        * \a   -- alert
        * \xAB -- ASCII karakter kodu 0xAB (hex)

    Bu komutun çıkışı bilgi gönderiyorken doğru diğer durumlarda yanlış olur.
    Bu komut program hafızasında çok yer kaplar.


MATEMATİKSEL İŞLEMLER İLE İLGİLİ BİLGİ
======================================

Unutmayın ki, LDMicro 16-bit tamsayı matematik komutlarına sahiptir.
Bu işlemlerde kullanılan değerler ve hesaplamanın sonucu -32768 ile
32767 arasında bir tamsayı olabilir.

Mesela y = (1/x)*1200 formülünü hesaplamaya çalışalım. x 1 ile 20
arasında bir sayıdır. Bu durumda y 1200 ile 60 arasında olur. Bu sayı
16-bit bir tamsayı sınırları içindedir. Ladder diyagramımızı yazalım.
Önce bölelim, sonra çarpma işlemini yapalım:

   ||         {DIV  temp  :=}          ||
   ||---------{ 1 / x       }----------||
   ||                                  ||
   ||          {MUL  y  :=  }          ||
   ||----------{ temp * 1200}----------||
   ||                                  ||

Yada bölmeyi doğrudan yapalım:

   ||           {DIV  y  :=}           ||
   ||-----------{ 1200 / x }-----------||

Matematiksel olarak iki işlem aynıd sonucu vermelidir. Ama birinci işlem
yanlış sonuç verecektir. (y=0 olur). Bu hata `temp' değişkeninin 1'den
küçük sonuç vermesindendir.Mesela x = 3 iken (1 / x) = 0.333 olur. Ama
0.333 bir tamsayı değildir. Bu nedenle sonuç 0 olur. İkinci adımda ise
y = temp * 1200 = 0 olur. İkinci şekilde ise bölen bir tamsayı olduğundan
sonuç doğru çıkacaktır.

İşlemlerinizde bir sorun varsa dikkatle kontrol ediniz. Ayrıca sonucun
başa dönmemesine de dikkat ediniz. Mesela 32767 + 1 = -32768 olur.
32767 sınırı aşılmış olacaktır.

Hesaplamalarınızda mantıksal değişimler yaparak doğru sonuçlar elde edebilirsiniz.
Örneğin; y = 1.8*x ise formülünüzü y = (9/5)*x şeklinde yazınız.(1.8 = 9/5)
y = (9*x)/5 şeklindeki bir kod sonucu daha tutarlı hale getirecektir.
performing the multiplication first:

   ||         {MUL  temp  :=}          ||
   ||---------{ x * 9       }----------||
   ||                                  ||
   ||           {DIV  y  :=}           ||
   ||-----------{ temp / 5 }-----------||


KODALAMA ŞEKLİ
==============

Programın sağladığı kolaylıklardan faydalanın. Mesela:

   ||       Xa               Ya        ||
 1 ||-------] [--------------( )-------||
   ||                                  ||
   ||       Xb               Yb        ||
   ||-------] [------+-------( )-------||
   ||                |                 ||
   ||                |       Yc        ||
   ||                +-------( )-------||
   ||                                  ||

yazmak aşağıdakinden daha kolay olacaktır.

   ||       Xa               Ya        ||
 1 ||-------] [--------------( )-------||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||       Xb               Yb        ||
 2 ||-------] [--------------( )-------||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||       Xb               Yc        ||
 3 ||-------] [--------------( )-------||
   ||                                  ||

                  *                 *                  *

Yazdığınız kodların sonuçlarına dikkat ediniz. Aşağıdaki satırlarda
mantıksız bir programlama yapılmıştır. Çünkü hem Xa hemde Xb aynı
anda doğru olabilir.

   ||       Xa         {v  :=       }  ||
 1 ||-------] [--------{ 12      MOV}--||
   ||                                  ||
   ||       Xb         {v  :=       }  ||
   ||-------] [--------{ 23      MOV}--||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||                                  ||
   ||      [v >]             Yc        ||
 2 ||------[ 15]-------------( )-------||
   ||                                  ||

Aşağıdaki satırlar yukarda bahsi geçen tarzdadır. Ancak yapılan
işlem 4-bit binary sayı tamsayıya çevrilmektedir.

   ||                                   {v  :=       }  ||
 3 ||-----------------------------------{ 0       MOV}--||
   ||                                                   ||
   ||       Xb0                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 1    }-----------||
   ||                                                   ||
   ||       Xb1                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 2    }-----------||
   ||                                                   ||
   ||       Xb2                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 4    }-----------||
   ||                                                   ||
   ||       Xb3                  {ADD  v  :=}           ||
   ||-------] [------------------{ v + 8    }-----------||
   ||                                                   ||


HATALAR (BUG)
=============

LDmicro tarafından üretilen kodlar çok verimli kodlar değildir. Yavaş çalışan
ve hafızada fazla yer kaplayan kodlar olabilirler. Buna rağmen orta büyüklükte
bir PIC veya AVR küçük bir PLC'nin yaptığı işi yapar. Bu nedenle diğer sorunlar
yer yer gözardı edlebilir.

Değişken isimleri çok uzun olmamalıdır.

Programınız yada kullandığınız hafıza seçtiğiniz işlemcinin sahip olduğundan
büyükse LDMicro hata vermeyebilir. Dikkat etmezseniz programınız hatalı çalışacaktır.

Bulduğunuz hataları yazara bildiriniz.

Teşekkürler:
    * Marcelo Solano, Windows 98'deki UI problemini bildirdiği için,
    * Serge V. Polubarjev, PIC16F628 işlemcisi seçildiğinde RA3:0'ın çalışmadığı
      ve nasıl düzelteceğimi bildirdiği için,
    * Maxim Ibragimov, ATmega16 ve ATmega162 işlemcileri test ettikleri, problemleri
      buldukları ve bildirdikleri için,
    * Bill Kishonti, sıfıra bölüm hatası olduğunda simülasyonun çöktüğünü bildirdikleri
      için,
    * Mohamed Tayae, PIC16F628 işlemcisinde EEPROM'da saklanması gereken değişkenlerin
      aslında saklanmadığını bildirdiği için,
    * David Rothwell, kullanıcı arayüzündeki birkaç problemi ve "Metin Dosyası Olarak Kaydet"
      fonksiyonundaki problemi bildirdiği için.


KOPYALAMA VE KULLANIM ŞARTLARI
==============================

LDMICRO TARAFINDAN ÜRETİLEN KODU İNSAN HAYATI VE İNSAN HAYATINI ETKİLEYEBİLECEK
PROJELERDE KULLANMAYINIZ. LDMICRO PROGRAMCISI LDMICRO'NUN KENDİNDEN VE LDMICRO
İLE ÜRETİLEN KODDAN KAYNAKLANAN HİÇBİR PROBLEM İÇİN SORUMLULUK KABUL ETMEMEKTEDİR.

Bu program ücretsiz bir program olup, dilediğiniz gibi dağıtabilirsiniz,
kaynak kodda değişiklik yapabilirsiniz. Programın kullanımı Free Software Foundation
tarafından yazılan GNU General Public License (version 3 ve sonrası)şartlarına bağlıdır.

Program faydalı olması ümidiyle dağıtılmıştır. Ancak hiçbir garanti verilmemektedir.
Detaylar için  GNU General Public License içeriğine bakınız.

Söz konusu sözleşmenin bir kopyası bu programla beraber gelmiş olması gerekmektedir.
Gelmediyse <http://www.gnu.org/licenses/> adresinde bulabilirsiniz.


COPYING, AND DISCLAIMER
=======================

DO NOT USE CODE GENERATED BY LDMICRO IN APPLICATIONS WHERE SOFTWARE
FAILURE COULD RESULT IN DANGER TO HUMAN LIFE OR DAMAGE TO PROPERTY. THE
AUTHOR ASSUMES NO LIABILITY FOR ANY DAMAGES RESULTING FROM THE OPERATION
OF LDMICRO OR CODE GENERATED BY LDMICRO.

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.


Jonathan Westhues

Rijswijk      -- Dec 2004
Waterloo ON   -- Jun, Jul 2005
Cambridge MA  -- Sep, Dec 2005
                 Feb, Mar 2006
                 Feb 2007

Email: user jwesthues, at host cq.cx

Türkçe Versiyon : <http://tekelektirik.com/public/ldmicro.rar>
