Pic 16F628A da EEPROM da değişken değeri kaydetme

Başlatan PICaso, 20 Mayıs 2020, 23:04:58

PICaso

Arkadaşlar paylaşacağım programım sorunsuz çalışıyor. Kafama bir soru takıldı. While döngüsünün sonunda değişkeni 
EEPROM a yazıyorum. Bu durum uzun vadede işlemcide sorun çıkartır mı?
int duty=125;
int lcd_duty; //0 ile 100 aras?nda ki de?erleri göstermek icin

void pwm ();

uint8_t Eeprom_read(uint8_t addr){
    EEADR = addr;
    
    EECON1bits.RD = 1;
    while(EECON1bits.RD);
    return EEDATA;
}

void Eeprom_write(uint8_t addr,uint8_t duty){
    EEADR = addr;
    EEDATA = duty;
    
    EECON1bits.WREN = 1;
  
    EECON2 = 0x55;
    EECON2 = 0xAA;
    
    EECON1bits.WR = 1;
    while(EECON1bits.WR);
    EECON1bits.WREN = 0;      
}

void main(void) {
       
///LCD BA?LANTILARI///   
TRISAbits.TRISA6 = 0;
TRISAbits.TRISA7 = 0;
TRISBbits.TRISB4 = 0;
TRISBbits.TRISB5 = 0;
TRISBbits.TRISB6 = 0;
TRISBbits.TRISB7 = 0;
//////////////////////


TRISBbits.TRISB0 = 1; //BUTON duty artir
TRISBbits.TRISB1 = 1; //BUTON duty azalt

PORTBbits.RB3 = 0;
TRISBbits.TRISB3 = 0; //PWM Out

 pwm();
 
 initLCD(); //LCD initialize ediliyor
 
  duty = Eeprom_read(0x00);
     __delay_ms(50);

    while (1) {
        
        if(RB0 == 0){ 
            __delay_ms(50);
          if(RB0 == 0){  
        duty==duty++;
            if(duty>=250){
            duty=250;}
          }}
        
        if(RB1 == 0){
            __delay_ms(50);
            if(RB1 == 0){
        duty==duty--;
            if(duty<=0){
            duty=0;}
            }}
  
   CCPR1L = duty;
   
   lcd_duty=(duty*4)/10;
    
   
    gotoLCD(SECOND_LINE);
    printf("Motor Hiz=%% %d",lcd_duty);
    
    
     Eeprom_write(0x00,duty);
   __delay_ms(50);  
    }
}

void putch(char c) {
    lcdWrite(c, DATA);
}

void pwm ()
{
    CCP1CON = 0b00001100;
    PR2 = 250;
    T2CON = 0b00000100;
}

PhD

Eğer her 50ms'de bir yani bu kadar sık EEPROM'a veri yazıyorsanız, EEPROM'a 1.000.000 (bir milyon) yazma kapasitesini (bu bilgi için kullandığınız işlemcinin datasheet'ine bakabilirsiniz) doldurduktan sonra sıkıntı yaşayabilirsiniz. Şu ana kadar bu kapasite aşıldığında ne oluyor bilmiyorum, hiç tecrübe etmedim.
...hiç...

PICaso

Alıntı yapılan: PhD - 21 Mayıs 2020, 00:42:35Eğer her 50ms'de bir yani bu kadar sık EEPROM'a veri yazıyorsanız, EEPROM'a 1.000.000 (bir milyon) yazma kapasitesini (bu bilgi için kullandığınız işlemcinin datasheet'ine bakabilirsiniz) doldurduktan sonra sıkıntı yaşayabilirsiniz. Şu ana kadar bu kapasite aşıldığında ne oluyor bilmiyorum, hiç tecrübe etmedim.
Hocam sistem sürekli çalışmayacak. Her akşam kapanacağını varsayarsak değişken değerin son değerini nasıl saklamalıyım.

fide

dutyEx isimli yeni bir değer tanımla ve duty'nin değişmesi muhtemel yerde ya da bekleme satırından önce duty değişkenine eşitle.
Sonra while içinde bekleme satırından sonra
if duty! =dutyEx
Şeklinde kontrol et.

