pic kendi kendine tetikleniyor

Başlatan izci, 05 Aralık 2015, 06:35:20

izci

merhaba 16f628den  887 ye geçiş yaptım ama sanırım umduğum kadar kolay bir entegre değil.
sorunum şu; butondan sinyal gelmediği halde pic geliyormuş  gibi davranıyor bazen  butondan bazende pedal sensöründen sinyal alıyormuş gibi  davranıyor, kendini hiç resetlemiyor . ilk önce plaket yollarında kısa devre var diye düşündüm  birşey bulamadım, sonra pic in giriş ayaklarına  bağlı olan pull up direncini kontrol ettim ve gördümki 10k üzerinden geçen 5volt giriş pinini high da tutmuyor gerilim 0 volt, ayakla plaketin  yollarını ayırıp kısa devre olmadığına emin oldum high'ı işlemci low'a çekiyor ve kendini tetiklemiş oluyor   işlemciyi değiştim sonuç aynı.
bu duruma sebep olan  bir ayarmı var acaba???



@ __config  _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_ON & _IESO_OFF & _FCMEN_ON & _LVP_OFF & _DEBUG_OFF
@ __config  _CONFIG2, _BOR21V & _WRT_OFF
OSCCON=%01101100
define osc 4'dahili osc 4mhzde çalışacak
PORTA=0:TRISA=%01000000 'a portu çıkış  a6 pedal girişi
portb=0:TRISB=%10001000  'b portu çıkış b3 kagıt kontrol sensörü
portc=0:TRISC=%00010000  'c  portu çıkış c4 ok buton
portd=0:TRISD=%00001100   'd portu çıkış  d2-3buton
porte=0:TRISE=1   
ANSEL= 0 'A portu analog pinler iptal
ANSELH=0  'B portu Analog pinler iptal
ADCON0=0
ADCON1=0
CM1CON0=0 'C1 Komparatör iptal
CM2CON0=0 'C2 Komparatör iptal
CCP1CON=0  'pwm kapalı
CCP2CON=0
WPUB=0  'PORTB pullup lar kapalı

'*******************değişken atama********************
pedal var portc.0
pedal_sinyal var portb.7
kagit_bitti var portb.3
red var portc.3
green var portc.2
blue var portc.1
motor_ileri var portd.0
motor_geri var portd.1
buton_asagi var portd.3
buton_yukari var portd.2
buton_sag var porte.1
buton_sol var porte.0
buton_menu var portc.4
kagit_sure var word
sayac var word

'***********eeprom tanımlamaları***********
read 10,kagit_sure.lowbyte,kagit_sure.highbyte
IF kagit_sure <=2000 or kagit_sure>=8000THEN
kagit_sure=4000:endif
write 10,kagit_sure.lowbyte,kagit_sure.highbyte
pause 15


read 1,sayac.lowbyte,sayac.highbyte
IF sayac =65307 THEN
sayac=0:endif
write 1,sayac.lowbyte,sayac.highbyte
pause 15

 

'***********LCD Tanımlamaları***********

DEFINE LCD_DREG PORTA 'LCD data bacakları Porta de bağlı
DEFINE LCD_DBIT 0 'LCD data bacakları 4. bitten başlıyor
DEFINE LCD_EREG PORTA 'LCD Enable Bacağı Porta de bağlı
DEFINE LCD_EBIT 4 'LCD Enable Bacağı 3. bite bağlı
DEFINE LCD_RWREG PORTA 'LCD RW Bacağı Portade bağlı
DEFINE LCD_RWBIT 5 'LCD RW Bacağı 2. bite bağlı
DEFINE LCD_RSREG PORTA 'LCD RS Bacağı Porta de bağlı
DEFINE LCD_RSBIT 7 'LCD RS bacağı 1. Bite bağlı
DEFINE LCD_BITS 4 'LCD 4 bit olarak bağlı
DEFINE LCD_LINES 2 'LCD 2 sıra olarak çalışıyor.
LOW PORTB.2 'RW
pause 200

