12f629 sleep modu Yardım

Başlatan mustikangal, 03 Temmuz 2019, 19:03:03

mustikangal

Merhaba, pic 12f629 ve tilt(eğim) sensörü kullanarak rgb led kontrol eden bir devre kurdum. Tilt sensörü pull up ile gpi0.2 ye bağlı.Tilt sensörün her tetiklemesinde (içinde metal bilye var,eğimde anahtar açılıyor,dik durunca kapanıyor) rgb farklı bir animasyon yapıyor. 3 animasyon var, 4. tetiklemede uyku moduna geçsin istiyorum. Ancak uyku modundan uyandıramıyorum. datasheet e baktım gpio.2 external input yazıyor ama nasıl kullanacağım bilemedim. Forumda ve internette örnekler var ancak 16f serisi ve C dili için daha çok. 12f629 için internette birşey bulamadım. Kodu ağaşıdaki gibi yazdım. sleep modunu kaldırınca kod çalışıyor ama ledler yanmasa da pic akım çekecektir pilden diye düşünüyorum.Yardımınız lazım.
   @ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _MCLRE_OFF & _CP_OFF
 DEFINE OSC 4
DEFINE OSCCAL_1K 1
CMCON = 7
GPIO=0
TRISIO=%00000100
k var byte  'tilt sensör tetiklendikçe rgb animasyonu değişecek
i var byte   'pwm için değişken
a var byte   'tilt tetiklendiğinde süre saymak için değişken
k=0
symbol tilt= GPIO.2 'tilt sensör 
symbol red= GPIO.1      'RGB kırmızı bacak
symbol green= GPIO.4     'RGB yeşil bacak
symbol blue= GPIO.5       'RGB mavi bacak
low red               'başlangıçta hepsi kapalı
low green
low blue

tiltkontrol:
if tilt=1 then
pause 800
if tilt <> 1 then goto tiltkontrol  '800ms süre verildi. ani tetiklenmeleri ve titreşimleri saymaması için
k=k+1    'k değişkeni 1 arttı
while gpio.0=1 :wend   'tilt sensör tetikteyken saymayacak
endif

sihir:
select case k     ' k değerine göre animasyonlar

case 1
goto ani1

case 2
goto ani2

case 3
goto ani3

case 4             'k=4 olunca ledleri söndür ve uyu diyeceğim
low red
low green
low blue
k=0
sleep 65535 '65535 18 saatlik uyku moduymuş yaklaşık
end select

goto tiltkontrol     'başa dön
ani1:
a=0
for i=50 to 255 step 1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol   'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm blue,i ,1

next
for i=255 to 50 step -1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol   'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm blue,i ,1

next

if tilt <>1 then         'eğer tetiklenme yoksa animasyona devam
goto ani1
else
goto tiltkontrol
endif

ani2:
a=0
for i=50 to 255 step 1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol     'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm green,i ,1

next
for i=255 to 50 step -1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol      'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm green,i ,1

next

if tilt <>1 then         'eğer tetiklenme yoksa animasyona devam
goto ani2
else
goto tiltkontrol
endif

ani3:
a=0
for i=50 to 255 step 1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol     'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm green,i/3 ,1
pwm blue,i ,1

next
for i=255 to 50 step -1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol      'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm green,i/3 ,1
pwm blue,i ,1

next

if tilt <>1 then     'eğer tetiklenme yoksa animasyona devam
goto ani3
else
goto tiltkontrol
endif

end

kodu şöyle yapınca çalışıyor. 3. animasyondan sonra duruyor. ama gerçekten sleep komutunda mı, algoritma doğru mu bilemedim

  @ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _MCLRE_OFF & _CP_OFF
DEFINE OSC 4
DEFINE OSCCAL_1K 1
CMCON = 7
GPIO=0
TRISIO=%0000001
k var byte  'tilt sensör tetiklendikçe rgb animasyonu değişecek
i var byte  'pwm için değişken
a var byte  'tilt tetiklendiğinde süre saymak için değişken
k=0
symbol tilt= GPIO.0 'tilt sensör 
symbol red= GPIO.2      'RGB kırmızı bacak
symbol green= GPIO.4    'RGB yeşil bacak
symbol blue= GPIO.5      'RGB mavi bacak
low red              'başlangıçta hepsi kapalı
low green
low blue
ilk var byte
ilk=0        'ilk açılış ve uyku sonrası modunu belirlemek için değişken. 1 olunca program çalışıyor demek
tiltkontrol:
if tilt=1 then
pause 800
if tilt <> 1 then goto tiltkontrol  '800ms süre verildi. ani tetiklenmeleri saymaması için
ilk=1
k=k+1    'k değişkeni 1 arttı
while tilt=1 :wend  'tilt sensör tetikteyken saymayacak  
endif                                                    
if k=0 and ilk=0 then      'hafif titreşimlerden etkilenmesin diye bunu ekledim. k ve ilk açılış 0 ise uykuya devam
@ SLEEP
endif

sihir:
select case k    ' k değerine göre animasyonlar

case 1
goto ani1

case 2
goto ani2

case 3
goto ani3

case 4            'k=4 olunca ledleri söndür ve uyu diyeceğim
low red
low green
low blue
k=0      'animasyon değişkenini sıfırladı
ilk=0    'ilk açılış ve uyku için ilk değişkenini ayarladı
end select

goto tiltkontrol    'başa dön
ani1:
a=0
for i=50 to 255 step 1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol  'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm blue,i ,1