Farklı ise hafızaya o zaman yaz.

Bu şekilde sadece duty değişince yazmış olacağın için eeproma yazma sayısı inanılmaz derecede düşecektir.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

mehmet

Değiştikten sonra bir zaman sayacı
belli bir değere kurulsun. Her değişim
bu sayacı yeniden kursun. Sayac
sıfırlandıktan sonra ve eprom alanı
farklı ise yazılsın.

Kullanıcı doğru değer bulunana kadar
değer değiştirilecek. Devamlı da kayıt
yapılacak. Mesela 10sn değer değişmezse
öyle kaydedilsin.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

fide

Başka bir öneri:

Bir adet süper cap yada yüksek kapasiteli kondansatör, diyot ve ekstra bir kesme pini ile düzenek kurun.
Cihaz kapatıldığı anda beslemeyi algılayan  pin 1'den 0'a düşecek. Bu size ihtiyacınız olan kesmeyi sağlayacak. Kondansatör hala dolu olduğu için eeproma yazmaya yetecek kadar süre sağlayacaktır size.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

PhD

Hem @fide hem @mehmet arkadaşlar gereken cevabı vermişler. @fide arkadaşımızın son belirttiğinde donanım değişikliği gerekiyor.
...hiç...

PICaso

Alıntı yapılan: fide - 21 Mayıs 2020, 02:46:14dutyEx isimli yeni bir değer tanımla ve duty'nin değişmesi muhtemel yerde ya da bekleme satırından önce duty değişkenine eşitle.
Sonra while içinde bekleme satırından sonra
if duty! =dutyEx
Şeklinde kontrol et.

Farklı ise hafızaya o zaman yaz.

Bu şekilde sadece duty değişince yazmış olacağın için eeproma yazma sayısı inanılmaz derecede düşecektir.

int dutyEx;
int duty=125;
int lcd_duty; //0 ile 100 aras?nda ki de?erleri göstermek icin



uint8_t Eeprom_read(uint8_t addr){
    EEADR = addr;
    
    EECON1bits.RD = 1;
    while(EECON1bits.RD);
    return EEDATA;
}

void Eeprom_write(uint8_t addr,uint8_t duty){
    EEADR = addr;
    EEDATA = duty;
    
    EECON1bits.WREN = 1;
  
    EECON2 = 0x55;
    EECON2 = 0xAA;
    
    EECON1bits.WR = 1;
    while(EECON1bits.WR);
    EECON1bits.WREN = 0;      
}

void main(void) {
       

 initLCD(); //LCD initialize ediliyor
 
  duty = Eeprom_read(0x00);
  
  duty == dutyEx;
     __delay_ms(50);

    while (1) {
        
        if(RB0 == 0){ 
            __delay_ms(50);
          if(RB0 == 0){  
        duty==duty++;
            if(duty>=250){
            duty=250;}
          }}
        
        if(RB1 == 0){
            __delay_ms(50);
            if(RB1 == 0){
        duty==duty--;
            if(duty<=0){
            duty=0;}
            }}
  
   CCPR1L = duty;
   
    lcd_duty=((duty*4)/10);
    
    
    gotoLCD(SECOND_LINE);
    printf("Motor Hiz = %%%d",lcd_duty);
 
    
    if (duty != dutyEx){
     Eeprom_write(0x00,duty);
   __delay_ms(50); }

    }
}

Hocam bu şekilde değişiklik yaptım. Fakat ''lcd_duty=((duty*4)/10);'' şu işlemi yapıp lcd ye yazma işlemi farklı çalışmaya başladı. Buton ile artış yaptığımda 100 e kadar çıkıyor. Buton ile azalma yaptığımda 990,980,970 şeklinde aalıyor. Enerjiyi kesip yeniden verdiğimde 970 de kalmış ise 97 şeklinde doğru yazıyor. bir kaç kere enerjiyi kesip yeniden verdiğimde lcd ekran da 102 değerini gösterdi.   