ana1:
high pedal
read 1,sayac.lowbyte,sayac.highbyte
LCDOUT $FE,1,"kesim adedi "
LCDOUT $FE,$C0,#sayac
high blue  'mavi led yak
pause 200
ana:
if kagit_bitti=1 then kagitbitti
if pedal_sinyal =0 then sinyalgeldi
if buton_menu=0  then menu
goto ana

kagitbitti:
low pedal
LCDOUT $FE,1,"kagit bitti "
goto kagitbitti

sinyalgeldi:
high motor_ileri
pause kagit_sure
low motor_ileri
goto ana1
menu:
write 10,kagit_sure.lowbyte,kagit_sure.highbyte
pause 10
LCDOUT $FE,1,"menu "
LCDOUT $FE,$C0,"motor sure= ",#kagit_sure
pause 10
if buton_asagi=0 then
while buton_asagi=0
kagit_sure=kagit_sure-1
pause 50
wend
endif
if buton_yukari=0 then
while buton_yukari=0
kagit_sure=kagit_sure+1
pause 50
wend
endif
pause 100
if buton_menu=0  then ana1
goto menu


ete

Bu işlemci sevdiklerimden birisidir. özellikleri açısından tabiiki. Epeycede kullandım hiç de söylediklerin gibi davranmadı bana karşı. Demekki sorun sende yada programında.
Program koymuşsun buraya ama hatalarla dolu. Bu şekilde çalışması zaten mümkün değil iken bu tür bir kanıya nerden vardığınıda anlamadım.
Şimdi diyeceksinki buraya koyduğum program asıl program değil o zaman neden koyuyorsun buraya?. Biz nereye bakıpda yorum yapacağız. ?
if kagit_bitti=1 then kagitbitti 
if sinyal_geldi=0 then sinyalgeldi

Programda kagitbitti diye bir etiket mevcut değil. Programda Sinyal_geldi diye bir değişken olmadığı gibi sinyalgeldi diye bir etiket de yok.

Bahsini ettiğin sorun genelde giriş olarak ayarlanmamış bir pin low çıkartırken o pine HIGH vermekle sağlanacak sorunlardan.
Artı ile eksi çakışması yani. Baktım programda bir çok giriş pini var. Bunlardan birisini yanlış değerlendirip bir yanındakine giriş yapıyor olabilirsin. Devreni iyice kontrol et ve bundan sonra incelenecek bir şey veriyorsan tam vermeye çalış.

Ete

izci

hocam verdiğim şey aslında tamdı  ama o kadar kurcaladım ki çorba  oldu birde sabahın beşi olunca  böyle oldu kusura bakmayın.
herşeyi yeniden kontrol edip paylaşırım tekrardan

izci

hocam dediğiniz gibi hatanın biri buton üzerinden bir giriş ve cıkışın kısa devre olması imiş onu hallettim,
ikinci hata şöyle a6 girişi kendi kendine tetik almaya devam ediyor ama bazende kendinden normale dönüyör kodda ve devrede hata göremedim  ama çözemedim de sıkıntıyı,  sonra bu girişi port b ye aldım  sıkıntısız çalışmaya başladı.
aklıma şöyle bir teori geliyor porta.6  osc2/clkout ucu olduğundan ve ben bu ucu giriş olarak tanımladığım için böyle bir hata oluşmuş olabilir mi? osc fuse ayarlarını mı yanlış yaptım acaba?

birde osc ayarlarını 8mhz çıkardığım zaman lcd karakter kaçırmaya başlıyor  bazı harfleri  göstermiyor  yada yanlış yerde gösteriyor bunun sebebi 4 bit olarak bağlı olması olabilir mi  yoksa osc fuse ayarlarından mıdır hocam  ?

ete

