Yapmış olduğum sayaçta elektrik kesintilerine karşı en son saat ve dakika bilgilerini kayıt etmek istiyorum. Elektrik kesintisini anlamak için resimdeki devreyi kullanıyorum.MCU pin B0 (int_Ext) a bağlı. ilk açılışta takılıp kalıyor. eeprom yazma işi gerçekleşmiyor.(yani sanırım)
Böyle bir durumla karşılaşan oldu mu ? Kod ektedir. Ayrıca sayaçla ilgili bir konu daha açmıştım.
https://www.picproje.org/index.php/topic,58856.0.html (https://www.picproje.org/index.php/topic,58856.0.html)
(http://s15.postimg.cc/71cvic8t7/mcu_001.png)
#include <16F628a.h> // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
//#device high_ints=true
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#priority ext, timer0
#define display_1 pin_A3
#define display_2 pin_A2
#define display_3 pin_A1
#define display_4 pin_A0
#define buton pin_A4
//int kesme =0;
int onlar = 0, yuzler = 0, binler = 0, birler=0, sayac=0;
//int onlar, yuzler, binler, birler, sayac;
const int digit[10] = {0x7F, 0x0C, 0xB6, 0x9F, 0xCC, 0xDA, 0xFA, 0x0F, 0xFF, 0xDF};
int i=0; // Tamsayı tipinde değişken tanımlanıyor
void eeprom_yaz()
{
write_eeprom(0,birler);
delay_ms(8);
write_eeprom(1,onlar);
delay_ms(8);
write_eeprom(2,yuzler);
delay_ms(8);
write_eeprom(3,binler);
delay_ms(8);
}
//****************** INT Kesmesi *****************************
#int_ext
void ext_isr()
{
#use delay(clock=4000000)
eeprom_yaz();
}
//****************** Timer0 Kesmesi *****************************
#int_timer0 // Timer0 kesmesi
void timer0_kesme () // Kesme fonksiyonu ismi
{
set_timer0(60); // TMR0 değeri belirleniyor
i++; // i değeri 1 arttırılıyor
if (i==10) //
output_high(pin_a6);
if (i==20) // i değeri 20'ye eşitse çıkışı lojik-1 olsun ve i değeri sıfırlansın
{
output_low(pin_a6);
sayac++;
i=0;
}
}
void basla()
{
/*
if(kesme==1)
{
eeprom_yaz();
kesme=0;
}
*/
if(input(buton))
{
delay_ms(10);
while(input(buton))
{
onlar = 0;
yuzler = 0;
binler = 0;
birler=0;
i=0;
sayac=0;
}}
if(sayac==61)
{
sayac=0;
birler++;
if(birler==10)
{
onlar++;
birler=0;
if(onlar==6)
{
yuzler++;
onlar=0;
if(yuzler==10)
{
binler++;
yuzler=0;
}
}
}
}
output_low(display_4);
output_low(display_3);
output_low(display_2);
output_high(display_1);
output_b(digit[birler]);
delay_ms(1);
output_low(display_4);
output_low(display_3);
output_low(display_1);
output_high(display_2);
output_b(digit[onlar]);
delay_ms(1);
output_low(display_4);
output_low(display_2);
output_low(display_1);
output_high(display_3);
output_b(digit[yuzler]);
delay_ms(1);
output_low(display_3);
output_low(display_2);
output_low(display_1);
output_high(display_4);
output_b(digit[binler]);
delay_ms(1);
}
/********* ANA PROGRAM FONKSİYONU********/
void main ( )
{
setup_timer_0(RTCC_INTERNAL |RTCC_8_BIT | RTCC_DIV_256); // Timer0 ayarları yapılıyor
set_timer0(60); // TMR0 değeri belirleniyor
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
ext_int_edge(H_TO_L);
set_tris_a(0b00100000);
set_tris_b(0b00000001);
output_a(0x00);
output_b(0x00); // B portu çıkışı ilk anda sıfırlanıyor
birler=read_eeprom(0);
delay_ms(8);
onlar=read_eeprom(1);
delay_ms(8);
yuzler=read_eeprom(2);
delay_ms(8);
binler=read_eeprom(3);
delay_ms(8);
enable_interrupts(INT_EXT);
enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
while(true) // Sonsuz döngü
{
basla();
}
}
Eeprom'un bir yazma süresi var. Dolayısı ile büyük ihtimal
pic besleme yedekleme süresi, eeprom yazma süresinden az kalıyordur.
Girişteki kondansatörü 1000 uF olarak bağlayarak dene derim.
ilk açılışta takılıp kalıyor. eeprom yazma işi gerçekleşmiyor.
Konu baslığı okuma hatası.
Sorun yazmadamı ?
Yoksa enerji verildiğinde beklediğin değerlerimi okumuyor.
Yoksa sistem hiç açılmıyormu ?
bence ilk önce rcon bitlerini kontrol edin, takılıp kalıyor dediğiniz acaba nedir, reset mi atıyor kendine?
Selam,
Eeprom'u neden kesme içinde çağırıyosunuzki?
Epprom yazma fonksiyonu çağırdığınızda o fonksiyon içinde GİE(Global İnterrupt Enable) kapatılır.
Bu false interrupt'a sebep olur.Pgm bloke olur kalır.
main bloğunda eeprom'u okuyun yazın,interrupt'a gerek yok.
İllaki Ext int kesmesini kontrol ediyorsanız bu kesmenin Flag'ini pgm'ın her noktasında kontrol edip
karar verebilirsiniz.
Mesela;
if(INTCONbits.INTF) {
INTCONbits.INTF = 0;
WriteEeprom(adr, data);
Val = ReadEeeprom(adr);
}
Elektrik gittiğinde durumu nasıl devam ettiriyorsunuz?
Pilmi var?
Bu şekilde bir deneyim derim.
Alıntı yapılan: Salih - 26 Nisan 2015, 10:44:47
Eeprom'un bir yazma süresi var. Dolayısı ile büyük ihtimal
pic besleme yedekleme süresi, eeprom yazma süresinden az kalıyordur.
Girişteki kondansatörü 1000 uF olarak bağlayarak dene derim.
Eeprom yazma 8ms diyor. 100uf olan kondansatörü 1000uf olarak değiştirmiştim. Ben ilk baştaki okuma kısmında takıldığını düşünüyorum.
Alıntı yapılan: sadogan - 26 Nisan 2015, 10:56:17
ilk açılışta takılıp kalıyor. eeprom yazma işi gerçekleşmiyor.
Konu baslığı okuma hatası.
Sorun yazmadamı ?
Yoksa enerji verildiğinde beklediğin değerlerimi okumuyor.
Yoksa sistem hiç açılmıyormu ?
Konu başlığı doğru ben ifade ederken yazma olarak lanse etmişim. Kodu incelerseniz ilk açılışta okuma kısmı var. Sonsuz döngü öncesinde. O kısmı kaldırınca program çalışıyor gibi. Fakat o zaman da tüm değerler 0 dan başlıyor. Bahsettiğim kodu geri eklediğimde enerji geldiğinde beklenen değerleri okumuyor.
Alıntı yapılan: esensoy - 26 Nisan 2015, 13:45:46
bence ilk önce rcon bitlerini kontrol edin, takılıp kalıyor dediğiniz acaba nedir, reset mi atıyor kendine?
Rcon bitlerini kontrol etmeyi bilmiyorum. Öğretebilirseniz memnun olurum. Aslında 7 segment displayler çalışmadığı için sistem tam nerede anlayamıyorum, reset konusunda da bilgim yok haliyle.
Alıntı yapılan: JOKERAS - 26 Nisan 2015, 14:19:14
Selam,
Eeprom'u neden kesme içinde çağırıyosunuzki?
Epprom yazma fonksiyonu çağırdığınızda o fonksiyon içinde GİE(Global İnterrupt Enable) kapatılır.
Bu false interrupt'a sebep olur.Pgm bloke olur kalır.
main bloğunda eeprom'u okuyun yazın,interrupt'a gerek yok.
İllaki Ext int kesmesini kontrol ediyorsanız bu kesmenin Flag'ini pgm'ın her noktasında kontrol edip
karar verebilirsiniz.
Mesela;
if(INTCONbits.INTF) {
INTCONbits.INTF = 0;
WriteEeprom(adr, data);
Val = ReadEeeprom(adr);
}
Elektrik gittiğinde durumu nasıl devam ettiriyorsunuz?
Pilmi var?
Bu şekilde bir deneyim derim.
Eeprom yazma sınırı olduğu için sadece elektrik kesildiğinde yazmasını istiyoruz. Elektrik kesildiğini resimdeki devre ile kontrol ediyoruz. Kondansatör 100uf değil 1000uf olarak değiştirildi. main içinde 1 kere ilk açılış yüklemesi yapmayı bekliyorum fakat o kısım çalışmıyor.
Verdiğim kodda eeprom sürekli yazılmıyorki!
Ext int flag set olduğunda yazılıyor.
void main (void) {
unsigned char Val;
Val = ReadEeprom(adr);
while(1) {
if(INTCONbits.INTF) { //Elektrik gitti,int Flag set oldu.
INTCONbits.INTF = 0;
WriteEeprom(adr, Val);
}else {
LcdWrite(Val);
}
}
}
Daha seksi kesmeli falan olsun derseniz şöylede olabilir.
Edit.Bu PD Bor ile alakalı biraz çetrefilli,ayrıca PD PCON'da değil STATUS reg'deymiş.Pardon!
Ext int olarak değiştirdim.
void main (void) {
unsigned char Val;
Val = ReadEeprom(adr);//Bir dahaki POR'te(Power On Reset) veya RESET durumunda eeprom içine yazılmış olan oknyr.
PowerDown: //INTF kesmesi PC'u buraya şutladı.
WriteEeprom(adr, Val); //Kapasitedeki voltaj bunu yazacak kadar,hala var.
__delay_us(100); //Kapasite burada deşarj oluyor,zaten önemide yok biz alacağımızı almış olduk.
while(1) {
LcdWrite(Val);
}
}
void interrupt (void) { // Elektrik gitti, INTF flag set oldu.
if(INTCONbits.INTF) { //Elektrik gitti,int Flag set oldu.
INTCONbits.INTF = 0;
goto PowerDown;
}
}
Bu şekilde deneyebilirsiniz.
Eeprom okuma yazma ...
(http://i.hizliresim.com/3DNQ6M.gif) (http://hizliresim.com/3DNQ6M)
Sorunu çözüldü.Başlangıçta içerisinde hiç bir veri olmadığı sorunla karşılaşıyormuşuz. Başlangıçta bir kere mahsus sıfırlama butonuna basık halde başlatırsak sorun düzeliyor.Yardımlarınız için çok teşekkür ederim.
Haa 0xFF.
Tabi okuduğunuz değer 0xFF oluncada pgm'nız "bu ney laan diyor":)
Hata denetimi yapmanız gerekirdi bu tip durumlar için.
Butona basmanıza gerek yok.
Okuduğunuz değeri sorgulayın.
Val = ReadEeprom(adr);
if(Val == 0xFF) {
WriteEeprom(adr, Val); //Val herhangi bir değer olabilir,maksat 0xFF'i bozmak.
}
Bir deneyin.
Alıntı yapılan: JOKERAS - 26 Nisan 2015, 21:16:05
Haa 0xFF.
Tabi okuduğunuz değer 0xFF oluncada pgm'nız "bu ney laan diyor":)
Hata denetimi yapmanız gerekirdi bu tip durumlar için.
Butona basmanıza gerek yok.
Okuduğunuz değeri sorgulayın.
Val = ReadEeprom(adr);
if(Val == 0xFF) {
WriteEeprom(adr, Val); //Val herhangi bir değer olabilir,maksat 0xFF'i bozmak.
}
Bir deneyin.
birler=read_eeprom(0);delay_ms(8);
if(birler==0xFF){birler=0;}
onlar =read_eeprom(1);delay_ms(8);
if(onlar==0xFF){onlar=0;}
yuzler=read_eeprom(2);delay_ms(8);
if(onlar==0xFF){yuzler=0;}
binler=read_eeprom(3);delay_ms(8);
if(binler==0xFF){binler=0;}
Hocam şöyle denedim işe yaramadı. Sanırım 0xFF Dışında bir veride tutuyor olabilir.
Usta,
tabiki tutacak,siz ona elektrik kesildiği andaki değer ne ise onu yazıyorsunuz.
Kodda delay'lara gerek yok!Boşuna zaman kaybı.
Bence kod tarasımınızı elden geçirin derim.
Alıntı yapılan: JOKERAS - 27 Nisan 2015, 12:52:20
Usta,
tabiki tutacak,siz ona elektrik kesildiği andaki değer ne ise onu yazıyorsunuz.
Kodda delay'lara gerek yok!Boşuna zaman kaybı.
Bence kod tarasımınızı elden geçirin derim.
Hocam Şu delaylara gerek yok demişsiniz. Sadece okumada mı yoksa yazmada da mı gerek yok. Okuduğum bir yerde 8ms beklemelisin eeprom yazması için diyordu da. Biraz açıklar mısınız.
Sizin dediğiniz süre Epprom okuma süresidir.
Yani Eeprom'u okurken geçen süre,fonksiyonun girişi ile çıkışı arasındaki süre.
Yazma durumunu kontrol etmek için EEIF diye bir flag var,onu sorgularsınız.
Bu flag yazma esnasında sıfır oluyor,yazma işlemi bittiğinde 1 oluyor.
while(!PIR1bits.EEIF); //:Yazma bitene kadar bekle.