fide

Alıntı yapılan: PICaso - 21 Mayıs 2020, 14:49:41
int dutyEx;
int duty=125;
int lcd_duty; //0 ile 100 aras?nda ki de?erleri göstermek icin



uint8_t Eeprom_read(uint8_t addr){
    EEADR = addr;
    
    EECON1bits.RD = 1;
    while(EECON1bits.RD);
    return EEDATA;
}

void Eeprom_write(uint8_t addr,uint8_t duty){
    EEADR = addr;
    EEDATA = duty;
    
    EECON1bits.WREN = 1;
  
    EECON2 = 0x55;
    EECON2 = 0xAA;
    
    EECON1bits.WR = 1;
    while(EECON1bits.WR);
    EECON1bits.WREN = 0;      
}

void main(void) {
      

 initLCD(); //LCD initialize ediliyor
 
  duty = Eeprom_read(0x00);
  
  duty == dutyEx;
    __delay_ms(50);

    while (1) {
        
        if(RB0 == 0){ 
            __delay_ms(50);
          if(RB0 == 0){  
        duty==duty++;
            if(duty>=250){
            duty=250;}
          }}
        
        if(RB1 == 0){
            __delay_ms(50);
            if(RB1 == 0){
        duty==duty--;
            if(duty<=0){
            duty=0;}
            }}
  
  CCPR1L = duty;
  
    lcd_duty=((duty*4)/10);
    
    
    gotoLCD(SECOND_LINE);
    printf("Motor Hiz = %%%d",lcd_duty);
 
    
    if (duty != dutyEx){
    Eeprom_write(0x00,duty);
  __delay_ms(50); }

    }
}

Hocam bu şekilde değişiklik yaptım. Fakat ''lcd_duty=((duty*4)/10);'' şu işlemi yapıp lcd ye yazma işlemi farklı çalışmaya başladı. Buton ile artış yaptığımda 100 e kadar çıkıyor. Buton ile azalma yaptığımda 990,980,970 şeklinde aalıyor. Enerjiyi kesip yeniden verdiğimde 970 de kalmış ise 97 şeklinde doğru yazıyor. bir kaç kere enerjiyi kesip yeniden verdiğimde lcd ekran da 102 değerini gösterdi. 

LCd yazma rutininde son sayıyı yazdıktan sonra en az iki adet boşluk bırakın.
970--> 97 sebebi şu ki:
Önce 100 yazdı.
sonra LCD silmeden soldan başlayıp 97 yazdı. İlk iki karakter silindi ama sondaki sıfır silinmedi. Siz de bunu 97 olarak değil 970 olarak gördünüz.

Diğer konu:
duty=dutyEx;
şeklinde değil 
dutyEx=duty;
şeklinde kullanın ve bunu while bloğu içine alın.