A6 daki hatanın OSC ayarı ile alakası yok. Sigorta ayarında doğru. Yine devrende bir sorun vardır bence.
Anlamak için PORTA.6 daki pullup direncini sök. Programdan o pini çıkış yap ve herhangi bir değer vermeden ölçü aleti ile kontrol et bakalım ne gösteriyor. LOW mı yoksa HIGH mı. HIGH ise mutlaka bir yerlerden kısa devre ile HIGH alıyordur.
Yada tam tersi GND ye kısa devredir ve butona basılmış gibi hareket ediyordur.
Kısaca yaşadığın sorunlar tamamen devrenle alakalı.
Karekter kaçırma olayıda yazılımla alakalı. Bir satırda 16 karekter vardır o satıra 17 karekter yazarsan fazla olan bir sonraki satırda belirir. Böyle bir sorun vardır mutlaka.
Daha yüksek hızlarda LCD ye verilen komutların işlenebilmesi için yeterli süre kalmayabilir. Buda ekranın karışmasına sebep olur.
Şayet böyle bir sorun var ise aşağıdaki komutları LCD tanımlamalarının altına ilave et.
DEFINE LCD_COMMANDUS 2000 'Command delay time in us
DEFINE LCD_DATAUS 50 'Data delay time in us

Ete

izci

hocam a6 pinini  dediğiniz gibi çıkış yaptım sürekli gnd veriyordu high a çektiğim halde değişmedi işlemciyi değiştirince düzeldi, sanırım kurcalarken yakmışım. lcd  verdiğiniz kodları eklediğim halde 8 mhz de karakter kaçırmaya devam ediyor ama 4mhz de sorunsuz çalışıyor, arızalı olabilir müsait olduğumda onu da değiştireceğim.
Birde pic in besleme bacaklarına bağladığımız bağladığımız 100nf filtre kondansatörlerini smd kullanırsam sıkıntı çıkarmı?

ete

Smd kondansatör sorun çıkarmaz.

Ete

F®T

SMD daha iyi olur.direk ayaklarının arasına atarsın.
"Hakk" şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

izci

yardımlarımız için teşekkür ediyorum özellikte sayın ete hocamızın hakkını nasıl öderiz bilmiyorum.

izci

hocam size bir iki sorum daha olacak,
yukarda yazdığım kodda "sinyalgeldi"  etiketi altında motor çalıştırıyorum  motor ilk kalkma anında bazen zorlanabiliyor ve işlemciye reset attırabiliyor bunun için soft start yapmam lazım bunu pwm ile şu şekilde yapabilirmiyim;
soft var byte 
for soft = 1 to 255
  pwm motor_ileri,soft,1
      pause 1
      next


ikinci sorum ise  motorun yaydığı zıt emk  eeproma yazılan verinin  sapıtmasına neden olabiliyor , bunu önlemek için eeproma  yazma olayını sadece veri yazmak istediğim kısımda aktif edip sonrasında eepromu yazmaya kapatmak istiyorum.
Datasheetten anladığım kadarı ile EECON1 yazmacına  8bitlik veri atamam gerekiyor ve bit 2 "WREN:EEPROM Write Enable bit" olarak
gösteriliyor  fakat bunu  programın sadece başında atayabilirim gibi geldi  bana,  bunun yerine veri yazacağım zaman
@  BSF   EECON1,WR  asm kodunu eklesem  veriyi yazdıktan sonra @  BCF   EECON1,WREN  olarak yazsam  işimi görürmü?
doğru mantık bu mu dur?

ete

#10
Soft start o şekilde olur.
Eprom write enable biti senin bildiğin anlamda bir enable biti değil. O bit eproma yazılacak zamanı belirler. Eproma yazma emri verdiğin zaman o bit otomatikman 1 olur ve yazma işlemi bitinceye kadar o bit 1 olarak kalır. Yazzma bitince bit sıfırlanır ve kullanıcı yada Basic ancak o bit sıfır ise yeniden eproma bilgi yazabilir. Senin düşündüğün anlamda eproma yazmayı engellemez.  O biti harici olarak high yaparsan o andaki parametreye göre eproma bilgi yazarsın. Bence bu işle uğraşma.
Eproma bilgi yazarsan yazar yazmak istemezsen yazmazsın. Bunun haricinde durup dururken eproma kimse bilgi yazmaz. İstem dışı yazmalar söz konusu ise zaten bu düşündüğün tedbirde işe yaramaz bana kalırsa. Sen zıt EMK ya bir çözüm bulmaya çalış bence. Ters diyot ve 100nf kondansatör iyi sonuçlar vermektedir.

