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;
}
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.
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.
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.
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ş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.
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.
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.
Alıntı yapılan: PICaso - 21 Mayıs 2020, 14: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
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.
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.
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.
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?
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?
Artan 2 biti ayırıp 8bit olarak kaydedebilirsin. Okurken de iki defada okursun.
Alıntı yapılan: devrecii - 29 Mayıs 2020, 16: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 X, uint8_t Y){
EEADR = addr;
EEDATA = Pwmduty, X,Y;
EECON1bits.WREN = 1;
EECON2 = 0x55;
EECON2 = 0xAA;
EECON1bits.WR = 1;
while(EECON1bits.WR);
EECON1bits.WREN = 0;
}
void main(void) {
Pwmduty = Eeprom_read(0x00);
X = Eeprom_read(0x01);
Y = Eeprom_read(0x02);
__delay_ms(50);
while (1) {
PwmdutyEx = Pwmduty;
XEx = X;
YEx = Y;
if (duty != dutyEx && X != XEx && Y != 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.
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_oku( unsigned int addres)//adrese yazılan 16 bit degeri oku
{
unsigned int iki,bir;
__delay_ms(10);
iki= eeprom_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
}
Alıntı yapılan: serkan - 30 Mayıs 2020, 10: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_oku( unsigned int addres)//adrese yazılan 16 bit degeri oku
{
unsigned int iki,bir;
__delay_ms(10);
iki= eeprom_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.