void main(void) {
      

 initLCD(); //LCD initialize ediliyor
 
  duty = Eeprom_read(0x00);
  
  
   

    while (1) {
        
        
dutyEx = duty;
 __delay_ms(50);
if(RB0 == 0){ 
            __delay_ms(50);
          if(RB0 == 0){  
            duty++;
            if(duty>=250){
            duty=250;}
          }}
        
        if(RB1 == 0){
            __delay_ms(50);
            if(RB1 == 0){
        duty--;
            if(duty<=0){
            duty=0;}
            }}
  
  CCPR1L = duty;
  
    lcd_duty=((duty*4)/10);
    
    
    gotoLCD(SECOND_LINE);
    printf("Motor Hiz = %%%d  ",lcd_duty);
 
    
    if (duty!= dutyEx){
    Eeprom_write(0x00,duty);
  __delay_ms(50); }

    }


diğer bir konu

duty==duty--;
böyle bir kullanım yok.
duty--;
şeklinde kullanılır.
== atama değil karşılaştırma operatörüdür. ::ok  ::ok
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

PICaso

Alıntı yapılan: fide - 21 Mayıs 2020, 16:14:34LCd yazma rutininde son sayıyı yazdıktan sonra en az iki adet boşluk bırakın.
970--> 97 sebebi şu ki:
Önce 100 yazdı.
sonra LCD silmeden soldan başlayıp 97 yazdı. İlk iki karakter silindi ama sondaki sıfır silinmedi. Siz de bunu 97 olarak değil 970 olarak gördünüz.

Diğer konu:
duty=dutyEx;
şeklinde değil 
dutyEx=duty;
şeklinde kullanın ve bunu while bloğu içine alın.

void main(void) {
      

 initLCD(); //LCD initialize ediliyor
 
  duty = Eeprom_read(0x00);
  
  
   

    while (1) {
        
        
dutyEx = duty;
 __delay_ms(50);
if(RB0 == 0){ 
            __delay_ms(50);
          if(RB0 == 0){  
            duty++;
            if(duty>=250){
            duty=250;}
          }}
        
        if(RB1 == 0){
            __delay_ms(50);
            if(RB1 == 0){
        duty--;
            if(duty<=0){
            duty=0;}
            }}
  
  CCPR1L = duty;
  
    lcd_duty=((duty*4)/10);
    
    
    gotoLCD(SECOND_LINE);
    printf("Motor Hiz = %%%d  ",lcd_duty);
 
    
    if (duty!= dutyEx){
    Eeprom_write(0x00,duty);
  __delay_ms(50); }

    }


diğer bir konu

duty==duty--;
böyle bir kullanım yok.
duty--;
şeklinde kullanılır.
== atama değil karşılaştırma operatörüdür. ::ok  ::ok

Çok teşekkür ederim hocam. Sorunlar düzeldi.

PICaso

Alıntı yapılan: mehmet - 21 Mayıs 2020, 04:14:07Değiştikten sonra bir zaman sayacı
belli bir değere kurulsun. Her değişim
bu sayacı yeniden kursun. Sayac
sıfırlandıktan sonra ve eprom alanı
farklı ise yazılsın.

Kullanıcı doğru değer bulunana kadar
değer değiştirilecek. Devamlı da kayıt
yapılacak. Mesela 10sn değer değişmezse
öyle kaydedilsin.
Hocam arttır ve azalt şeklinde 2 buton kullanıyorum. 10sn lik timer kurup, 2 kere butona basma arasında 10sn veya daha fazla süre geçmiş ise son değeri EEPROM a yazmalıyım. Doğru anlamış mıyım? Sizin önerinizi de müsait olduğum da denemeye çalışacağım. Teşekkür ederim yardımlarınız için.

mehmet

Eproma bilgi yazmak ilgili alanın
ömrünü azaltıyor. Belli bir süre sonra
artık o alan silinemez hale geliyor.
Son değer ancak okunabiliyor.
Eepromu en uzun zamanda verimli kullanmak
için yazmayı çok gerekli olduğunda yapmak
gerek.

Klimayı düşünün; doğru sıcaklığı bulmak
için bir kaç kez butonlara basarız. Eğer
her basışta eeprom kaydı olsa bir kaç
günde kullanılamaz hale gelir.

Bunu aşmak için herkes farklı çözümler
üretir. Duruma göre biri veya bir kaçını
aynı anda kullanmak gerekebilir. Belkide
eeprom yerine başka hafıza birimleri
kullanılacak.

Buna göre uygun yöntemi siz belirleyeceksiniz.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr
https://creativecommons.org/licenses/by/4.0/deed.tr "CC BY"

PICaso

Arkadaşlar 8 bitlik veriyi EEPROM a yazıyorum. Veri 10 bit olduğunda 0. ve 1. biti nasıl kaydetmem gerekiyor, nasıl bir yol izlemeliyim?

PICaso

Arkadaşlar 8 bitlik veriyi EEPROM a yazıyorum. Veri 10 bit olduğunda 0. ve 1. biti nasıl kaydetmem gerekiyor, nasıl bir yol izlemeliyim?

devrecii

Artan 2 biti ayırıp 8bit olarak kaydedebilirsin. Okurken de iki defada okursun.