Ete

Bahri Bilir

#11
Konu başlığıyla ilgili müsadenizle benimde bir kaç sorum olacak.
Pullup ve pulldown dirençlerinin direncin watt gücü ile bağlantısı nedir.

Özellikle buna SMD (watt gücünü bilmiyorum) 1 K ile  pulldown ladığım pine elimle dokandığında lojik 1 oluduğunu görünce ihtimal verdim.
Bu normal direnç kullandığım zamanlarda kolay kolay karşılaşmadığım bir problemdi.

Bir pic pinine 12V ve 5V girebilmek için pulldown direnci ve pin hat arası direnci nasıl olmalı? (Üzerine sıktığım sıçak silikondan etkilenip pin lojik 1 oluyor :) )
"Hedeflerin bittiği tek yer, YENİ hedeflerin başlangıcıdır"

Maxim

bilirshop

şu an elimle probu tutuyorum, voltaja dikkat!

izci

Erol hocam 2 sorum daha olacak size
1- devrenin eektriğini kesip açtığım zaman lcd  normal calışken işlemciyi resetlediğimde lcd  çalışmıyor,
bazen resete üstüste 5-6 defa basınca çalışabiliyor  lcd çalışmasada işlemci  çalışıyor


2- motor_süre adlı değişkeni  eeproma 1630 olarak yazdırıyorum sonra bakıyorum ki 1791 olmuş kendi kendine,
ilk olarak motordan parazit aldığı için yapatığını düşündüm ama motor hiç bağlanmadan bile bu hatayı verdi
butonlardan tetik alıyor diye düşündüm ama butonlar her basıldığında 2 ve katları olarak artırıp azaltıyor
tek haneli bir sayı değeri alması imkansız bu hatayı ne zaman yapacağı  belli olmadığı için daha net tespitte bulunamadım.
video ve kodları ekliyorum hocam nerelerde hatam var bakarsanız sevinirim.
video: https://youtu.be/RjwqIdUGlVc



@ __config  _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _CP_ON & _CPD_ON & _BOR_OFF  & _IESO_OFF & _FCMEN_ON & _LVP_OFF & _DEBUG_OFF
@ __config  _CONFIG2, _BOR21V & _WRT_OFF

OSCCON=%01101100
define osc 4'dahili osc 4mhzde çalışacak
PORTA=0:TRISA=%00000000   
portb=0:TRISB=%00000010
portc=0:TRISC=%11111111 
portd=0:TRISD=%11111111   
porte=0:TRISE=1   
ANSEL= %00000000 'A portu analog pinler iptal
ANSELH=%00000000  'B portu Analog pinler iptal
ADCON0=0
ADCON1=0
CM1CON0=0 'C1 Komparatör iptal
CM2CON0=0 'C2 Komparatör iptal
CCP1CON=0  'pwm kapalı
CCP2CON=0
WPUB=0  'PORTB pullup lar kapalı
'*******************değişken atama********************
pedal_kapat var portb.2
pedal_basili var portb.1
kumas_bitti var portd.4
red var portb.5
green var portb.4
blue var portb.3
motor_ileri var portb.7
motor_geri var portb.6
buton_asagi var portd.0
buton_yukari var portc.0
buton_sag var portd.1
buton_sol var portc.3
buton_menu var portc.2
motor_sure var word
sayac var word
soft var byte

'***********eeprom tanımlamaları***********         
read 10,motor_sure.lowbyte,motor_sure.highbyte
IF motor_sure <=1000 or motor_sure>=5000THEN
motor_sure=1630
write 10,motor_sure.lowbyte,motor_sure.highbyte
pause 25
endif
'***********LCD Tanımlamaları***********

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 4
DEFINE LCD_RWREG PORTA
DEFINE LCD_RWBIT 5
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 0
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
pause 200
LCDOUT $FE,1 :pause 50
LCDOUT $FE,$0C