next
for i=255 to 50 step -1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol  'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm blue,i ,1

next

if tilt <>1 then        'eğer tetiklenme yoksa animasyona devam
goto ani1
else
goto tiltkontrol
endif

ani2:
a=0
for i=50 to 255 step 1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol    'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm green,i ,1

next
for i=255 to 50 step -1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol      'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm red,i/3 ,1
pwm green,i ,1

next

if tilt <>1 then        'eğer tetiklenme yoksa animasyona devam
goto ani2
else
goto tiltkontrol
endif

ani3:
a=0
for i=50 to 255 step 1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol    'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm green,i/3 ,1
pwm blue,i ,1

next
for i=255 to 50 step -1
if tilt=1 then a=a+1
if a>60 then goto tiltkontrol      'animasyon sürerken tilt tetiklenirse animasyondan çıkıp başa gitsin
pwm green,i/3 ,1
pwm blue,i ,1

next

if tilt <>1 then    'eğer tetiklenme yoksa animasyona devam
goto ani3
else
goto tiltkontrol
endif

end

ete

ASM modu sleep konumundan ancak ve ancak harici bir kesme oluştuğu zaman çıkabilirsin.
Bununda yolu hehangi bir harici kesme yaratacak pinden giriş yapmaktan geçer.
Programına baktım,
Her şeyden önce harici girişin (Tilt) GPIO.2 ye değil GPIO.0'a bağlı gözüküyor. TRISIO ya bakarsan daha kolay anlarsın üstelik bu komut için 7 bit bilgi vermişsin (TRISIO=%0000001) 8 bit olmalı.Aksi halde yanlış değerlendirmeler meydana gelebilir.
Öncelikle girişin hangi pin olacağına kesin karar ver. Şayet GPIO.0 dan giriş yapacak isen sleep modundan ancak Pin giriş değişikliği kesmesi ile uykudan çıkabilirsin.
Bunun için yapman gereken IOC.0=1 vermen yeterli olacaktır.
Ama istersen INTCON registerinde de Port değişiklik kesme bitini aktive edip kesme bayrağınıda sıfırlayıp(INTCON.0)  sleep moduna girmen gerekir. Port değişiklik kesmesi ilgili pindeki bir değişikliği (LOW dan HIGH konumuna yada HIGH dan LOW konumuna geçme gibi) algılayıp programı kesme etiketine yönlendirir. Ama INTCON registerini aktive etmez isen bir kesme etiketin olmayacaktır. Böylece oluşan kesme sadece programı sleep modundan çıkartır.
Yapılacak işi bir kez daha tekrarlayayım.
Programın başlarından IOC.0=1 vermen gerekiyor.
Sleep konumuna geçmeden önce,
INTCON.0=0 komutunu vererek önceden oluşmuş bir kesemeye ait bayrağı sıfırlaman gerekiyor.
Ardından Port okunup konum bilgisi alınacaktır bunuda TEMP=GPIO veya (bit bazında Temp.0=GPIO.0) şeklinde yapabilirsin. Bu aşamadan sonra sistemi uykuya sokarsın.
GPIO.0 pininde bir değişiklik olduğu zaman sistem otomatikman kesmeden çıkacak ve program sleep komutundan sonraki satırdan çalışmasına devam edecektir. Bu satırda tekrardan INTCON.0=0 komutunu vererek bayarğı sıfırlaman uygun olacaktır.
Gerisi normal program çalışma mantığı ile devam edecektir.


ete


mustikangal

#2
Teşekkür ederim ete hocam. Yazdıklarınızı okuyunca kavradım biraz olayı. Dediklerinizi yaptım ancak TEMP.0=GPIO.0 kodu hata veriyor derleme yaparken. onu sildiğimde derleme yapıyor. Bu kodun manasını kavrayamadım. Derslerinizden anladığım kadarıyla TEMP bir değişken. Program başına temp vAR BYTE yazınca derleme yaptı. Umarım doğru yapmışımdır.
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _BODEN_OFF & _MCLRE_OFF & _CP_OFF
DEFINE OSC 4
DEFINE OSCCAL_1K 1
CMCON = 7
GPIO=0
IOC.0=1    'UYKU İÇİN
temp var byte
TRISIO=%00000001
k var byte  'tilt sensör tetiklendikçe rgb animasyonu değişecek
i var byte   'pwm için değişken
a var byte   'tilt tetiklendiğinde süre saymak için değişken
k=0
symbol tilt= GPIO.0 'tilt sensör 
symbol red= GPIO.2      'RGB kırmızı bacak
symbol green= GPIO.4     'RGB yeşil bacak
symbol blue= GPIO.5       'RGB mavi bacak
high red               'başlangıçta hepsi kapalı
high green
high blue
ilk var byte
ilk=0        'ilk açılış ve uyku sonrası modunu belirlemek için değişken. 1 olunca program çalışıyor demek
tiltkontrol:
if tilt=1 then
pause 700
ilk=1
k=k+1    'k değişkeni 1 arttı
while tilt=1 :wend   'tilt sensör tetikteyken saymayacak  
endif                                                     
if k=0 and ilk=0 then      'hafif titreşimlerden etkilenmesin diye bunu ekledim. k ve ilk açılış 0 ise uykuya devam
INTCON.0=0
temp.0 = gpio.0
@ SLEEP
INTCON.0=0

endif


Powered by EzPortal