74hc165 ile rb0 kesmesi

Başlatan greatgonzo, 12 Haziran 2012, 00:39:37

greatgonzo

2 tane 74hc165 entegresi seri baglı olarak rb0 data bacağına bağlı şekilde  rb0 kesmesi ile veri almaya çalışıyorum fakat başarılı olamadım. Nette buna ilişkin pek kaynak yok. Bu şekilde olunca şunu düşündüm acaba senkronizasyon ile ilgili bir problem mi oluşuyor. Acaba tecrübe eden oldumu ?

İyi çalışmalar....

ete

#1
Şema olmayınca sorun epeyce bir havada kalmış. Kim nereye bağlı belli değil. Soru RB0 kesmesi ile ilgili ama her şey senin kafanda yada elinin altında ve sanki bizlerde olayı biliyormuşuz gibi bir soru sormuşsun. Ama bilmiyoruz maalesef.

Şimdi tahminde bulunarak ve yalnızca 1 adet 74165 i sisteme bağladığını düşünerek cevap vermeye çalışayım.
Önce 74165 in bir paralelden seriye dönüştürücü olduğunu belirtelim. Data bacaklarından girdiğin 8 bitlik sayıyı SO bacağından clk palsi vererek seri olarak alabilirsin. Şimdi sen data bacaklarına birer buton vs bağladığını düşünelim. Bu duurmda SO bacağınıda RB0 bacağına bağlaman lazımki bir kesme oluşturabilesin. Ancak oluşturacağın kesme  RB0 pininin LOW dan HIGH konumuna geçerken oluşturuluyor olması gerekir.
İşlem sırasıda şöyle;
SH/LO bacağı başlangıçta HIGH da bekleyecek ve ona bir puls vereceksin ve onu yine  HIGH da bekleteceksin.
INH bacağı LOW da bekleyecek. Bu konumda CLK girişine bir puls vereceksin.
Bu aşamadan sonra verdiğin her puls Data girişlerinin sırası ile SO bacağından çıkmasına sebep olacaktır.
Bu durumda bacaklardan birisi HIGH ise otomatikman SO bacağıda LOW konumundan HIGH konumuna geçerek kesmeyi oluşturabilir.
Başka söze de gerek yok sanırım.

Ete

greatgonzo

ETE hocam cevapiçin teşekkürler. Konuyu havada bırakmam için özür dilerim.Bu şekilde sormamın nedeni ,affınıza sığınarak, tek bir sorun ve cevabından ziyade konunun tartışılması. Yeri geldiğinde pek çok arkadaşımıza bu tarz şeylerin faydası dokunacağını düşünüyorum. Zira ben sıklıkla hiç işimin olmadığı konuları bile gazete,dergi gibi takip ediyorum. Neyin ne zaman lazım olacağı belli olmaz:-)

Hocam bununla ilgili olarakta basit bir devre çizdim. Kesme ile bir ledi yakmaya çalıştım. Denemelerim başarısız olunca da shift register hadisesini hiç anlamadığımı düşünmeye başladım. Yada bir şeyleri gözden kaçırıyorum. Kodu ve şemayı ekliyorum.

Birde hocam şunuda arada danışmak isterim. Mesela bir bacağı High da tutarken işlemci @sleep moduna girermi ?

İyi çalışmalar...




@ DEVICE pic16F628 'işlemci 16F628
@ DEVICE pic16F628, WDT_on 'Watch Dog timer açık
@ DEVICE pic16F628, PWRT_ON 'Power on timer açık
@ DEVICE pic16F628, PROTECT_OFF 'Kod Koruma kapalı
@ DEVICE pic16F628, MCLR_OFF 'MCLR pini kullanılmıyor.
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak

PORTA=0:PORTB=0
TrisA=%00000000
TrisB=%00000001

CMCON=7

OPTION_REG=%1100000
INTCON=%10010000
ON INTERRUPT GoTo KESME               

SYMBOL LED=PORTB.7
SYMBOL DTA=PortB.0
SYMBOL CLK=PORTB.1
SYMBOL SH=PORTB.3
VERI var byte

BASLA:
high sh
@sleep
pauseus 10
goto basla