pause 50
'***********program başlangıcı***********
ana1:
low red
low green
high blue  'mavi led yak
high pedal_kapat  'pedalı kullanıma aç
read 10,motor_sure.lowbyte,motor_sure.highbyte
read 1,sayac.lowbyte,sayac.highbyte
LCDOUT $FE,1,"kesim hazir "
LCDOUT $FE,$C0,"sayac= ", #sayac
pause 200
ana:
if kumas_bitti=1 then kumas_tak
if pedal_basili=0 then pedal_basildi
if buton_menu=0  then
while buton_menu=0
wend
pause 50
goto  menu
endif
goto ana
'****************************************************************************************************
'****************************************************************************************************
pedal_basildi:
    pause 100
low pedal_kapat
sayac=sayac+1
write 1,sayac.lowbyte,sayac.highbyte
pause 30
low blue
low red
high green
LCDOUT $FE,1,"pedala basildi "
LCDOUT $FE,$C0,"kesime hazir"
for soft = 220 to 255
  pwm motor_ileri,soft,1
pauseus 1
next
high motor_ileri
pause motor_sure
low motor_ileri
low green
goto ana1
'****************************************************************************************************
'****************************************************************************************************
kumas_tak:
low pedal_kapat
low blue
low green
high red
LCDOUT $FE,1,"kumas bitti "
LCDOUT $FE,$C0,"kumasi yenileyin"
pause 500
if buton_yukari=0 then
while buton_yukari=0
high motor_geri
pause 5
low motor_geri
pause 5
wend
endif

if buton_asagi=0 then
while buton_asagi=0
high motor_ileri
pause 5
low motor_ileri
pause 5
wend
low motor_ileri
endif

if buton_menu=0 then
LCDOUT $FE,1,"geri sayim "
LCDOUT $FE,$C0,"5"
pause 1000
LCDOUT $FE,$C0,"4"
pause 1000
LCDOUT $FE,$C0,"3"
pause 1000
LCDOUT $FE,$C0,"2"
pause 1000
LCDOUT $FE,$C0,"1"
for soft =0 to 100
high motor_ileri
pause 5
low motor_ileri
pause 5
next
endif
goto kumas_tak:
'*****************************************menü*************************************************************************
menu:
low pedal_kapat
high red
high green
high blue
pause 10
LCDOUT $FE,1,"menu "
LCDOUT $FE,$C0,"motor sure= ",#motor_sure
pause 10
if buton_asagi=0 then
while buton_asagi=0
motor_sure=motor_sure-2
pause 70
wend
endif
if buton_yukari=0 then
while buton_yukari=0 :motor_sure=motor_sure+2 :pause 70:wend 
endif:pause 100
if buton_menu=0  then
while buton_menu=0
pause 50
wend
write 10,motor_sure.lowbyte,motor_sure.highbyte
pause 20
goto  ana1
endif
goto menu

end





ete

İçine program yüklenmiş bir işlemciye gerilim verdiğinde neler olur biraz düşünelim.

Öncelikle programda yer alan kendi registerlerine verilen değerler ilgili yerlere yerleştirilirler.
Daha sonra tanımladığın değişkenleri derleyicinin otomatik olarak verdiği adreslere yerleştirilip varsa ilk yani default değerleri üzerlerine yazılır.
Daha sonra LCD tanımlamaları uygulanıp LCD ye ait registerlerin yenilenmesi için ona gereken bilgiler yollanır.
Unutma bir LCD nin initalize dediğimiz ilk yenilenme işlmei enazından 150-200 ms kadar bir vakit alır. Bu vakitten önce LCD ye bir şeylar yazmaya kalkarsan LCD sapıtır.
Sonuçta bütün her şeyin yerli yerine oturabilmesi için açılışta işlemciye ve LCD ye en azından bir 300 ms lik süre tanımak gerekiyor. Şimdi programına bakalım bu açıklamaya uymayan neler var.

