CCS C AÇILIŞ EEPROM READ HATASI (ÇÖZÜLDÜ)

Başlatan ehliseyf, 26 Nisan 2015, 01:59:44

ehliseyf

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



#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();
 }
}
Code'm mu oturturum !

Salih

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.

sadogan

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 ?

esensoy

bence ilk önce rcon bitlerini kontrol edin, takılıp kalıyor dediğiniz acaba nedir, reset mi atıyor kendine?
En tehlikeli an "zafer" anıdır.

JOKERAS

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.



ehliseyf

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.
Code'm mu oturturum !

JOKERAS

#6
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 ...



ehliseyf

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.
Code'm mu oturturum !

JOKERAS

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.

ehliseyf

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.
Code'm mu oturturum !

JOKERAS

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.


ehliseyf

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.
Code'm mu oturturum !

JOKERAS

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.