Şimdi Ara

LCD'yi 4bit modda çalıştırma(ASM)

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
1 Misafir - 1 Masaüstü
5 sn
7
Cevap
0
Favori
703
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
Öne Çıkar
0 oy
Sayfa: 1
Giriş
Mesaj
  • Arkadaşlar elimde LCD'ye mesaj yazan bir program var.Program ilk başta "merhaba dünya" yazıyor.Sonra 9999'a kadar saymaya başlıyor.
    Kod "PİC PROGRAMLAMA TEKNİKLERİ ve PIC16F877A" kitabından alınmıştır.
    Benim problemim şu;
    Kodlar lcd'nin Data uçlarının PORTB'nin ilk dört bitine göre verilmiş.Benim devrede son dört bitine bağlı.Gerekli birkaç değişikliği yaptım ama ekrandan görüntü almayı beceremedim.
    Zaten 4bit Modda ilk denemem, kafam iyice karıştı.
    Sizce kodlarda nasıl bir değiştirme yapmam gerek?
    Kodlar aşağıda
    ;******************************************************************* 
    ; Dosya Adı : 12_1.asm
    ; Programın Amacı : 4-bit arabirim modunda LCD kullanımı
    ; PIC DK2.1a : PORTB Çıkış ==> LCD display
    ; : XT ==> 4Mhz
    ;*******************************************************************
    list p=16F877A
    include "p16F877A.inc"
    __config H'3F31' ;PWRT on, diğerleri kapalı,
    ;Osilatör XT ve 4Mhz
    ;-------------------------------------------------------------------
    ; Değişken tanımları yapılıyor: Her bir değişken başlangıç
    ; adresinden itibaren birbirinin peşi sıra 1 byte yer kaplar.
    ;-------------------------------------------------------------------
    CBLOCK 0x20 ;16F877A'nın RAM başlangıç adresi,
    sayacH ;sayacın yüksek byte'ı.
    sayacL ;sayacın düşük byte'ı.

    LCD_data ;LCD için geçici veri değişkeni.
    LCD_tmp0 ;LCD için geçici veri değişkeni.
    LCD_tmp1 ;LCD için geçici veri değişkeni.
    LCD_line ;LCD için satır bilgisini tutan değişken.
    LCD_pos ;LCD için sütun bilgisi tutan değişken.

    HexMSB ;Desimale çevrilecek sayının en değerli byte'ı.
    HexLSB ;Desimale çevrilecek sayının en değersiz byte'ı.
    binler ;Desimale çevrilen sayının binler basamağı.
    yuzler ;Desimale çevrilen sayının yüzler basamağı.
    onlar ;Desimale çevrilen sayının onlar basamağı.
    birler ;Desimale çevrilen sayının birler basamağı.

    delay_s_data ;Gecikme alt programları için veri değişkeni.
    delay_data ;Gecikme alt programları için veri değişkeni.
    ENDC

    ORG 0
    pagesel Ana_program
    goto Ana_program ;Ana programa git.

    ORG 4 ;Kesme alt programı bu adresten başlıyor.
    goto kesme
    ;-------------------------------------------------------------------
    ; LCD ile ilgili temel tanımlamalar ve mesajlar.
    ;-------------------------------------------------------------------
    ; LCD'nin bağlı olduğu port tanımları yapılıyor.
    #define LCD_DataPort PORTB ;Data pinlerinin bağlı olduğu port
    ;(D7-D4 -> RB3-RB0 ).
    #define LCD_CtrlPort PORTB ;Kontrol pinlerinin bağlandığı port

    ; LCD'nin kontrol pinlerinin bağlı olduğu mikrodenetleyici pinleri
    ; tanımlanıyor.
    #define LCD_RS 4 ;LCD RS pini RB4'e bağlı.
    #define LCD_EN 5 ;LCD E pini RB5'e bağlı.
    #define LCD_RW 6 ;LCD RW pini RB6'ya bağlı.

    mesajlar ;LCD'ye gönderilecek mesajlar buraya yazılıyor.
    addwf PCL, F ;mesaj adresini yükle.
    msg0 dt "Merhaba ", 0 ;0 sonlandırma karakteri.
    msg1 dt "DUNYA!..", 0
    msg2 dt "HEX:", 0
    msg3 dt "DEC:", 0
    ;-------------------------------------------------------------------
    ; LCD ile ilgili macro tanımları:
    ;-------------------------------------------------------------------
    LCD_RS_HIGH macro ;LCD'nin RS girişini HIGH yaparak
    banksel LCD_CtrlPort ;veri alma modu seçilir.
    bsf LCD_CtrlPort, LCD_RS
    endm

    LCD_RS_LOW macro ;LCD'nin RS girişini LOW yaparak
    banksel LCD_CtrlPort ;komut alma modu seçilir.
    bcf LCD_CtrlPort, LCD_RS
    endm

    LCD_EStrobe macro ;LCD'ye veri ya da komut
    banksel LCD_CtrlPort ;gönderildiğinde LCD'nin
    bsf LCD_CtrlPort, LCD_EN ;bunu işlemesini sağlar.
    movlw .20 ;20us kadar bekle.
    call delay_us
    bcf LCD_CtrlPort, LCD_EN
    endm

    LCD_Locate macro line, pos
    movlw line ;Satır bilgisini yükle.
    movwf LCD_line
    movlw pos ;Sütun bilgisini yükle.
    movwf LCD_pos
    call LCD_SetPos ;Kursörü konumlandır.
    endm

    ; ----------------LCD ile ilgili fonksiyonlar.---------------------
    ;-------------------------------------------------------------------
    ; 4 bit iletişim modunda LCD'ye veri transferi yapar.
    ;-------------------------------------------------------------------
    LCD_NybbleOut
    andlw 0x0F ;En değersiz 4 bit W'de,
    movwf LCD_tmp0 ;geçici değişkene alınıyor.
    movf LCD_DataPort,W ;LCD'nin data pinlerinin bağlı
    ;olduğu port bilgisi W'de.
    andlw 0xF0 ;Port bilgisinin en değerli 4 bit’i
    ;korunuyor.
    iorwf LCD_tmp0, W ;Korunan bilgi ile veri
    ;birleştiriliyor.
    movwf LCD_DataPort ;PortA transfer ediliyor.
    LCD_EStrobe ;LCD'nin veriyi alması sağlanıyor.
    movlw .255 ;250us kadar bekle. Bu süre LCD
    ;içerisindeki işlemlerin tamamlanması
    call delay_us ;için gerekli ( en az 160us kadar ).
    return
    ;-------------------------------------------------------------------
    ; LCD'ye 1 byte komut transfer eder.
    ;-------------------------------------------------------------------
    LCD_SendCmd
    movwf LCD_data ;Komutu geçici değişkene al.
    swapf LCD_data, W ;En değerli 4 bit’i gönder.
    LCD_RS_LOW ;RS = 0 (komut modu)
    call LCD_NybbleOut
    movf LCD_data, W ;En değersiz 4 bit’i gönder.
    LCD_RS_LOW ;RS = 0 (komut modu)
    call LCD_NybbleOut
    return
    ;-------------------------------------------------------------------
    ; LCD'ye bir rakam ya da bir karakter göndermek için kullanılır.
    ;-------------------------------------------------------------------
    LCD_SendASCII
    addlw '0' ;LCD'ye rakamı ASCII koda
    ;dönüştürerek göndermek için.
    LCD_SendCHAR ;LCD'ye karakter göndermek için
    ;çağrılacak.
    movwf LCD_data ;Komutu geçici değişkene al.
    swapf LCD_data, W ;En değerli 4 bit’i gönder.
    LCD_RS_HIGH ;RS = 1 ( veri gönderme modu )
    call LCD_NybbleOut
    movf LCD_data, W ;En değersiz 4 bit’i gönder.
    LCD_RS_HIGH ;RS = 1 ( veri gönderme modu )
    call LCD_NybbleOut
    return
    ;-------------------------------------------------------------------
    ; 1 byte veriyi hexadesimal formda LCD'ye yazar.
    ;-------------------------------------------------------------------
    LCD_SendHEX
    movwf LCD_tmp1
    sublw 0x9F ;sayı > 0x9F mi?
    btfss STATUS, C ;hayır ise bir komut atla.
    goto LCD_HEX_j0
    swapf LCD_tmp1, W
    andlw 0x0F ;En değerli 4 bit W'nin en
    call LCD_SendASCII ;değersiz 4 bit’inde.
    goto LCD_HEX_j1
    LCD_HEX_j0
    swapf LCD_tmp1, W
    andlw 0x0F ;En değerli 4 bit W'nin en
    addlw .55 ;değersiz 4 bit’inde.
    call LCD_SendCHAR
    LCD_HEX_j1
    movf LCD_tmp1, W
    andlw 0x0F ;En değersiz 4 bit W'nin en
    movwf LCD_tmp1 ;değersiz 4 bit’inde.
    sublw 0x09 ;sayı > 0x09 mi?
    btfss STATUS, C ;hayır ise bir komut atla.
    goto LCD_HEX_j2
    movf LCD_tmp1, W
    call LCD_SendASCII
    return
    LCD_HEX_j2
    movf LCD_tmp1, W
    addlw .55
    call LCD_SendCHAR
    return
    ;-------------------------------------------------------------------
    ; 1 byte veriyi binary formda LCD'ye yazar.
    ;-------------------------------------------------------------------
    LCD_SendBIN
    movwf LCD_tmp1 ;Geçici değişkene al.
    movlw .0
    btfss LCD_tmp1, 7 ;7. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 7 ;7. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.

    movlw .0
    btfss LCD_tmp1, 6 ;6. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 6 ;6. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.

    movlw .0
    btfss LCD_tmp1, 5 ;5. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 5 ;5. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.

    movlw .0
    btfss LCD_tmp1, 4 ;4. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 4 ;4. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.

    movlw .0
    btfss LCD_tmp1, 3 ;3. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 3 ;3. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.
    movlw .0
    btfss LCD_tmp1, 2 ;2. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 2 ;2. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.

    movlw .0
    btfss LCD_tmp1, 1 ;1. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 1 ;1. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.

    movlw .0
    btfss LCD_tmp1, 0 ;0. bit 1 ise bir komut atla.
    call LCD_SendASCII ;0 yazdır.
    movlw .1
    btfsc LCD_tmp1, 0 ;0. bit 0 ise bir komut atla.
    call LCD_SendASCII ;1 yazdır.
    return
    ;-------------------------------------------------------------------
    ; LCD ekran belleğini siler.
    ;-------------------------------------------------------------------
    LCD_Clear
    movlw 0x01 ;LCD görüntü belleğini sil,
    ;dolayısı ile
    call LCD_SendCmd ;LCD'de görünen bilgileri de sil.
    movlw .5
    call delay_ms
    return
    ;-------------------------------------------------------------------
    ; Kursörü göster
    ;-------------------------------------------------------------------
    LCD_CursorOn
    movlw 0x0F ;Display'i aç, kursörü göster.
    call LCD_SendCmd ;Blink ON.
    return

    ;-------------------------------------------------------------------
    ; Kursörü gizle
    ;-------------------------------------------------------------------
    LCD_CursorOff
    movlw 0x0C ;Display'i aç, kursörü gizle,
    call LCD_SendCmd ;Blink OFF.
    return
    ;-------------------------------------------------------------------
    ; LCD ekranı kullanıma hazırlar.
    ;-------------------------------------------------------------------
    LCD_init
    bsf STATUS, RP0 ;BANK1 seçildi. Yönlendirme
    ;kaydedicileri bu bankta.
    movf LCD_DataPort, W
    andlw 0xF0 ;Portun en değersiz
    ;dörtlüsü çıkış yapıldı.
    movwf LCD_DataPort ;Port yönlendirildi.
    bcf LCD_CtrlPort, LCD_EN ;LCD_CtrlPort'un LCD_EN
    ;pini çıkışa yönlendirildi.
    bcf LCD_CtrlPort, LCD_RS ;LCD_RS pini çıkış yapıldı.
    bcf LCD_CtrlPort, LCD_RW ;LCD_RW pini çıkış yapıldı.
    bcf STATUS, RP0 ;BANK0 seçildi.
    clrf LCD_DataPort

    movlw .50
    call delay_ms ;40-50 ms kadar bekle.
    LCD_RS_LOW
    movlw 0x03 ;8 bit iletişim komutu verildi.
    call LCD_NybbleOut

    movlw .5 ;LCD'nin hazır olması için
    ;bekleniyor.
    call delay_ms

    LCD_EStrobe ;8 bit iletişim için komut
    ;yinelendi.
    movlw .255 ;160-255us kadar bekle.
    call delay_us

    LCD_EStrobe ;8 bit iletişim için komut
    ;yinelendi.
    movlw .255 ;160-255us kadar bekle.
    call delay_us

    LCD_RS_LOW
    movlw 0x02 ;LCD, 4 Bit iletişim moduna alındı.
    call LCD_NybbleOut

    movlw .255 ;160-255us kadar bekle.
    call delay_us

    movlw 0x28 ;4 bit iletişim, 2 satır LCD, 5x7
    call LCD_SendCmd ;font seçildi.
    movlw 0x10 ;LCD'de yazının kayması engellendi.
    call LCD_SendCmd
    movlw 0x01 ;LCD görüntü belleğini sil.
    call LCD_SendCmd

    movlw .5 ;5 ms bekle.
    call delay_ms

    movlw 0x06 ;Kursör her karakter yazımında bir
    call LCD_SendCmd ;ilerlesin.
    movlw 0x0C ;Display'i aç, kursörü gizle.
    call LCD_SendCmd
    return
    ;-------------------------------------------------------------------
    ; Mesaj etiketi (adresi) W’ye yüklenen mesajı LCD ekranda görüntüler
    ;-------------------------------------------------------------------
    LCD_SendMessage
    Movwf FSR ;İlk karaktere işaret et (onun adresini
    LCD_SMsg: ;tut).
    Movf FSR, W ;İşaret edilen karakter sırasını W'ye al.
    incf FSR, F ;Bir sonraki karaktere konumlan.
    Call mesajlar ;Mesajlardan ilgili karakteri al.
    iorlw 0 ;Mesaj sonu mu? 0 bilgisi alındı ise
    ;mesaj sonu demektir.
    btfsc STATUS, Z ;Mesaj sonu değil ise bir komut atla.
    return ;Mesaj sonu ise alt programdan çık.
    call LCD_SendCHAR ;Karakteri LCD'ye yazdır.
    goto LCD_SMsg ;Bir sonraki karakter için
    ;işlemleri tekrarla.
    ;-------------------------------------------------------------------
    ; Kursörü LCD'de istenilen satır ve sütuna konumlandırır. Text'in
    ; nereye yazılacağını belirler. 1 - 2 satır olan LCD'ler için
    ; yazıldığına dikkat ediniz. 4 satır LCD'ler için LCD_line değerinin
    ; 0, 1, 2 veya 3 olması durumuna göre DDRAM başlangıç adresleri
    ; tespit edilmelidir.
    ;-------------------------------------------------------------------
    LCD_SetPos
    movlw 0x80 ;0. satır için DDRAM adres başlangıç
    movf LCD_line, F ;değeri.
    btfss STATUS, Z ;0. satır ise bir komut atla.
    movlw 0xC0 ;1. satır için 0x80 adresine ilave
    ;edilecek değer.
    addwf LCD_pos, W ;Kursör pozisyonu da ilave edilerek
    ;DDRAM'deki adres bulunuyor.
    call LCD_SendCmd
    return
    ;-------------------------------------------------------------------
    ; 2 byte binary veriyi bcd'ye dönüştürür. Sonuç binler, yüzler,
    ; onlar ve birler değişkenlerinde saklanır.
    ;-------------------------------------------------------------------
    HexTODec
    clrf binler ;binler = 0
    clrf yuzler ;yuzler = 0
    clrf onlar ;onlar = 0
    clrf birler ;birler = 0
    binler_kont
    movlw 04h ;W'ye 1024 (0x0400) sayısının en
    ;değerli byte'ını yükle.
    subwf HexMSB, W ;HexMSB'den 1024 çıkart.
    btfss STATUS, C ;HexMSB > 1024'mü?
    goto yuzler_kont2 ;hayır ise yüzleri kontrol et.
    incf binler, F ;evet ise binleri bir artır.
    movlw 04h ;W'ye 0x04 yükle.
    subwf HexMSB, F ;HexMSB'den 1000 çıkart.
    movlw 18h ;W'ye 0x18 yükle.
    addwf HexLSB, F ;HexLSB'ye (0x18 = 24) ekle
    btfsc STATUS, C ;elde var mı?
    incf HexMSB, F ;evet ise bir artır.
    goto binler_kont ;binleri yeniden kontrol et
    yuzler_kont2
    movlw 0x01 ;256 (0x0100)
    subwf HexMSB, W ;HexMSB'den 200 çıkart ve sonucu
    ;W'ye sakla.
    btfss STATUS, C ;sonuç >=256'mı?
    goto yuzler_kont1 ;Hayır ise 100'ün katlarını
    ;kontrol et.
    movlw 0x02 ;değilse,
    addwf yuzler, F ;yuzler'e 2 ekle
    movlw 0x01 ;W = 1
    subwf HexMSB, F ;HexMSB'den 200 çıkart.
    movlw 0x38 ;W =0x38 (256'nın 56 lık kısmı)
    addwf HexLSB, F ;HexLSB'ye 56'yı ekle.
    btfsc STATUS, C ;elde var mı?
    incf HexMSB, F ;evet ise HexMSB'yi bir artır.
    movlw 0x0A ;W = 10
    subwf yuzler, W ;yuzler = 1000 olup olmadığını
    ;kontrol et.
    btfss STATUS, Z ;sonuç sıfır mı?
    goto yuzler_kont2 ;hayır ise yuzleri yeniden kontrol
    clrf yuzler ;et. yuzler = 0
    incf binler, F ;binler'i artır.
    goto yuzler_kont2 ;yuzler'i 200 ya da daha büyük
    ;sayı için yeniden kontrol et.
    yuzler_kont1
    movlw 0x64 ;W = 0x64
    subwf HexLSB, W ;HexLSB'den 100 çıkart.
    btfss STATUS, C ;sonuç >= 100 mü?
    goto onlar_kont ;hayır ise onları kontrol et.
    incf yuzler, F ;evet ise yuzler'i bir artır.
    movlw 0x64 ;W = 0x64 (100)
    subwf HexLSB, F ;HexLSB'yi 100 azalt.
    movlw 0x0A ;W = 0x0A (10)
    subwf yuzler, W ;yuzler = 1000 kontrolü yap.
    btfss STATUS, Z ;sonuç = 0 mı?
    goto yuzler_kont1 ;hayır ise 100 için yuzler'i
    ;yeniden kontrol et.
    clrf yuzler ;yuzler = 0
    incf binler, F ;binleri bir artır.
    goto yuzler_kont1 ;100 ya da daha büyük olma durumu
    ;için yüzleri yeniden kontrol et.
    onlar_kont
    movlw 0x0A ;W = 0x0A (10)
    subwf HexLSB, W ;HexLSB'den 10 çıkart.
    btfss STATUS, C ;sonuç >= 10 mu?
    goto birler_kont ;hayır ise birleri kontrol et.
    incf onlar, F ;evet ise onları bir artır.
    movlw 0x0A ;W = 0x0A (10)
    subwf HexLSB, F ;HexLSB'den 10 çıkart.
    goto onlar_kont ;onlar'ı yeniden kontrol et.
    birler_kont
    movf HexLSB, W ;W = HexLSB
    movwf birler ;birler = W, dönüşüm işlemi tamam
    return ;alt programdan çık.
    ;-------------------------------------------------------------------
    ; 1-255 sn arasında gecikme sağlayan alt program.
    ;-------------------------------------------------------------------
    delay_s
    movwf delay_s_data
    delay_s_j0:
    movlw .250 ;4 * 250 = 1000 ms bekle,
    call delay_ms ;her çevrim 1 sn.
    movlw .250
    call delay_ms
    movlw .250
    call delay_ms
    movlw .250
    call delay_ms
    decfsz delay_s_data
    goto delay_s_j0
    return

    ;-------------------------------------------------------------------
    ; 1-255 ms arasında gecikme sağlayan alt program.
    ;-------------------------------------------------------------------
    delay_ms
    movwf delay_data
    delay_ms_j0
    movlw .142
    movwf delay_data+1
    nop
    nop
    delay_ms_j1
    nop
    nop
    nop
    nop
    decfsz delay_data+1, F
    goto delay_ms_j1
    nop
    decfsz delay_data, F
    goto delay_ms_j0
    nop
    return
    ;-------------------------------------------------------------------
    ; 16-255 µs gecikme sağlayan alt program.
    ;-------------------------------------------------------------------
    delay_us
    movwf delay_data
    rrf delay_data, F
    rrf delay_data, F
    movlw .63
    andwf delay_data, F
    movlw .3
    subwf delay_data, F
    nop
    decfsz delay_data, F
    goto $ - 2
    nop
    return
    ;-------------------------------------------------------------------
    ; Kesme programı (kullanılacak ise LCD ya da zamanlamanın önemli
    ; olduğu cihazlarla çalışırken iletişimin kesilmemesine dikkat
    ; ediniz).
    ;-------------------------------------------------------------------
    kesme
    retfie
    ;-------------------------------------------------------------------
    ; Ana program
    ;-------------------------------------------------------------------
    Ana_program
    call LCD_init ;LCD’yi kullanıma hazırlar.
    Ana_j0:
    call LCD_Clear ;LCD'deki bilgileri sil.
    call LCD_CursorOff ;Kursörü gizle.
    clrf sayacH ;sayac = 0
    clrf sayacL

    LCD_Locate 0, 0 ;0. satır, 0. sütuna konumlan.
    movlw msg0-6 ;mesaj0 yaz (adresi 6 eksiği).
    call LCD_SendMessage
    LCD_Locate 1, 0 ;1. satır, 0. sütuna konumlan
    movlw msg1-6 ;mesaj1 yaz.
    call LCD_SendMessage

    movlw .10
    call delay_s ;10 saniye bekle.

    Ana_j1:
    call LCD_Clear ;LCD'deki bilgileri sil.

    ;sayac değerini hexadesimal formda 0. satıra yaz.
    LCD_Locate 0, 0 ;0. satır, 0. sütuna konumlan.
    movlw msg2-6 ;mesaj2 yaz.
    call LCD_SendMessage
    movf sayacH, W
    call LCD_SendHEX
    movf sayacL, W
    call LCD_SendHEX

    ;sayaç değerini desimal formda 1. satıra yaz.
    LCD_Locate 1, 0 ;0. satır, 0. sütuna konumlan.
    movlw msg3-6 ;mesaj2 yaz.
    call LCD_SendMessage
    movf sayacH, W ;HexMSB = sayacH
    movwf HexMSB
    movf sayacL, W ;HexLSB = sayacL
    movwf HexLSB
    call HexTODec ;Desimale dönüştür.
    movf binler, W ;binler basamağını yaz.
    call LCD_SendASCII
    movf yuzler, W ;yüzler basamağını yaz.
    call LCD_SendASCII
    movf onlar, W ;onlar basamağını yaz.
    call LCD_SendASCII
    movf birler, W ;birler basamağını yaz.
    call LCD_SendASCII

    movlw .1 ;1 sn bekle.
    call delay_s

    ; sayacL değerini binary formda 1. satıra yaz (0. satırda aynı
    ; sayının HEX değeri var).
    LCD_Locate 1, 0 ;0. satır, 0. sütuna konumlan.
    movf sayacL, W
    call LCD_SendBIN ;sayacL değerini binary formda
    ;göster.
    ; sayaç değerini 10000 olana kadar bir artır, 10000 ise en başa dön
    incf sayacL, F ;sayacL'yi bir artır.
    btfsc STATUS, Z ;sayacL sıfırdan farklı ise bir
    ;komut atla.
    incf sayacH, F ;sayacH'i bir artır.
    movlw 0x27
    subwf sayacH, W
    btfss STATUS, Z ;sayacH = 0x27 ise bir komut atla.
    goto Ana_j2 ;sayac henüz 10000'e ulaşmadı, o
    ;halde devam et.
    movlw 0x10
    subwf sayacL, W
    btfss STATUS, Z ;sayacL = 0x10 ise bir komut atla.
    goto Ana_j2 ;sayac henüz 10000'e ulaşmadı, o
    ;halde devam et.
    goto Ana_j0 ;En başa dönerek işlemleri tekrar
    Ana_j2: ;et.
    movlw .1 ;1 sn bekle.
    call delay_s
    goto Ana_j1 ;sayma işlemine devam.

    end
    ;*******************************************************************

    Fikirlerinizi bekliyorum.


    (Bu arada @tyilgin1 benim işi birkaç ufak hatyla da olsa hallettim.)



    < Bu mesaj bu kişi tarafından değiştirildi strom -- 18 Ocak 2008; 22:25:56 >



    _____________________________




  • Arkadaşlar sorunu uzun uğraşlar sonunda buldum.

    LCD_SendCmd
    movwf LCD_data ;
    swapf LCD_data, W
    SWAPF LCD_data,W
    LCD_RS_LOW
    call LCD_NybbleOut
    movf LCD_data, W ;En değersiz 4 bit’i gönder.
    LCD_RS_LOW ;RS = 0 (komut modu)
    call LCD_NybbleOut
    return

    LCD_NybbleOut
    andlw 0x0F
    movwf LCD_tmp0
    SWAPF LCD_tmp0,W
    movf LCD_DataPort,W ;LCD'nin data pinlerinin bağlı
    ;olduğu port bilgisi W'de.
    andlw 0xF0 ;Port bilgisinin en değe
    SWAPF LCD_tmp0,W
    ;korunuyor.
    iorwf LCD_tmp0, W ;Korunan bilgi ile veri
    ;birleştiriliyor.
    movwf LCD_DataPort ;PortA transfer ediliyor.
    LCD_EStrobe ;LCD'nin veriyi alması sağlanıyor.
    movlw .255 ;250us kadar bekle. Bu süre LCD
    ;içerisindeki işlemlerin tamamlanması
    call delay_us ;için gerekli ( en az 160us kadar ).
    return

    LCD_init
    bsf STATUS, RP0 ;BANK1 seçildi. Yönlendirme
    ;kaydedicileri bu bankta.
    movf LCD_DataPort, W
    andlw 0x0F ;Portun en değersiz


    Kodlarındaki koyu renkli komutları ekledim.Artık PORTB'nin üst 4bit'ine bağlı şekilde çalışıyor.
    Herkese teşekkürler.
    _____________________________




  • 1 bit yöntemiyle sürmenin daha rahat ve avantajlı olduğunu düşünüyorum.Ben 1 bitlik yöntemi öneririm.

    Çalışmalarınızda başarılar dilerim.
    _____________________________
  • quote:

    Orjinalden alıntı: 90alper90

    1 bit yöntemiyle sürmenin daha rahat ve avantajlı olduğunu düşünüyorum.Ben 1 bitlik yöntemi öneririm.

    Çalışmalarınızda başarılar dilerim.


    Devreyi kurmuş bulundum.Bu şekilde idare etmem gerek.
    _____________________________
  • quote:

    Orjinalden alıntı: strom


    quote:

    Orjinalden alıntı: 90alper90

    1 bit yöntemiyle sürmenin daha rahat ve avantajlı olduğunu düşünüyorum.Ben 1 bitlik yöntemi öneririm.

    Çalışmalarınızda başarılar dilerim.


    Devreyi kurmuş bulundum.Bu şekilde idare etmem gerek.

    Çalışmalarınızda başarılar.Ben genel olarak fikrimi belirtmek istedim.
    _____________________________
  • Arkadaşlar ufak bir sorun çıktı.RS,E bacaklarını PORTB'deki byte işlemlerinden etkilenmemesi için D portuna tşımıştım.Yukarda bahsettiğim değişikleri yapıp çalıştırdıktan sonra bitleri tekrar B portuna taşıdım.Fakat bu sefer çalışmadı.
    Tahmin ediyorum SWAP komutları LCD'yi etkiledi.Ama başka bir çözümde bulamadım.
    Benim yaptığım yolu yok sayarak yeni önerilerde bulunabilir misiniz?
    Herkese teşekkürler...

    (Not:RS,E bacaklarının port değiştirmelerini
    #define LCD_CtrlPort PORTB ;Kontrol pinlerinin bağlandığı port

    ; LCD'nin kontrol pinlerinin bağlı olduğu mikrodenetleyici pinleri
    ; tanımlanıyor.
    #define LCD_RS 4 ;LCD RS pini RB4'e bağlı.
    #define LCD_EN 5 ;LCD E pini RB5'e bağlı.

    satırlarını değiştirerek yapıyorum.)
    _____________________________
  • Arkadaşlar yukarıdaki kodu boşverin.
    Bana
    LCD PORTB
    D4 ---- B4
    D5 ---- B5
    D6 ---- B6
    D7 ---- B7
    ve
    RS ---- B1
    E ---- B0

    Şekilde LCD-16F877 bağlantısı olan ve ekrana herhangi birşey yazdıran bir program gönderbilir misiniz???

    Ben şu şekilde yazdım.Ama çalışmadı;

    ;******************************************************************* 
    ; Dosya Adı : 12_1.asm
    ; Programın Amacı : 4-bit arabirim modunda LCD kullanımı
    ; PIC DK2.1a : PORTB Çıkış ==> LCD display
    ; : XT ==> 4Mhz
    ;*******************************************************************
    list p=16F877A
    include "p16F877A.inc"
    __config H'3F31' ;PWRT on, diğerleri kapalı,
    ;Osilatör XT ve 4Mhz
    ;-------------------------------------------------------------------
    ; Değişken tanımları yapılıyor: Her bir değişken başlangıç
    ; adresinden itibaren birbirinin peşi sıra 1 byte yer kaplar.
    ;-------------------------------------------------------------------
    CBLOCK 0x20 ;16F877A'nın RAM başlangıç adresi,


    LCD_data ;LCD için geçici veri değişkeni.
    LCD_tmp0 ;LCD için geçici veri değişkeni.
    LCD_tmp1 ;LCD için geçici veri değişkeni.
    LCD_line ;LCD için satır bilgisini tutan değişken.
    LCD_pos ;LCD için sütun bilgisi tutan değişken.

    delay_s_data ;Gecikme alt programları için veri değişkeni.
    delay_data ;Gecikme alt programları için veri değişkeni.
    ENDC

    ORG 0
    pagesel Ana_program
    goto Ana_program ;Ana programa git.

    ORG 4 ;Kesme alt programı bu adresten başlıyor.
    goto kesme
    ;-------------------------------------------------------------------
    ; LCD ile ilgili temel tanımlamalar ve mesajlar.
    ;-------------------------------------------------------------------
    #define LCD_CtrlPort PORTB ;Kontrol pinlerinin bağlandığı port

    ; LCD'nin kontrol pinlerinin bağlı olduğu mikrodenetleyici pinleri
    ; tanımlanıyor.
    #define LCD_RS 1 ;LCD RS pini RB4'e bağlı.
    #define LCD_EN 0 ;LCD E pini RB5'e bağlı.

    ;-------------------------------------------------------------------
    ; LCD ile ilgili macro tanımları:
    ;-------------------------------------------------------------------
    LCD_RS_HIGH macro ;LCD'nin RS girişini HIGH yaparak
    banksel LCD_CtrlPort ;veri alma modu seçilir.
    bsf LCD_CtrlPort, LCD_RS
    endm

    LCD_RS_LOW macro ;LCD'nin RS girişini LOW yaparak
    banksel LCD_CtrlPort ;komut alma modu seçilir.
    bcf LCD_CtrlPort, LCD_RS
    endm

    LCD_ESTROBE macro ;LCD'ye veri ya da komut
    banksel LCD_CtrlPort ;gönderildiğinde LCD'nin
    bsf LCD_CtrlPort, LCD_EN ;bunu işlemesini sağlar.
    movlw .20 ;20us kadar bekle.
    call delay_us
    bcf LCD_CtrlPort, LCD_EN
    endm
    ;Makro Sonu
    ;*******************************************************************


    ;-------------------------------------------------------------------
    ; 1-255 sn arasında gecikme sağlayan alt program.
    ;-------------------------------------------------------------------
    delay_s
    movwf delay_s_data
    delay_s_j0:
    movlw .250 ;4 * 250 = 1000 ms bekle,
    call delay_ms ;her çevrim 1 sn.
    movlw .250
    call delay_ms
    movlw .250
    call delay_ms
    movlw .250
    call delay_ms
    decfsz delay_s_data
    goto delay_s_j0
    return

    ;-------------------------------------------------------------------
    ; 1-255 ms arasında gecikme sağlayan alt program.
    ;-------------------------------------------------------------------
    delay_ms
    movwf delay_data
    delay_ms_j0
    movlw .142
    movwf delay_data+1
    nop
    nop
    delay_ms_j1
    nop
    nop
    nop
    nop
    decfsz delay_data+1, F
    goto delay_ms_j1
    nop
    decfsz delay_data, F
    goto delay_ms_j0
    nop
    return
    ;-------------------------------------------------------------------
    ; 16-255 µs gecikme sağlayan alt program.
    ;-------------------------------------------------------------------
    delay_us
    movwf delay_data
    rrf delay_data, F
    rrf delay_data, F
    movlw .63
    andwf delay_data, F
    movlw .3
    subwf delay_data, F
    nop
    decfsz delay_data, F
    goto $ - 2
    nop
    return


    ;-------------------------------------------------------------------
    ; Kesme programı (kullanılacak ise LCD ya da zamanlamanın önemli
    ; olduğu cihazlarla çalışırken iletişimin kesilmemesine dikkat
    ; ediniz).
    ;-------------------------------------------------------------------
    kesme
    retfie
    ;*******************************************************************


    ;///////////////////////////////////////////////////////////////////
    ;Lcd'yi Hazırlıyoruz.
    ;///////////////////////////////////////////////////////////////////
    LCD_INIT
    ;Lcd Hazır olana kadar bekle.
    MOVLW .200 ;Yaklaşık 200ms bekleniyor.
    call delay_ms
    ;***************************
    ;Resetle
    MOVLW B'00110000'
    MOVWF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder

    MOVLW .20
    CALL delay_ms
    ;*******
    ;Fonksiyonlar ayarlanıyor.
    MOVLW B'00100000'
    MOVWF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder

    MOVLW B'00100000'
    MOVWF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder

    MOVLW B'11000000'
    MOVWF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder
    MOVLW .20
    CALL delay_ms
    ;****************************
    ;Display Açılıyor.
    CLRF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder

    MOVLW B'11100000'
    MOVWF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder
    MOVLW .20
    CALL delay_ms
    ;*****************
    ;EntryMode Ayarlanıyor
    CLRF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder

    MOVLW B'01100000'
    MOVWF PORTB
    LCD_RS_LOW ;Komut alma modu seçiliyor.
    LCD_ESTROBE ;Gönder
    MOVLW .20
    CALL delay_ms
    ;****************************************
    ;Karakter Gönder(M karakteri)
    MOVLW B'01000000'
    MOVWF PORTB
    LCD_RS_HIGH
    LCD_ESTROBE
    MOVLW B'10000000'
    MOVWF PORTB
    LCD_RS_HIGH
    LCD_ESTROBE

    RETURN


    ;-------------------------------------------------------------------
    ; Ana program
    ;-------------------------------------------------------------------
    Ana_program

    ;Hangi port kullanılacağı belirleniyor
    BANKSEL TRISB ;Data uçlarının bulunduğu bacaklar çıkış yapılıyor
    CLRF TRISB
    BCF PORTB,3 ;R/W Toprak seviyesine çekiliyor.
    CLRF PORTB

    MOVLW .2
    CALL delay_s

    CALL LCD_INIT
    DON
    GOTO DON
    ;*************************************
    end
    ;*******************************************************************


    (Yukardaki kod ilk verdiğim kodun sadeleşmiş halidir)



    < Bu mesaj bu kişi tarafından değiştirildi strom -- 19 Ocak 2008; 19:08:30 >
    _____________________________




  • Yapay Zeka’dan İlgili Konular
    Daha Fazla Göster
    
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.