Picproje Elektronik Sitesi

DERLEYİCİLER => Microchip XC Serisi => Microchip XC8 => Konuyu başlatan: PICaso - 21 Mayıs 2020, 02:04:58

Başlık: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 21 Mayıs 2020, 02:04:58
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(cDATA);
}

void pwm ()
{
    
CCP1CON 0b00001100;
    
PR2 250;
    
T2CON 0b00000100;
}
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PhD - 21 Mayıs 2020, 03:42:35
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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 21 Mayıs 2020, 03:54:51
Alıntı yapılan: PhD - 21 Mayıs 2020, 03: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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: fide - 21 Mayıs 2020, 05:46:14
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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: mehmet - 21 Mayıs 2020, 07:14:07
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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: fide - 21 Mayıs 2020, 08:16:30
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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PhD - 21 Mayıs 2020, 13:22:42
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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 21 Mayıs 2020, 17:49:41
Alıntı yapılan: fide - 21 Mayıs 2020, 05: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.   
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: fide - 21 Mayıs 2020, 19:14:34
Alıntı yapılan: PICaso - 21 Mayıs 2020, 17:49:41int 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
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 22 Mayıs 2020, 03:52:33
Alıntı yapılan: fide - 21 Mayıs 2020, 19: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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 22 Mayıs 2020, 03:59:00
Alıntı yapılan: mehmet - 21 Mayıs 2020, 07: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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: mehmet - 22 Mayıs 2020, 05:09:21
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.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 29 Mayıs 2020, 18:53:47
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?
Başlık: Ynt: Pic 16F628A da EEPROM a 10 Bitilk Veri Kaydetme
Gönderen: PICaso - 29 Mayıs 2020, 19:25:47
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?
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: devrecii - 29 Mayıs 2020, 19:36:33
Artan 2 biti ayırıp 8bit olarak kaydedebilirsin. Okurken de iki defada okursun. 
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 29 Mayıs 2020, 19:59:53
Alıntı yapılan: devrecii - 29 Mayıs 2020, 19:36:33Artan 2 biti ayırıp 8bit olarak kaydedebilirsin. Okurken de iki defada okursun. 

    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 Pwmduty,uint8_t Xuint8_t Y){
    
EEADR addr;
    
EEDATA PwmdutyX,Y;
 
    
EECON1bits.WREN 1;
  
    
EECON2 0x55;
    
EECON2 0xAA;
    
    
EECON1bits.WR 1;
    while(
EECON1bits.WR);
    
EECON1bits.WREN 0;      
}

void main(void) {

 
  
Pwmduty Eeprom_read(0x00);
  
Eeprom_read(0x01);
  
Eeprom_read(0x02);
    
__delay_ms(50);

    while (
1) {
        
        
PwmdutyEx Pwmduty;
        
XEx X;
        
YEx Y;
        
    
    
    if (
duty != dutyEx && != XEx && != YEx){
    
Eeprom_write(0x00,Pwmduty);
    
    
Eeprom_write(0x01,X);
    
    
Eeprom_write(0x02,Y);
  
__delay_ms(50); }
 



Hocam şu şekilde yaptım ama derlenmedi. Adresleme sırasında yanlışım var sanırım.
Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: serkan - 30 Mayıs 2020, 13:49:41
PICaso 10 bit değeri 8 bitlik eeprom bölümlerine yazma birleştirmek ve okumakla ilgili örnek denendi.



void EEPROM_yaz(int addres,unsigned int deger)//8 bitlik adreslere 16 bitlik  degeri yaz.
      
{
  
unsigned int iki,bir;
      
iki = (deger);      
      
bir = (deger >> 8); 
      
__delay_ms(10);
      
eeprom_write(addres,iki);
      
eeprom_write(addres 1,bir);
      }
////////////////////////////////////////////////////
 
unsigned int EEPROM_okuunsigned int addres)//adrese yazılan 16 bit degeri oku
      
{
   
unsigned int  iki,bir;       
   
__delay_ms(10);
      
ikieeprom_read(addres);
      
bir=eeprom_read(addres 1);
      return (
iki<< 0) + (bir << 8); 
      } 
/////////////////////////////////////////////////////
	
  
 
void main(){
  
unsigned int sayi=0,sayi1;

   
sayi=19724;

   
EEPROM_yaz(12,sayi); //12 ve 13 nolu adrese yaz 

   
sayi1=EEPROM_oku(12); //12 ve 13 nolu adresi oku

Başlık: Ynt: Pic 16F628A da EEPROM da değişken değeri kaydetme
Gönderen: PICaso - 31 Mayıs 2020, 21:28:19
Alıntı yapılan: serkan - 30 Mayıs 2020, 13:49:41PICaso 10 bit değeri 8 bitlik eeprom bölümlerine yazma birleştirmek ve okumakla ilgili örnek denendi.



void EEPROM_yaz(int addres,unsigned int deger)//8 bitlik adreslere 16 bitlik  degeri yaz.
      
{
  
unsigned int iki,bir;
      
iki = (deger);      
      
bir = (deger >> 8); 
      
__delay_ms(10);
      
eeprom_write(addres,iki);
      
eeprom_write(addres 1,bir);
      }
////////////////////////////////////////////////////
 
unsigned int EEPROM_okuunsigned int addres)//adrese yazılan 16 bit degeri oku
      
{
   
unsigned int  iki,bir;       
   
__delay_ms(10);
      
ikieeprom_read(addres);
      
bir=eeprom_read(addres 1);
      return (
iki<< 0) + (bir << 8); 
      } 
/////////////////////////////////////////////////////
	
  
 
void main(){
  
unsigned int sayi=0,sayi1;

   
sayi=19724;

   
EEPROM_yaz(12,sayi); //12 ve 13 nolu adrese yaz 

   
sayi1=EEPROM_oku(12); //12 ve 13 nolu adresi oku


@serkan hocam teşekkür ederim, bu kod anlamama yardımcı oldu.