DonanımHaber Mini sürüm 2 Ocak 2026 tarihi itibariyle kullanımdan kalkacaktır. Bunun yerine daha hızlı bir deneyim için DH Android veya DH iOS uygulamalarını kullanabilirsiniz.
Arama butonu
Bu konudaki kullanıcılar: 1 misafir, 1 mobil kullanıcı
6
Cevap
705
Tıklama
0
Öne Çıkarma
LCD'yi 4bit modda çalıştırma(ASM)
S
18 yıl (1792 mesaj)
Binbaşı
Konu Sahibi

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 >

S
18 yıl (1792 mesaj)
Binbaşı
Konu Sahibi

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.


Bu mesaja 1 cevap geldi.
A
18 yıl (4116 mesaj)
Yarbay

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.


Bu mesaja 1 cevap geldi.
S
18 yıl (1792 mesaj)
Binbaşı
Konu Sahibi

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.


Bu mesaja 1 cevap geldi.
A
18 yıl (4116 mesaj)
Yarbay

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.



S
18 yıl (1792 mesaj)
Binbaşı
Konu Sahibi

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.)


Bu mesaja 1 cevap geldi.
S
18 yıl (1792 mesaj)
Binbaşı
Konu Sahibi

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 >

DH Mobil uygulaması ile devam edin. Mobil tarayıcınız ile mümkün olanların yanı sıra, birçok yeni ve faydalı özelliğe erişin. Gizle ve güncelleme çıkana kadar tekrar gösterme.