DISABLE
KESME:
LOW SH:PAUSEUS 1:HiGH SH
HIGH CLK:PAUSEUS 1:LOW CLK
SHIFTIN dta,clk,1,[VERI]
PAUSE 1
TOGGLE LED
INTCON.1=0
Resume
Enable
End



ete

#3
Programa bir baktım SLEEP komutu gördüm.
Kesme etiketine baktım clk palslerini orada verdiriyorsun.
Peki işlemci uykuya girince kim CLK palsi verecekte shift register sayacak ve bir tuşa basıldığı bilgisini iletecek?
Tavukmu yumurtadan çıktı yoksa yumurtamı tavuktan çıktı hesabı bu. Clk vermezsen 74165 gişinde olan tuşları hissetmeyecek.
Hisstemeyince Kesme oluşmayacak. Üstelik PortB.0 girişinde bir pulldown direncide yok. Mademki 74165 den bir HIGH bekleniyor (butona basılınca) o halde PortB.0 pini LOW da beklemeli. Peki sen ne yapmışsın yalnızca bağladığın buton pinine Pulldown bağlamışsın. Peki o seçili değil ise PortB.0 ne yapacak havada gezinir durur. Bunun anlamı bir HIGH olur bir lOW.
Devrende ve programında taktiksel hatalar var.
Bu sistem ile sleep kullanamazsın. Kullanırsan sistem uykuya girince artık tuşları göremezsin. Görsen bile oradaki bilgiyi seri data olarak alamazsın. Taktik değiştirmen gerekiyor. En azından arada bir açıp tarama yaptırıp tuşa basılmışmı kontrol ettirmen belkide daha doğru olurdu.

Ete

greatgonzo

Kesinlikle haklısınız ETE hocam.Bende timer kesmesi ile sleep komutundan çıkma ihtimalinide göz önünde bulunduruyordum ,hatta yazılımımda başka amaçlarla kullanmak zorunda da kalacaktım. Kaba bir şekilde yaptığım denemede timer kesmesi ile uyandırmak ve periyodik olarak shift registerı kontol etmek çok dengeli oldu. Hal böyle olunca rb0 kesmesi tamamen gereksizlik haline geldi.

Birde şunu merak rb0 kesmesi ve shift regisler ikilisini hiç bir arada tecrübe ettiniz mi hocam. Çünkü nette hiç uygulamasına rastlamadım. Shift registerların çalışması anlamında eksiklerim olduğunun farkındayım ama şunu fark ettim ki zamanlama son derece hassas ve önemli. Rb0 kesmesini seri çıkış bacağından tetikleyecek ama pic in kesme üretmesi mutlaka ,azda olsa , zaman alır. Hele ki uyku modundaysa biraz daha uzaması gerekir. İşte bu noktada ilk gelen veriyi yakalamak mümkün mü ? Usarttan bahsetsek 1-2 byte tamponlama yaptığını öngörebiliriz ama Portb.0 bacağına bağlı böyle bir tampon varmı.

Programıda uygun bir zamanda ( kısmetse yarın gibi ) açıklamalarıyla beraber eklemek istiyorum. Birden fazla shift registerli hale getirmek niyetindeyim. Belki tecübe ettiğim  durum arkadaşlara yardımcı olur.

İyi çalışmalar.

ete

Doğru yolu bulduğuna sevindim. PortB.0 kesmesini  sıfat değiştir ile değil ama multiplexer (4051 ve 4067) ile çok kullandım.  Senin bahsini ettigin gecikmeler yaşanmıyor. Unutmaki bir komut çevrimi 1us dir . Bu epeyce kısa bir süredir.
Ete

greatgonzo

İki adet 74hc165 ve bir adet 2X16 Lcd ile örnek bir devre kurdum. Umarım arkadaşların işlerine yarar. Bir tek belirtmekte fayda görüyorum LCD ekrana veri yolladıktan sonraki pause komutu hatalı. Normal şartlarda döngü kurulursa Timer sayacının hassasiyeti açısından daha faydalı olur. Bu şeklide yapma zorunluluğumda Timer1 in 1:1 bölme oranından dolayı oluştu. Hesabı tam hatırlayamıyorum ama zannedersem saniyede 13 - 15 defa tarama yapıyor. Bu da LCD deki görüntüyü kırpıştırıyordu. Kullanacak yere göre tarama adedini ayarlanmasında fayda var.