İşlemciye yeterli açılma zamanını vermeden hemen eprom okumaya başlamışsın ki bu bir kusur. O bahsini ettiğim 300 ms lik gecikmeden sonra eprom okuman gerekiyor. Zira o ana kadar henüz epromdan okunacak değişkenlerin yerli yerine oturmadı bile. LCD yi açılışa sokan (initalize) komut LCDOUT $FE,1 komutudur. Bu komutu da 300 ms lik gecikmeden önce verip sonra 300 ms beklemek ardından ne yapacaksan yapman gerekir.
Sen ise boşuna 200 ms lik bir gecikme verip sonra LCD yi açmışsın. Önden verilen o 200 ms lik gecikmenin LCD ye hiç bir faydası yok çünki henüz LCD açılış komutunu vermemişsin.
Sonuç olarak bu dediklerimi ANA1 etiketine gelinceye kadar yapıp sistemi hazır hale getirmen sonra epromdan okunacakları okuman ve ardından ANA1 etiketine atlaman gerekiyor. İşlemciye arada birde olsa Reset atıyorsan gecikme süresini biraz daha uzun tutarsan senin için daha iyi olur.

Eproma yazma yada okumada bir sorun görmedim. Sıralama doğru. Doğru derken 16 bitlik bir sayı solda haigh byte kısmı sağda low byte kısmı olacak şekilde hex formatında karşımıza çıkar. Bu tabii görüntüye uygun olarak eproma yazarken ve okurken önce HIGHBYTE (Byte1) ve sonra LOWBYTE (Byte0) verilip alınırsa daha doğru olur.

Değişken tanımlamada pin tipi tanımlamaları SYMBOL kullanarak yapman daha doğru olur.
"blue var portb.3"    yerine    SYMBOL blue=portb.3  şeklinde kullanmalısın. Böylece gerçek değişkenlerinle aralarında fark olur. Üstelik port pinlerinine isim verirken pinleri yukarıdan aşağıya sırası ile kullanmakda akıllıca olurdu. Böylece yanlış pin tanımlama ihtimalini elemiş olur anında hata varsa kolaylıkla görebilirsin.

Eproma yazma süresi 10ms dir. Fazlası bir işine yaramadığı gibi lüzumsuz gecikmeler program akışını engeller.
İşlerini çok fazla pause kullanmadan halletmeye çalışman daha doğru olur.

Programa bakınca özellikle PORTB de bazı pinlerin giriş pini olması gerektiğini düşünüyorum.
Mesela;
pedal_basili var portb.1 şeklinde tanımladığın bu pin bir giriş pini olmalı. Çünki ANA etiketi altında bu pini test ediyorsun.
if pedal_basili=0 then pedal_basildi şeklinde bir test o pinin giriş pini olması gerektiğini söylüyor bana. Ama TRISB ye bakıyorum TRISB=%00000000 şeklinde bütün PORTB yi çıkış olarak tanımlamışsın. Bu doğrumu sence.
Bana kalırsa giriş çıkış pinlerini, kontrol et yeniden ve giriş olanlara TRDIS registerinde 0 yerine 1 ver.

Madem programda motora PWM sinyali veriyorsun neden şahane bir HPWM çıkışı var iken sen çokda güzel çalışmayan PWM komutunu kullanıyorsun. Kullandığın işlemcide 2 adet HPWM çıkışı vardır. Bunlar pin açıklamalarında CCP1 ve CCP2 olarak adlandırılmıştır. Bunlardan birisini kullanarak orada sürekli bir PWM sinyalini elde edebilirsin.
Ders notlarımda HPWM konusunu okumanı tavisiye ederim.
Tespitlerim bu kadar. Daha ileri tespitler için programı çalıştırıp kusurları anında görerek işlem yapmak gerekir.

Kolay Gelsin
ETE

Powered by EzPortal