Kısaca  şunuda eklemek isterim ki @sleep vb komutlardan  Tımerlar içerisinde sadece Timer1 kesmesi uyandırır. Pek çok pic te durum benzerdir. Timer0 ile denerseniz  pic hiç uyanamaz.

ETE hocam yardımlarınız için çok teşekkür ederim.

Örnek kodlarıda ekliyorum. Herkese iyi çalışmalar...




@ DEVICE PIC16F88
@ DEVICE PIC16F88, WDT_ON
@ DEVICE PIC16F88, PWRT_ON
@ DEVICE PIC16F88, PROTECT_OFF
@ DEVICE PIC16F88, MCLR_OFF
@ DEVICE PIC16F88, INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F88, LVP_OFF
@ DEVICE PIC16F88, BOD_OFF
@ DEVICE PIC16F88, FCMEN_OFF
@ DEVICE PIC16F88, IESO_OFF
@ DEVICE PIC16F88, CCPMX_ON
@ DEVICE PIC16F88, DEBUG_OFF
@ DEVICE PIC16F88, WRT_OFF
@ DEVICE PIC16F88, CPD_OFF

DEFINE OSC 4
DEFINE LCD_DREG PORTB     
DEFINE LCD_DBIT 0     
DEFINE LCD_EREG PORTB   
DEFINE LCD_EBIT 4     
DEFINE LCD_RSREG PORTB   
DEFINE LCD_RSBIT 5       
DEFINE LCD_BITS 4       
DEFINE LCD_LINES 4         

OPTION_REG.7=1              'PİC16F88 pull-up dirençleri iptal.
OSCCON=%01101100      'PİC16F88 dahili osilatör açık ve 4MHz.

CMCON=7                         'Komparatör pinler iptal,hepsi dijital.
ANSEL=0                           'PİC16F88 analog pinler iptal,hepsi dijital.
ADCON0=0                        'Anolog/dijital çevirici kapalı.

PORTA=0:TRISA=%00000001
PORTB=0:TRISB=0

T1CON=%00001001         'PİC16F88 TIMER sayacı açık/bölme oranı 1/1
INTCON=%11000000       'Tüm kesmeler açık ve donanımsal kesmeler açık.
PIE1.0=1                          'TIMER1 kesmesini aktif edildi.
PIR1.0=0                          'TIMER1 kesme bayrağı sıfırlandı.

SYMBOL SO=PORTA.0       'Shift Register seri çıkış bacağı.
SYMBOL CLK=PORTA.1     'Shift Register clock  bacağı.
SYMBOL SHLD=PORTA.2   'Shift Register yükleme bacağı.
bilgi var word
gor var byte
clear

LCDOUT $FE,1
pause 100

ON INTERRUPT GOTO KESME             'Kesme durumunda KESME adlı etikete sıçra.

BASLA:
LCDOUT $FE,1,BIN bilgi                            'Shift registerdan gelen veriyi binary olarak göster.
LCDOUT $FE,$C0,"TUS : ",dec GOR          'Shift registerdan gelen verinin hangi biti 1 ise göster.

PAUSE 50 '*** ÖNEMLİ: HATALI KOMUT ***

@sleep                                                      'Uyku moduna geç.
GOTO BASLA


DISABLE
KESME:                                                   'Kesme durumunda icra edilecek etiket.
INTCON.7=0                                           'İNTCON'dan tüm kesmeleri engelle,başka kesme oluşmaması için
LOW SHLD:PAUSEUS 10:HiGH SHLD       'Shift register içeriğini yükle.
SHIFTIN SO,clk,0,[BILGI\16]                   'Shift register içerigini seri olarak al.
gor=NCD bilgi                                        'Seri olarak alınan bilginin en soldaki 1 olan bitinin bangi basamakta olduğu tespit et.
PIR1.0=0                                               'TIMER1 kesme bayrağını sıfırla.
INTCON.7=1                                           'INTCON üzerinden tüm kesmeleri aç.
ENABLE
resume
END

Powered by EzPortal